From a00a5ff876efe7d2299dbc913688b26daf9ff3a7 Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Thu, 24 Jul 2025 14:30:26 +0800 Subject: [PATCH] =?utf8?q?application=E6=96=87=E4=BB=B6=E5=A4=B9=E4=B8=8Bw?= =?utf8?q?earable=E6=96=87=E4=BB=B6=E5=A4=B9=E5=90=88=E5=B9=B6=E6=8F=90?= =?utf8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../alipay/service/alipay_bluetooth.c | 2 +- .../wearable/nativeabilityfwk/CMakeLists.txt | 2 +- .../nativeabilityfwk/include/Ability.h | 133 +++- .../nativeabilityfwk/include/AbilitySlice.h | 94 +-- .../include/AbilitySliceProxy.h | 23 +- .../include/BackDragListener.h | 79 +- .../nativeabilityfwk/include/NativeAbility.h | 10 +- .../include/PageTransitionMgr.h | 34 +- .../nativeabilityfwk/include/Presenter.h | 79 +- .../nativeabilityfwk/include/RecentManager.h | 192 +++++ .../wearable/nativeabilityfwk/include/Slice.h | 13 +- .../nativeabilityfwk/include/SlicePage.h | 66 ++ .../include/SlicePageFactory.h | 69 ++ .../include/SlicePageManager.h | 102 +++ .../nativeabilityfwk/include/SliceProxy.h | 14 +- .../wearable/nativeabilityfwk/include/View.h | 107 ++- .../wearable/nativeabilityfwk/src/Ability.cpp | 169 +++-- .../nativeabilityfwk/src/AbilitySlice.cpp | 134 ++++ .../nativeabilityfwk/src/NativeAbility.cpp | 38 +- .../transition/BackToHexagonsTransition.cpp | 2 +- .../transition/BackToWaterfallTransition.cpp | 8 +- .../wearable/nativeapp/CMakeLists.txt | 62 +- .../brandy-auto-ota-cli/libuikit_fwk.a | Bin 240634 -> 423236 bytes .../brandy-auto-ota-ser/libuikit_fwk.a | Bin 240634 -> 423236 bytes .../nativeapp/brandy-native-js/libuikit_fwk.a | Bin 240634 -> 423236 bytes .../nativeapp/brandy-xts/libuikit_fwk.a | Bin 240634 -> 423236 bytes .../nativelauncher/include/AppViewIDs.h | 16 + .../nativelauncher/include/NativeLauncher.h | 2 - .../include/NativeRegisterManager.h | 37 +- .../include/UICardPageFactory.h | 73 ++ .../nativelauncher/include/UiConfig.h | 25 + .../include/ui_resource_breath.h | 102 +++ .../include/ui_resource_camera.h | 17 + .../nativelauncher/include/ui_resource_date.h | 21 + .../include/ui_resource_findPhone.h | 46 ++ .../include/ui_resource_sleep.h | 28 + .../include/ui_resource_string.h | 23 + .../include/ui_resource_timer.h | 27 + .../include/ui_resource_weather.h | 89 +++ .../include/ui_stopwatch_resource.h | 25 + .../nativelauncher/src/NativeLauncher.cpp | 43 +- .../src/NativeRegisterManager.cpp | 51 +- .../nativelauncher/src/UICardPageFactory.cpp | 43 ++ .../nativeui/activity/src/ActivityModel.cpp | 59 +- .../activity/src/ActivityPresenter.cpp | 6 +- .../activity/src/ActivityWeekView.cpp | 4 +- .../activity/src/MainActivityView.cpp | 2 +- .../nativeui/add_card/src/AddCardAdapter.cpp | 2 +- .../nativeui/add_card/src/AddCardItem.cpp | 4 +- .../nativeui/add_card/src/AddCardModel.cpp | 2 +- .../add_card/src/AddCardPresenter.cpp | 6 +- .../nativeui/add_card/src/AddCardView.cpp | 4 +- .../nativeui/alarm/src/AlarmClockModel.cpp | 21 +- .../nativeui/alarm/src/AlarmCloseRingView.cpp | 6 +- .../nativeui/alarm/src/AlarmConfigView.cpp | 4 +- .../nativeui/alarm/src/AlarmJudgeView.cpp | 4 +- .../nativeui/alarm/src/AlarmMaxClock.cpp | 6 +- .../nativeui/alarm/src/AlarmNewTimeView.cpp | 2 +- .../alarm/src/AlarmPopUpPresenter.cpp | 8 +- .../nativeui/alarm/src/AlarmPopUpView.cpp | 4 +- .../nativeui/alarm/src/AlarmPresenter.cpp | 4 +- .../nativeui/alarm/src/AlarmRingView.cpp | 6 +- .../nativeui/alarm/src/AlarmSetTimeView.cpp | 2 +- .../nativeui/alarm/src/AlarmSetWeekView.cpp | 2 +- .../nativeui/alarm/src/MainAlarmView.cpp | 4 +- .../alarmclockmanage/src/AlarmClockManage.cpp | 6 +- .../src/AlarmClockTimerConfig.cpp | 8 +- .../nativeui/alipay/src/AlipayBarCode.cpp | 4 +- .../nativeui/alipay/src/AlipayBind.cpp | 4 +- .../nativeui/alipay/src/AlipayBindAni.cpp | 2 +- .../nativeui/alipay/src/AlipayBindRes.cpp | 4 +- .../nativeui/alipay/src/AlipayExitBind.cpp | 2 +- .../nativeui/alipay/src/AlipayHelp.cpp | 4 +- .../src/AlipayList/AlipayListAdapter.cpp | 4 +- .../src/AlipayList/AlipayListItemView.cpp | 2 +- .../alipay/src/AlipayList/AlipayListView.cpp | 4 +- .../nativeui/alipay/src/AlipayMainView.cpp | 2 +- .../nativeui/alipay/src/AlipayModel.cpp | 4 +- .../nativeui/alipay/src/AlipayPayCode.cpp | 4 +- .../nativeui/alipay/src/AlipayPresenter.cpp | 13 +- .../nativeui/alipay/src/AlipaySetting.cpp | 4 +- .../src/AlipayTrans/AlipayGetTransList.cpp | 2 +- .../alipay/src/AlipayTrans/AlipayTransAni.cpp | 2 +- .../src/AlipayTrans/AlipayTransCode.cpp | 4 +- .../src/AlipayTrans/AlipayTransEnable.cpp | 4 +- .../AlipayTrans/AlipayTransListAdapter.cpp | 4 +- .../AlipayTrans/AlipayTransListItemView.cpp | 2 +- .../src/AlipayTrans/AlipayTransListView.cpp | 6 +- .../alipay/src/AlipayTrans/AlipayTransRes.cpp | 4 +- .../src/AlipayTrans/AlipayTransTips.cpp | 4 +- .../nativeui/alipay/src/AlipayUnbind.cpp | 2 +- .../alipay/src/AlipayUnbindFinish.cpp | 2 +- .../nativeui/aod_view/src/AodModel.cpp | 4 +- .../nativeui/aod_view/src/AodPresenter.cpp | 2 +- .../nativeui/aod_view/src/AodView.cpp | 25 +- .../nativeui/applist/include/ApplistModel.h | 70 -- .../nativeui/applist/src/AppItemView.cpp | 44 +- .../nativeui/applist/src/ApplistAdapter.cpp | 2 +- .../nativeui/applist/src/ApplistModel.cpp | 20 +- .../nativeui/applist/src/ApplistPresenter.cpp | 3 +- .../nativeui/applist/src/ApplistView.cpp | 35 +- .../nativeui/blood/src/BloodModel.cpp | 133 ++++ .../nativeui/blood/src/BloodPresenter.cpp | 89 +++ .../nativeui/blood/src/BloodView.cpp | 603 +++++++++++++++ .../bloodoxygen/src/BloodBandoffView.cpp | 4 +- .../bloodoxygen/src/BloodOxygenModel.cpp | 2 +- .../bloodoxygen/src/BloodOxygenPresenter.cpp | 10 +- .../bloodoxygen/src/BloodOxygenView.cpp | 4 +- .../src/BluetoothCaseListAdapter.cpp | 8 +- .../src/BluetoothDeviceCaseListAdapter.cpp | 8 +- .../bluetooth/src/BluetoothDeviceListView.cpp | 8 +- .../bluetooth/src/BluetoothEarListView.cpp | 10 +- .../bluetooth/src/BluetoothEarPhoneView.cpp | 10 +- .../bluetooth/src/BluetoothHeadsetEvent.cpp | 4 +- .../bluetooth/src/BluetoothItemView.cpp | 2 +- .../nativeui/bluetooth/src/BluetoothModel.cpp | 71 +- .../bluetooth/src/BluetoothOptionsView.cpp | 8 +- .../bluetooth/src/BluetoothPresenter.cpp | 6 +- .../bluetooth/src/BluetoothReconnectView.cpp | 8 +- .../bluetooth/src/BluetoothWrapper.cpp | 2 +- .../bluetooth/src/MainBluetoothView.cpp | 4 +- .../bluetooth/src/TipsConnFailMessageView.cpp | 8 +- .../bluetooth/src/TipsFailMessageView.cpp | 8 +- .../bluetooth/src/TipsSuccMessageView.cpp | 8 +- .../nativeui/breath/src/BreathDurPage.cpp | 171 +++++ .../nativeui/breath/src/BreathExerPage.cpp | 323 ++++++++ .../nativeui/breath/src/BreathMainPage.cpp | 253 +++++++ .../nativeui/breath/src/BreathModel.cpp | 259 +++++++ .../nativeui/breath/src/BreathPresenter.cpp | 13 + .../nativeui/breath/src/BreathResultPage.cpp | 353 +++++++++ .../nativeui/breath/src/BreathRhyPage.cpp | 172 +++++ .../nativeui/breath/src/BreathStartPage.cpp | 197 +++++ .../nativeui/callerlog/src/CallerItemView.cpp | 7 +- .../nativeui/callerlog/src/CallerLogModel.cpp | 12 +- .../callerlog/src/CallerLogPresenter.cpp | 6 +- .../nativeui/callerlog/src/CallerLogView.cpp | 6 +- .../nativeui/camera/src/CameraMainPage.cpp | 376 ++++++++++ .../nativeui/camera/src/CameraModel.cpp | 24 + .../nativeui/camera/src/CameraPresenter.cpp | 15 + .../nativeui/clock/src/AmbientClockView.cpp | 8 +- .../nativeui/clock/src/MainClockView.cpp | 8 +- .../compass/include/CompassCalibrationView.h | 34 - .../compass/include/CompassControlView.h | 36 - .../nativeui/compass/include/CompassModel.h | 38 - .../compass/include/CompassPresenter.h | 46 -- .../nativeui/compass/include/CompassView.h | 47 -- .../compass/include/MainCompassPresenter.h | 32 - .../compass/include/MainCompassView.h | 44 -- .../compass/src/CompassCalibrationView.cpp | 124 --- .../compass/src/CompassControlView.cpp | 93 +-- .../nativeui/compass/src/CompassFragment.cpp | 213 ++++++ .../nativeui/compass/src/CompassModel.cpp | 56 +- .../nativeui/compass/src/CompassPresenter.cpp | 171 ----- .../nativeui/compass/src/CompassView.cpp | 206 ----- .../compass/src/MainCompassPresenter.cpp | 48 +- .../nativeui/compass/src/MainCompassView.cpp | 105 +-- .../connectnewphone/src/ConnectOpenView.cpp | 9 +- .../src/ConnectPhonePresenter.cpp | 6 +- .../connectnewphone/src/ConnectPhoneView.cpp | 2 +- .../connectnewphone/src/ConnectSelectView.cpp | 7 +- .../nativeui/date/src/DateAdapter.cpp | 73 ++ .../nativeui/date/src/DateButtonAdapter.cpp | 73 ++ .../nativeui/date/src/DateButtonItemView.cpp | 96 +++ .../nativeui/date/src/DateItemView.cpp | 118 +++ .../nativeui/date/src/DateMainPage.cpp | 303 ++++++++ .../nativeui/date/src/DateMessagePage.cpp | 168 +++++ .../nativeapp/nativeui/date/src/DateModel.cpp | 93 +++ .../nativeui/date/src/DatePresenter.cpp | 16 + .../nativeui/emptypage/src/EmptyPage.cpp | 67 ++ .../nativeui/emptypage/src/EmptyPresenter.cpp | 13 + .../findphone/src/FindPhoneMainPage.cpp | 623 ++++++++++++++++ .../nativeui/findphone/src/FindPhoneModel.cpp | 30 + .../findphone/src/FindPhonePresenter.cpp | 15 + .../flashlight/src/FlashLightBlinkPage.cpp | 141 ++++ .../flashlight/src/FlashLightColorPage.cpp | 330 ++++++++ .../flashlight/src/FlashLightDefaultPage.cpp | 132 ++++ .../flashlight/src/FlashLightModel.cpp | 78 ++ .../flashlight/src/FlashLightPage.cpp | 174 +++++ .../flashlight/src/FlashLightPlayPage.cpp | 104 +++ .../flashlight/src/FlashLightPresenter.cpp | 14 + .../src/FlashLightSetItemAdapter.cpp | 57 ++ .../flashlight/src/FlashLightSetItemView.cpp | 95 +++ .../flashlight/src/FlashLightSetPage.cpp | 166 +++++ .../nativeui/heartrate/src/HeartModel.cpp | 12 +- .../nativeui/heartrate/src/HeartRateView.cpp | 4 +- .../activity}/ActivityModel.h | 4 +- .../activity}/ActivityPresenter.h | 2 +- .../activity}/ActivityWeekView.h | 2 +- .../activity}/MainActivityView.h | 8 +- .../add_card}/AddCardAdapter.h | 2 +- .../add_card}/AddCardItem.h | 0 .../add_card}/AddCardModel.h | 4 +- .../add_card}/AddCardPresenter.h | 2 +- .../add_card}/AddCardView.h | 4 +- .../alarm}/AlarmClockModel.h | 2 +- .../alarm}/AlarmCloseRingView.h | 2 +- .../alarm}/AlarmConfigView.h | 2 +- .../alarm}/AlarmJudgeView.h | 4 +- .../include => include/alarm}/AlarmMaxClock.h | 4 +- .../alarm}/AlarmNewTimeView.h | 4 +- .../alarm}/AlarmPopUpPresenter.h | 12 +- .../alarm}/AlarmPopUpView.h | 8 +- .../alarm}/AlarmPresenter.h | 2 +- .../include => include/alarm}/AlarmRingView.h | 2 +- .../alarm}/AlarmSetTimeView.h | 4 +- .../alarm}/AlarmSetWeekView.h | 4 +- .../include => include/alarm}/MainAlarmView.h | 16 +- .../alarmclockmanage}/AlarmClockManage.h | 2 +- .../AlmmgrAlarmClockManage.h | 2 +- .../AlarmClockTimerConfig.h | 0 .../alipay}/AlipayBarCode.h | 2 +- .../include => include/alipay}/AlipayBind.h | 2 +- .../alipay}/AlipayBindAni.h | 2 +- .../alipay}/AlipayBindRes.h | 2 +- .../alipay}/AlipayExitBind.h | 2 +- .../include => include/alipay}/AlipayHelp.h | 2 +- .../alipay}/AlipayList/AlipayListAdapter.h | 2 +- .../alipay}/AlipayList/AlipayListItem.h | 0 .../alipay}/AlipayList/AlipayListItemView.h | 4 +- .../alipay}/AlipayList/AlipayListView.h | 6 +- .../alipay}/AlipayMainView.h | 40 +- .../include => include/alipay}/AlipayModel.h | 0 .../alipay}/AlipayPayCode.h | 2 +- .../alipay}/AlipayPresenter.h | 2 +- .../alipay}/AlipayRefreshBindCode.h | 2 +- .../alipay}/AlipaySetting.h | 2 +- .../alipay}/AlipayTrans/AlipayGetTransList.h | 2 +- .../alipay}/AlipayTrans/AlipayTransAni.h | 2 +- .../alipay}/AlipayTrans/AlipayTransCode.h | 2 +- .../alipay}/AlipayTrans/AlipayTransEnable.h | 2 +- .../AlipayTrans/AlipayTransListAdapter.h | 2 +- .../alipay}/AlipayTrans/AlipayTransListItem.h | 0 .../AlipayTrans/AlipayTransListItemView.h | 4 +- .../alipay}/AlipayTrans/AlipayTransListView.h | 6 +- .../alipay}/AlipayTrans/AlipayTransRes.h | 2 +- .../alipay}/AlipayTrans/AlipayTransTips.h | 2 +- .../include => include/alipay}/AlipayUnbind.h | 2 +- .../alipay}/AlipayUnbindFinish.h | 2 +- .../include => include/aod_view}/AodModel.h | 3 +- .../aod_view}/AodPresenter.h | 6 +- .../include => include/aod_view}/AodView.h | 6 +- .../include => include/applist}/AppItemView.h | 18 +- .../applist}/ApplistAdapter.h | 4 +- .../nativeui/include/applist/ApplistModel.h | 103 +++ .../applist}/ApplistPresenter.h | 6 +- .../include => include/applist}/ApplistView.h | 3 +- .../nativeui/include/blood/BloodModel.h | 35 + .../nativeui/include/blood/BloodPresenter.h | 54 ++ .../nativeui/include/blood/BloodView.h | 86 +++ .../bloodoxygen}/BloodBandoffView.h | 0 .../bloodoxygen}/BloodOxygenModel.h | 0 .../bloodoxygen}/BloodOxygenPresenter.h | 2 +- .../bloodoxygen}/BloodOxygenView.h | 4 +- .../bluetooth}/BluetoothCaseListAdapter.h | 4 +- .../include/bluetooth/BluetoothChangeBle.h | 17 + .../BluetoothDeviceCaseListAdapter.h | 2 +- .../bluetooth}/BluetoothDeviceListView.h | 2 +- .../bluetooth}/BluetoothEarListView.h | 2 +- .../bluetooth}/BluetoothEarPhoneView.h | 2 +- .../bluetooth}/BluetoothHeadsetEvent.h | 0 .../bluetooth}/BluetoothItemView.h | 2 +- .../bluetooth}/BluetoothModel.h | 12 +- .../bluetooth}/BluetoothOptionsView.h | 2 +- .../bluetooth}/BluetoothPresenter.h | 8 +- .../bluetooth}/BluetoothReconnectView.h | 0 .../bluetooth}/BluetoothWrapper.h | 0 .../bluetooth}/MainBluetoothView.h | 22 +- .../bluetooth}/TipsConnFailMessageView.h | 0 .../bluetooth}/TipsFailMessageView.h | 0 .../bluetooth}/TipsSuccMessageView.h | 0 .../nativeui/include/breath/BreathDurPage.h | 47 ++ .../nativeui/include/breath/BreathExerPage.h | 62 ++ .../nativeui/include/breath/BreathMainPage.h | 48 ++ .../nativeui/include/breath/BreathModel.h | 57 ++ .../nativeui/include/breath/BreathPresenter.h | 19 + .../include/breath/BreathResultPage.h | 55 ++ .../nativeui/include/breath/BreathRhyPage.h | 44 ++ .../nativeui/include/breath/BreathStartPage.h | 51 ++ .../nativeui/include/breath/BreathView.h | 24 + .../callerlog}/CallerItemView.h | 4 +- .../callerlog}/CallerLogModel.h | 2 +- .../callerlog}/CallerLogPresenter.h | 2 +- .../callerlog}/CallerLogView.h | 6 +- .../nativeui/include/camera/CameraMainPage.h | 84 +++ .../nativeui/include/camera/CameraModel.h | 27 + .../nativeui/include/camera/CameraPresenter.h | 20 + .../nativeui/include/camera/CameraView.h | 20 + .../clock}/AmbientClockView.h | 4 +- .../include => include/clock}/MainClockView.h | 4 +- .../include/compass/CompassControlView.h | 29 + .../include/compass/CompassFragment.h | 36 + .../nativeui/include/compass/CompassModel.h | 30 + .../include/compass/MainCompassPresenter.h | 25 + .../include/compass/MainCompassView.h | 27 + .../connectnewphone}/ConnectOpenView.h | 0 .../connectnewphone}/ConnectPhonePresenter.h | 2 +- .../connectnewphone}/ConnectPhoneView.h | 6 +- .../connectnewphone}/ConnectSelectView.h | 2 +- .../nativeui/include/date/DateAdapter.h | 43 ++ .../nativeui/include/date/DateButtonAdapter.h | 44 ++ .../include/date/DateButtonItemView.h | 35 + .../nativeui/include/date/DateItemView.h | 39 + .../nativeui/include/date/DateMainPage.h | 58 ++ .../nativeui/include/date/DateMessagePage.h | 40 + .../nativeui/include/date/DateModel.h | 82 ++ .../nativeui/include/date/DatePresenter.h | 36 + .../nativeui/include/date/DateView.h | 20 + .../nativeui/include/emptypage/EmptyPage.h | 48 ++ .../include/emptypage/EmptyPresenter.h | 17 + .../nativeui/include/emptypage/EmptyView.h | 14 + .../include/findphone/FindPhoneMainPage.h | 74 ++ .../include/findphone/FindPhoneModel.h | 42 ++ .../include/findphone/FindPhonePresenter.h | 18 + .../include/findphone/FindPhoneView.h | 20 + .../include/flashlight/FlashLightBlinkPage.h | 40 + .../include/flashlight/FlashLightColorPage.h | 46 ++ .../flashlight/FlashLightDefaultPage.h | 39 + .../include/flashlight/FlashLightModel.h | 73 ++ .../include/flashlight/FlashLightPage.h | 55 ++ .../include/flashlight/FlashLightPlayPage.h | 38 + .../include/flashlight/FlashLightPresenter.h | 18 + .../flashlight/FlashLightSetItemAdapter.h | 54 ++ .../flashlight/FlashLightSetItemView.h | 38 + .../include/flashlight/FlashLightSetPage.h | 49 ++ .../include/flashlight/FlashLightView.h | 25 + .../flashlight/FlashlightUiResourceImage.h | 49 ++ .../heartrate}/HeartModel.h | 2 +- .../heartrate}/HeartRateView.h | 2 +- .../indoorwalk}/CustomizationView.h | 0 .../indoorwalk}/IndoorWalkEndView.h | 0 .../indoorwalk}/IndoorWalkModel.h | 0 .../indoorwalk}/IndoorWalkMotionView.h | 10 +- .../indoorwalk}/IndoorWalkPreparedView.h | 0 .../indoorwalk}/IndoorWalkPresenter.h | 0 .../indoorwalk}/IndoorWalkView.h | 10 +- .../indoorwalk}/MotionPageFifth.h | 2 +- .../indoorwalk}/MotionPageFirst.h | 2 +- .../indoorwalk}/MotionPageFourth.h | 2 +- .../indoorwalk}/MotionPageSecond.h | 2 +- .../indoorwalk}/MotionPageThird.h | 2 +- .../key}/KeyInputListener.h | 0 .../include => include/main}/AppGroupView.h | 0 .../include => include/main}/DialBinParser.h | 6 +- .../main}/DialBinParserManager.h | 10 +- .../main}/DialBinParserV3.h | 17 +- .../include => include/main}/DialBinTypes.h | 0 .../include => include/main}/DialBinTypesV2.h | 2 +- .../include => include/main}/HealthModel.h | 2 +- .../nativeapp/nativeui/include/main/LoadImg.h | 23 + .../include => include/main}/MainModel.h | 0 .../main}/MainPresenterSample.h | 17 +- .../include => include/main}/MainViewSample.h | 24 +- .../nativeui/include/main/MessageAdapter.h | 66 ++ .../nativeui/include/main/MessageItemView.h | 40 + .../nativeui/include/main/MessageMainView.h | 54 ++ .../nativeui/include/main/MessageModel.h | 44 ++ .../main}/ModelListenerSample.h | 0 .../include => include/main}/PullUpDownView.h | 0 .../include => include/main}/UiServersMsg.h | 0 .../{main/include => include/main}/UiViewId.h | 0 .../main}/VolumeSettingPresenter.h | 4 +- .../main}/VolumeSettingView.h | 4 +- .../main}/dial/DialArcLabelView.h | 2 +- .../main}/dial/DialArcProgressView.h | 3 +- .../main}/dial/DialBaseModel.h | 2 +- .../main}/dial/DialBoxProgressView.h | 3 +- .../main}/dial/DialDataBase.h | 2 +- .../main}/dial/DialDataType.h | 0 .../main}/dial/DialDigitalImgView.h | 4 +- .../main}/dial/DialKaleidoscopeView.h | 0 .../main}/dial/DialLabelView.h | 2 +- .../main}/dial/DialModelHeartRate.h | 2 +- .../main}/dial/DialModelPower.h | 2 +- .../main}/dial/DialModelSteps.h | 2 +- .../main}/dial/DialModelTime.h | 2 +- .../main}/dial/DialOHSliceId.h | 0 .../main}/dial/DialOptionImgView.h | 4 +- .../main}/dial/DialRotateImgView.h | 2 +- .../main}/dial/DialSequenceImgView.h | 0 .../main}/dial/DialStaticImgView.h | 2 +- .../main}/dial/DialVideoView.h | 0 .../include => include/main}/dial/DialView.h | 2 +- .../main}/dial/DialViewContainer.h | 4 +- .../main}/dial/DialViewGroup.h | 12 +- .../main}/dial/ModelDialDataFactory.h | 6 +- .../main}/dial/OnDialDataUpdateListener.h | 2 +- .../main}/dial/RegisterDialModel.h | 4 +- .../main}/dial/WatchInterface.h | 39 +- .../makephone}/CallerDisplayView.h | 0 .../makephone}/CallingView.h | 0 .../makephone}/DialingScreenView.h | 0 .../makephone}/MainCallingPresenter.h | 6 +- .../makephone}/MainCallingView.h | 8 +- .../makephone}/WaitingHintsView.h | 0 .../offlinevoice}/MainVocassistView.h | 4 +- .../offlinevoice}/VocassistModel.h | 2 +- .../offlinevoice}/VocassistPresenter.h | 4 +- .../offlinevoice}/VocassistView.h | 2 +- .../phoneservice}/PhoneAudio.h | 0 .../phoneservice}/PhoneService.h | 2 +- .../nativeui/include/player/BluetoothView.h | 50 ++ .../player}/PlayersCaseListAdapter.h | 0 .../include => include/player}/PlayersModel.h | 9 +- .../player}/PlayersPresenter.h | 28 +- .../include => include/player}/PlayersView.h | 2 +- .../include/qrcode_conn/QrcodeConnModel.h | 31 + .../include/qrcode_conn/QrcodeConnPresenter.h | 31 + .../include/qrcode_conn/QrcodeConnView.h | 45 ++ .../rebootdevice}/RebootDeviceView.h | 0 .../rebootdevice}/RebootModel.h | 0 .../rebootdevice}/RebootPresenter.h | 0 .../rebootdevice}/RebootView.h | 4 +- .../rebootdevice}/ShutdownDeviceView.h | 0 .../include/recent_app/RecentAppPresenter.h | 33 + .../include/recent_app/RecentAppView.h | 68 ++ .../RestoreDefaultsPresenter.h | 0 .../restoredefaults}/RestoreDefaultsView.h | 6 +- .../restoredefaults}/RestoreSelectView.h | 2 +- .../rtcservice}/RtcService.h | 2 +- .../screennotify}/ui_screennotify.h | 14 + .../screensetting}/ScreenModels.h | 0 .../set_card}/SetCardAdapter.h | 2 +- .../set_card}/SetCardDeleteView.h | 2 +- .../set_card}/SetCardItem.h | 2 +- .../set_card}/SetCardModel.h | 4 +- .../set_card}/SetCardNoCardView.h | 2 +- .../set_card}/SetCardPresenter.h | 2 +- .../set_card}/SetCardView.h | 8 +- .../set_dial}/SetDialInfo.h | 0 .../set_dial}/SetDialModel.h | 2 +- .../set_dial}/SetDialPresenter.h | 14 +- .../set_dial}/SetDialView.h | 0 .../set_dial_style}/SetDialStyleModel.h | 2 +- .../set_dial_style}/SetDialStylePresenter.h | 4 +- .../set_dial_style}/SetDialStyleView.h | 2 +- .../nativeui/include/set_ota/OTACommon.h | 39 + .../nativeui/include/set_ota/OTAModel.h | 56 ++ .../nativeui/include/set_ota/OTAPresenter.h | 44 ++ .../nativeui/include/set_ota/OTAView.h | 45 ++ .../settings}/SetDesktopModel.h | 14 +- .../settings}/SettingAdapter.h | 4 +- .../include/settings/SettingDesktopPage.h | 53 ++ .../settings}/SettingItem.h | 2 +- .../settings}/SettingItemView.h | 4 +- .../include/settings/SettingMainPage.h | 38 + .../settings}/SettingModel.h | 4 +- .../include/settings/SettingPresenter.h | 19 + .../nativeui/include/settings/SettingView.h | 22 + .../include/sleep/SleepingDetailsPage.h | 75 ++ .../nativeui/include/sleep/SleepingMainPage.h | 83 +++ .../nativeui/include/sleep/SleepingModel.h | 82 ++ .../include/sleep/SleepingPresenter.h | 18 + .../nativeui/include/sleep/SleepingView.h | 22 + .../nativeui/include/sleep/TargetSleepTime.h | 50 ++ .../nativeui/include/sports/SportsModel.h | 44 ++ .../nativeui/include/sports/SportsPresenter.h | 25 + .../nativeui/include/sports/SportsView.h | 48 ++ .../include/stopwatch/StopwatchAdapter.h | 31 + .../include/stopwatch/StopwatchItemView.h | 33 + .../include/stopwatch/StopwatchModel.h | 62 ++ .../include/stopwatch/StopwatchPage.h | 79 ++ .../include/stopwatch/StopwatchPresenter.h | 17 + .../include/stopwatch/StopwatchView.h | 19 + .../temperature}/TempClickMea.h | 2 +- .../temperature}/TempContinueWarn.h | 2 +- .../temperature}/TempExitInter.h | 4 +- .../temperature}/TempExitPrompt.h | 2 +- .../temperature}/TempInitInter.h | 4 +- .../temperature}/TempJoinStudy.h | 2 +- .../temperature}/TempLittleTip.h | 2 +- .../temperature}/TempMainView.h | 32 +- .../temperature}/TempMeaProcess.h | 2 +- .../temperature}/TempMeasure.h | 4 +- .../temperature}/TempModel.h | 0 .../temperature}/TempPresenter.h | 2 +- .../temperature}/TempPromptWear.h | 2 +- .../temperature}/TempRemindWear.h | 2 +- .../temperature}/TempReport.h | 4 +- .../temperature}/TempStudyAbout.h | 2 +- .../temperature}/TempWarn.h | 2 +- .../nativeui/include/timers/TimerMainPage.h | 49 ++ .../nativeui/include/timers/TimerModel.h | 56 ++ .../nativeui/include/timers/TimerPresenter.h | 31 + .../include/timers/TimerSettingPage.h | 54 ++ .../nativeui/include/timers/TimerTimingPage.h | 81 ++ .../nativeui/include/timers/TimerView.h | 24 + .../nativeui/include/training/DataView.h | 45 ++ .../nativeui/include/training/MenuView.h | 57 ++ .../nativeui/include/training/PauseView.h | 35 + .../nativeui/include/training/PrepareView.h | 47 ++ .../nativeui/include/training/PromptView.h | 34 + .../nativeui/include/training/TargetAdapter.h | 54 ++ .../include/training/TargetItemView.h | 38 + .../include/training/TargetSettingView.h | 36 + .../nativeui/include/training/TargetView.h | 48 ++ .../include/training/TrainingAdapter.h | 54 ++ .../include/training/TrainingItemView.h | 38 + .../nativeui/include/training/TrainingModel.h | 31 + .../include/training/TrainingPresenter.h | 45 ++ .../include/training/TrainingSettingAdapter.h | 54 ++ .../training/TrainingSettingItemView.h | 38 + .../include/training/TrainingSettingView.h | 58 ++ .../nativeui/include/training/TrainingView.h | 77 ++ .../uisample}/UISampleModel.h | 2 +- .../uisample}/UISamplePresenter.h | 0 .../uisample}/UISampleView.h | 0 .../nativeui/include/uiservice/ui_language.h | 22 + .../uiservice}/ui_service.h | 2 + .../include => include/videocard}/VideoCard.h | 6 +- .../nativeui/include/weather/WeatherAdapter.h | 60 ++ .../include/weather/WeatherItemView.h | 36 + .../include/weather/WeatherMainPage.h | 54 ++ .../nativeui/include/weather/WeatherModel.h | 185 +++++ .../include/weather/WeatherPageSecond.h | 51 ++ .../include/weather/WeatherPageThird.h | 46 ++ .../include/weather/WeatherPresenter.h | 18 + .../nativeui/include/weather/WeatherView.h | 21 + .../indoorwalk/src/CustomizationView.cpp | 4 +- .../indoorwalk/src/IndoorWalkEndView.cpp | 4 +- .../indoorwalk/src/IndoorWalkModel.cpp | 6 +- .../indoorwalk/src/IndoorWalkMotionView.cpp | 10 +- .../indoorwalk/src/IndoorWalkPreparedView.cpp | 6 +- .../indoorwalk/src/IndoorWalkPresenter.cpp | 8 +- .../indoorwalk/src/IndoorWalkView.cpp | 4 +- .../indoorwalk/src/MotionPageFifth.cpp | 2 +- .../indoorwalk/src/MotionPageFirst.cpp | 6 +- .../indoorwalk/src/MotionPageFourth.cpp | 6 +- .../indoorwalk/src/MotionPageSecond.cpp | 6 +- .../indoorwalk/src/MotionPageThird.cpp | 6 +- .../nativeui/key/src/KeyInputListener.cpp | 16 +- .../nativeui/main/src/HealthModel.cpp | 2 +- .../nativeapp/nativeui/main/src/LoadImg.cpp | 40 + .../nativeapp/nativeui/main/src/MainModel.cpp | 7 +- .../nativeui/main/src/MainPresenterSample.cpp | 35 +- .../nativeui/main/src/MainViewSample.cpp | 10 +- .../nativeui/main/src/MessageAdapter.cpp | 82 ++ .../nativeui/main/src/MessageItemView.cpp | 96 +++ .../nativeui/main/src/MessageMainView.cpp | 374 ++++++++++ .../nativeui/main/src/MessageModel.cpp | 107 +++ .../nativeui/main/src/ModelListenerSample.cpp | 2 +- .../nativeui/main/src/PullUpDownView.cpp | 8 +- .../main/src/VolumeSettingPresenter.cpp | 14 +- .../nativeui/main/src/VolumeSettingView.cpp | 4 +- .../main/src/dial/DialArcLabelView.cpp | 2 +- .../main/src/dial/DialArcProgressView.cpp | 14 +- .../main/src/dial/DialBoxProgressView.cpp | 14 +- .../nativeui/main/src/dial/DialDataBase.cpp | 2 +- .../main/src/dial/DialDigitalImgView.cpp | 2 +- .../nativeui/main/src/dial/DialLabelView.cpp | 2 +- .../main/src/dial/DialModelHeartRate.cpp | 4 +- .../nativeui/main/src/dial/DialModelPower.cpp | 24 +- .../nativeui/main/src/dial/DialModelSteps.cpp | 4 +- .../nativeui/main/src/dial/DialModelTime.cpp | 10 +- .../main/src/dial/DialOptionImgView.cpp | 2 +- .../main/src/dial/DialRotateImgView.cpp | 2 +- .../main/src/dial/DialSequenceImgView.cpp | 2 +- .../main/src/dial/DialStaticImgView.cpp | 2 +- .../nativeui/main/src/dial/DialVideoView.cpp | 2 +- .../main/src/dial/DialViewContainer.cpp | 6 +- .../nativeui/main/src/dial/DialViewGroup.cpp | 14 +- .../main/src/dial/ModelDialDataFactory.cpp | 2 +- .../nativeui/main/src/dial/WatchInterface.cpp | 374 ++++++---- .../makephone/src/CallerDisplayView.cpp | 4 +- .../nativeui/makephone/src/CallingView.cpp | 4 +- .../makephone/src/DialingScreenView.cpp | 4 +- .../makephone/src/MainCallingPresenter.cpp | 14 +- .../makephone/src/MainCallingView.cpp | 6 +- .../makephone/src/WaitingHintsView.cpp | 6 +- .../offlinevoice/src/MainVocassistView.cpp | 4 +- .../offlinevoice/src/VocassistModel.cpp | 8 +- .../offlinevoice/src/VocassistPresenter.cpp | 7 +- .../offlinevoice/src/VocassistView.cpp | 10 +- .../nativeui/phoneservice/src/PhoneAudio.cpp | 4 +- .../phoneservice/src/PhoneService.cpp | 6 +- .../nativeui/player/src/BluetoothView.cpp | 8 +- .../player/src/PlayersCaseListAdapter.cpp | 8 +- .../nativeui/player/src/PlayersModel.cpp | 31 +- .../nativeui/player/src/PlayersPresenter.cpp | 19 +- .../nativeui/player/src/PlayersView.cpp | 8 +- .../qrcode_conn/src/QrcodeConnModel.cpp | 20 + .../qrcode_conn/src/QrcodeConnPresenter.cpp | 39 + .../qrcode_conn/src/QrcodeConnView.cpp | 91 +++ .../rebootdevice/src/RebootDeviceView.cpp | 7 +- .../nativeui/rebootdevice/src/RebootModel.cpp | 2 +- .../rebootdevice/src/RebootPresenter.cpp | 6 +- .../nativeui/rebootdevice/src/RebootView.cpp | 10 +- .../rebootdevice/src/ShutdownDeviceView.cpp | 7 +- .../recent_app/src/RecentAppPresenter.cpp | 90 +++ .../nativeui/recent_app/src/RecentAppView.cpp | 204 +++++ .../src/RestoreDefaultsView.cpp | 2 +- .../restoredefaults/src/RestorePresenter.cpp | 62 +- .../restoredefaults/src/RestoreSelectView.cpp | 7 +- .../nativeui/rtcservice/src/RtcService.cpp | 4 +- .../screennotify/src/ui_screennotify.cpp | 80 +- .../screensetting/src/ScreenModels.cpp | 4 +- .../nativeui/set_card/src/SetCardAdapter.cpp | 2 +- .../set_card/src/SetCardDeleteView.cpp | 2 +- .../nativeui/set_card/src/SetCardItem.cpp | 4 +- .../nativeui/set_card/src/SetCardModel.cpp | 4 +- .../set_card/src/SetCardNoCardView.cpp | 2 +- .../set_card/src/SetCardPresenter.cpp | 6 +- .../nativeui/set_card/src/SetCardView.cpp | 4 +- .../set_desktop/include/SetDesktopPresenter.h | 35 - .../set_desktop/include/SetDesktopView.h | 57 -- .../set_desktop/src/SetDesktopPresenter.cpp | 66 -- .../nativeui/set_dial/src/SetDialModel.cpp | 8 +- .../set_dial/src/SetDialPresenter.cpp | 28 +- .../nativeui/set_dial/src/SetDialView.cpp | 6 +- .../set_dial_style/src/SetDialStyleModel.cpp | 2 +- .../src/SetDialStylePresenter.cpp | 6 +- .../set_dial_style/src/SetDialStyleView.cpp | 11 +- .../nativeui/set_ota/src/OTAModel.cpp | 150 ++++ .../nativeui/set_ota/src/OTAPresenter.cpp | 126 ++++ .../nativeui/set_ota/src/OTAView.cpp | 133 ++++ .../settings/include/SettingPresenter.h | 34 - .../nativeui/settings/include/SettingView.h | 35 - .../src/SetDesktopModel.cpp | 13 +- .../nativeui/settings/src/SettingAdapter.cpp | 2 +- .../src/SettingDesktopPage.cpp} | 95 ++- .../nativeui/settings/src/SettingItemView.cpp | 7 +- .../nativeui/settings/src/SettingMainPage.cpp | 174 +++++ .../nativeui/settings/src/SettingModel.cpp | 29 +- .../settings/src/SettingPresenter.cpp | 68 +- .../nativeui/settings/src/SettingView.cpp | 121 --- .../sleep/src/SleepingDetailsPage.cpp | 635 ++++++++++++++++ .../nativeui/sleep/src/SleepingMainPage.cpp | 705 ++++++++++++++++++ .../nativeui/sleep/src/SleepingModel.cpp | 283 +++++++ .../nativeui/sleep/src/SleepingPresenter.cpp | 13 + .../nativeui/sleep/src/TargetSleepTime.cpp | 335 +++++++++ .../nativeui/sports/src/SportsModel.cpp | 266 +++++++ .../nativeui/sports/src/SportsPresenter.cpp | 48 ++ .../nativeui/sports/src/SportsView.cpp | 213 ++++++ .../stopwatch/src/StopwatchAdapter.cpp | 63 ++ .../stopwatch/src/StopwatchItemView.cpp | 80 ++ .../nativeui/stopwatch/src/StopwatchModel.cpp | 120 +++ .../nativeui/stopwatch/src/StopwatchPage.cpp | 588 +++++++++++++++ .../stopwatch/src/StopwatchPresenter.cpp | 14 + .../nativeui/temperature/src/TempClickMea.cpp | 2 +- .../temperature/src/TempContinueWarn.cpp | 2 +- .../temperature/src/TempExitInter.cpp | 2 +- .../temperature/src/TempExitPrompt.cpp | 2 +- .../temperature/src/TempInitInter.cpp | 2 +- .../temperature/src/TempJoinStudy.cpp | 2 +- .../temperature/src/TempLittleTip.cpp | 2 +- .../nativeui/temperature/src/TempMainView.cpp | 6 +- .../temperature/src/TempMeaProcess.cpp | 4 +- .../nativeui/temperature/src/TempMeasure.cpp | 2 +- .../nativeui/temperature/src/TempModel.cpp | 4 +- .../temperature/src/TempPresenter.cpp | 7 +- .../temperature/src/TempPromptWear.cpp | 2 +- .../temperature/src/TempRemindWear.cpp | 2 +- .../nativeui/temperature/src/TempReport.cpp | 2 +- .../temperature/src/TempStudyAbout.cpp | 2 +- .../nativeui/temperature/src/TempWarn.cpp | 2 +- .../nativeui/timers/src/TimerMainPage.cpp | 199 +++++ .../nativeui/timers/src/TimerModel.cpp | 103 +++ .../nativeui/timers/src/TimerPresenter.cpp | 15 + .../nativeui/timers/src/TimerSettingPage.cpp | 386 ++++++++++ .../nativeui/timers/src/TimerTimingPage.cpp | 548 ++++++++++++++ .../nativeui/training/src/DataView.cpp | 363 +++++++++ .../nativeui/training/src/MenuView.cpp | 133 ++++ .../nativeui/training/src/PauseView.cpp | 179 +++++ .../nativeui/training/src/PrepareView.cpp | 345 +++++++++ .../nativeui/training/src/PromptView.cpp | 138 ++++ .../nativeui/training/src/TargetAdapter.cpp | 64 ++ .../nativeui/training/src/TargetItemView.cpp | 76 ++ .../training/src/TargetSettingView.cpp | 185 +++++ .../nativeui/training/src/TargetView.cpp | 134 ++++ .../nativeui/training/src/TrainingAdapter.cpp | 64 ++ .../training/src/TrainingItemView.cpp | 78 ++ .../nativeui/training/src/TrainingModel.cpp | 40 + .../training/src/TrainingPresenter.cpp | 213 ++++++ .../training/src/TrainingSettingAdapter.cpp | 64 ++ .../training/src/TrainingSettingItemView.cpp | 75 ++ .../training/src/TrainingSettingView.cpp | 134 ++++ .../nativeui/training/src/TrainingView.cpp | 297 ++++++++ .../nativeui/uisample/src/UISampleModel.cpp | 2 +- .../uisample/src/UISamplePresenter.cpp | 10 +- .../nativeui/uisample/src/UISampleView.cpp | 4 +- .../framework/src/test_case_list_adapter.cpp | 2 +- .../uitest/framework/src/ui_test_group.cpp | 2 + .../nativeui/uiservice/src/ui_language.cpp | 72 ++ .../nativeui/uiservice/src/ui_service.cpp | 25 +- .../nativeui/videocard/src/VideoCard.cpp | 10 +- .../nativeui/weather/src/WeatherAdapter.cpp | 67 ++ .../nativeui/weather/src/WeatherItemView.cpp | 98 +++ .../nativeui/weather/src/WeatherMainPage.cpp | 336 +++++++++ .../nativeui/weather/src/WeatherModel.cpp | 411 ++++++++++ .../weather/src/WeatherPageSecond.cpp | 264 +++++++ .../nativeui/weather/src/WeatherPageThird.cpp | 206 +++++ .../nativeui/weather/src/WeatherPresenter.cpp | 16 + .../wearable/ohos_deps/CMakeLists.txt | 2 + .../wearable/ohos_deps/wearable_log.h | 69 +- .../wearable/ohos_deps/wearable_onlinelog.c | 155 ++++ .../wearable/ohos_deps/wearable_onlinelog.h | 48 ++ .../wearable/ohos_startup/CMakeLists.txt | 1 + .../wearable/ohos_startup/ohosfwk_startup.c | 4 + .../wearable/service/CMakeLists.txt | 2 + .../wearable/service/app_store/CMakeLists.txt | 1 - .../wearable/service/app_store/app_store.cpp | 47 +- .../wearable/service/app_store/app_store.h | 6 + .../service/app_store/app_store_msg.cpp | 1 + .../broadcast/include/broadcast_feature.h | 4 +- .../broadcast/src/broadcast_implement.c | 3 + .../service/device_msg/CMakeLists.txt | 51 ++ .../service/device_msg/device_location.cpp | 174 +++++ .../service/device_msg/device_location.h | 20 + .../service/device_msg/device_msg.cpp | 191 +++++ .../service/device_msg/device_proxy.cpp | 476 ++++++++++++ .../service/device_msg/device_proxy.h | 104 +++ .../service/device_msg/msg_center_device.cpp | 520 +++++++++++++ .../service/device_msg/msg_center_device.h | 114 +++ .../service/dial_market/CMakeLists.txt | 1 - .../service/dial_market/dial_market.cpp | 244 ++++++ .../service/dial_market/dial_market_msg.cpp | 47 ++ .../service/msg_center/CMakeLists.txt | 32 +- .../brandy-auto-ota-cli/libmsg_center.a | Bin 148842 -> 147266 bytes .../brandy-auto-ota-ser/libmsg_center.a | Bin 148842 -> 147266 bytes .../brandy-native-js/libmsg_center.a | Bin 148842 -> 147266 bytes .../msg_center/brandy-xts/libmsg_center.a | Bin 148842 -> 147266 bytes .../msg_center/include/msg_center_protocol.h | 2 + .../include/notify/notification_manager.h | 1 + .../include/notify/phone_msg_notification.h | 75 ++ .../src/common/msg_center_self_cmd.cpp | 43 ++ .../msg_center/src/msg_center_customer.cpp | 241 +++--- .../src/notify/alarm_notification.cpp | 3 +- .../ketinput/src/NotifyOnKeyListener.cpp | 16 +- .../src/notify/makephone_notification.cpp | 8 +- .../src/notify/phone_msg_notification.cpp | 206 +++++ .../src/actions/display_action.c | 2 +- .../service/remote_msg/CMakeLists.txt | 37 + .../service/remote_msg/remote_msg.cpp | 73 ++ .../wearable/service/remote_msg/remote_msg.h | 33 + .../service/xiaodu_voice/xiaodu_voice.cpp | 88 ++- .../service/xiaodu_voice/xiaodu_voice_msg.cpp | 3 + 735 files changed, 28048 insertions(+), 3372 deletions(-) create mode 100644 code/sdk/application/wearable/nativeabilityfwk/include/RecentManager.h create mode 100644 code/sdk/application/wearable/nativeabilityfwk/include/SlicePage.h create mode 100644 code/sdk/application/wearable/nativeabilityfwk/include/SlicePageFactory.h create mode 100644 code/sdk/application/wearable/nativeabilityfwk/include/SlicePageManager.h create mode 100644 code/sdk/application/wearable/nativeabilityfwk/src/AbilitySlice.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/UICardPageFactory.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_breath.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_camera.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_date.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_findPhone.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_sleep.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_string.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_timer.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_weather.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_stopwatch_resource.h create mode 100644 code/sdk/application/wearable/nativeapp/nativelauncher/src/UICardPageFactory.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathDurPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathExerPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathResultPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathRhyPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathStartPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraPresenter.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassCalibrationView.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassControlView.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassModel.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassPresenter.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassView.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassPresenter.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassView.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassCalibrationView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassFragment.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassPresenter.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMessagePage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DateModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/date/src/DatePresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhonePresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightBlinkPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightColorPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightDefaultPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPlayPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetPage.cpp rename code/sdk/application/wearable/nativeapp/nativeui/{activity/include => include/activity}/ActivityModel.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{activity/include => include/activity}/ActivityPresenter.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{activity/include => include/activity}/ActivityWeekView.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{activity/include => include/activity}/MainActivityView.h (81%) rename code/sdk/application/wearable/nativeapp/nativeui/{add_card/include => include/add_card}/AddCardAdapter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{add_card/include => include/add_card}/AddCardItem.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{add_card/include => include/add_card}/AddCardModel.h (88%) rename code/sdk/application/wearable/nativeapp/nativeui/{add_card/include => include/add_card}/AddCardPresenter.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{add_card/include => include/add_card}/AddCardView.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmClockModel.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmCloseRingView.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmConfigView.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmJudgeView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmMaxClock.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmNewTimeView.h (86%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmPopUpPresenter.h (86%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmPopUpView.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmPresenter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmRingView.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmSetTimeView.h (86%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/AlarmSetWeekView.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarm/include => include/alarm}/MainAlarmView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarmclockmanage/include => include/alarmclockmanage}/AlarmClockManage.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarmclockmanage/include => include/alarmclockmanage}/AlmmgrAlarmClockManage.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alarmclocktimerconfig/include => include/alarmclocktimerconfig}/AlarmClockTimerConfig.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayBarCode.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayBind.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayBindAni.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayBindRes.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayExitBind.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayHelp.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayList/AlipayListAdapter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayList/AlipayListItem.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayList/AlipayListItemView.h (88%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayList/AlipayListView.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayMainView.h (76%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayModel.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayPayCode.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayPresenter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayRefreshBindCode.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipaySetting.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayGetTransList.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransAni.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransCode.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransEnable.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransListAdapter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransListItem.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransListItemView.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransListView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransRes.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayTrans/AlipayTransTips.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayUnbind.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{alipay/include => include/alipay}/AlipayUnbindFinish.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{aod_view/include => include/aod_view}/AodModel.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{aod_view/include => include/aod_view}/AodPresenter.h (82%) rename code/sdk/application/wearable/nativeapp/nativeui/{aod_view/include => include/aod_view}/AodView.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{applist/include => include/applist}/AppItemView.h (79%) rename code/sdk/application/wearable/nativeapp/nativeui/{applist/include => include/applist}/ApplistAdapter.h (94%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistModel.h rename code/sdk/application/wearable/nativeapp/nativeui/{applist/include => include/applist}/ApplistPresenter.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{applist/include => include/applist}/ApplistView.h (96%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodView.h rename code/sdk/application/wearable/nativeapp/nativeui/{bloodoxygen/include => include/bloodoxygen}/BloodBandoffView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bloodoxygen/include => include/bloodoxygen}/BloodOxygenModel.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bloodoxygen/include => include/bloodoxygen}/BloodOxygenPresenter.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{bloodoxygen/include => include/bloodoxygen}/BloodOxygenView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothCaseListAdapter.h (88%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothChangeBle.h rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothDeviceCaseListAdapter.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothDeviceListView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothEarListView.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothEarPhoneView.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothHeadsetEvent.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothItemView.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothModel.h (88%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothOptionsView.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothPresenter.h (88%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothReconnectView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/BluetoothWrapper.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/MainBluetoothView.h (81%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/TipsConnFailMessageView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/TipsFailMessageView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{bluetooth/include => include/bluetooth}/TipsSuccMessageView.h (100%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathDurPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathExerPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathResultPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathRhyPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathStartPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathView.h rename code/sdk/application/wearable/nativeapp/nativeui/{callerlog/include => include/callerlog}/CallerItemView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{callerlog/include => include/callerlog}/CallerLogModel.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{callerlog/include => include/callerlog}/CallerLogPresenter.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{callerlog/include => include/callerlog}/CallerLogView.h (92%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraView.h rename code/sdk/application/wearable/nativeapp/nativeui/{clock/include => include/clock}/AmbientClockView.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{clock/include => include/clock}/MainClockView.h (96%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassControlView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassFragment.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassView.h rename code/sdk/application/wearable/nativeapp/nativeui/{connectnewphone/include => include/connectnewphone}/ConnectOpenView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{connectnewphone/include => include/connectnewphone}/ConnectPhonePresenter.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{connectnewphone/include => include/connectnewphone}/ConnectPhoneView.h (85%) rename code/sdk/application/wearable/nativeapp/nativeui/{connectnewphone/include => include/connectnewphone}/ConnectSelectView.h (86%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMessagePage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DatePresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/date/DateView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhonePresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightBlinkPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightColorPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightDefaultPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPlayPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashlightUiResourceImage.h rename code/sdk/application/wearable/nativeapp/nativeui/{heartrate/include => include/heartrate}/HeartModel.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{heartrate/include => include/heartrate}/HeartRateView.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/CustomizationView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/IndoorWalkEndView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/IndoorWalkModel.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/IndoorWalkMotionView.h (82%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/IndoorWalkPreparedView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/IndoorWalkPresenter.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/IndoorWalkView.h (82%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/MotionPageFifth.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/MotionPageFirst.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/MotionPageFourth.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/MotionPageSecond.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{indoorwalk/include => include/indoorwalk}/MotionPageThird.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{key/include => include/key}/KeyInputListener.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/AppGroupView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/DialBinParser.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/DialBinParserManager.h (81%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/DialBinParserV3.h (82%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/DialBinTypes.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/DialBinTypesV2.h (99%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/HealthModel.h (94%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/main/LoadImg.h rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/MainModel.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/MainPresenterSample.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/MainViewSample.h (86%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageMainView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageModel.h rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/ModelListenerSample.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/PullUpDownView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/UiServersMsg.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/UiViewId.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/VolumeSettingPresenter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/VolumeSettingView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialArcLabelView.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialArcProgressView.h (78%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialBaseModel.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialBoxProgressView.h (78%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialDataBase.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialDataType.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialDigitalImgView.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialKaleidoscopeView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialLabelView.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialModelHeartRate.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialModelPower.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialModelSteps.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialModelTime.h (97%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialOHSliceId.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialOptionImgView.h (93%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialRotateImgView.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialSequenceImgView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialStaticImgView.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialVideoView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialView.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialViewContainer.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/DialViewGroup.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/ModelDialDataFactory.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/OnDialDataUpdateListener.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/RegisterDialModel.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{main/include => include/main}/dial/WatchInterface.h (59%) rename code/sdk/application/wearable/nativeapp/nativeui/{makephone/include => include/makephone}/CallerDisplayView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{makephone/include => include/makephone}/CallingView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{makephone/include => include/makephone}/DialingScreenView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{makephone/include => include/makephone}/MainCallingPresenter.h (84%) rename code/sdk/application/wearable/nativeapp/nativeui/{makephone/include => include/makephone}/MainCallingView.h (83%) rename code/sdk/application/wearable/nativeapp/nativeui/{makephone/include => include/makephone}/WaitingHintsView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{offlinevoice/include => include/offlinevoice}/MainVocassistView.h (85%) rename code/sdk/application/wearable/nativeapp/nativeui/{offlinevoice/include => include/offlinevoice}/VocassistModel.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{offlinevoice/include => include/offlinevoice}/VocassistPresenter.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{offlinevoice/include => include/offlinevoice}/VocassistView.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{phoneservice/include => include/phoneservice}/PhoneAudio.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{phoneservice/include => include/phoneservice}/PhoneService.h (99%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/player/BluetoothView.h rename code/sdk/application/wearable/nativeapp/nativeui/{player/include => include/player}/PlayersCaseListAdapter.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{player/include => include/player}/PlayersModel.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{player/include => include/player}/PlayersPresenter.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{player/include => include/player}/PlayersView.h (96%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnView.h rename code/sdk/application/wearable/nativeapp/nativeui/{rebootdevice/include => include/rebootdevice}/RebootDeviceView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{rebootdevice/include => include/rebootdevice}/RebootModel.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{rebootdevice/include => include/rebootdevice}/RebootPresenter.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{rebootdevice/include => include/rebootdevice}/RebootView.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{rebootdevice/include => include/rebootdevice}/ShutdownDeviceView.h (100%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppView.h rename code/sdk/application/wearable/nativeapp/nativeui/{restoredefaults/include => include/restoredefaults}/RestoreDefaultsPresenter.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{restoredefaults/include => include/restoredefaults}/RestoreDefaultsView.h (84%) rename code/sdk/application/wearable/nativeapp/nativeui/{restoredefaults/include => include/restoredefaults}/RestoreSelectView.h (86%) rename code/sdk/application/wearable/nativeapp/nativeui/{rtcservice/include => include/rtcservice}/RtcService.h (86%) rename code/sdk/application/wearable/nativeapp/nativeui/{screennotify/include => include/screennotify}/ui_screennotify.h (67%) rename code/sdk/application/wearable/nativeapp/nativeui/{screensetting/include => include/screensetting}/ScreenModels.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardAdapter.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardDeleteView.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardItem.h (88%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardModel.h (91%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardNoCardView.h (88%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardPresenter.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_card/include => include/set_card}/SetCardView.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial/include => include/set_dial}/SetDialInfo.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial/include => include/set_dial}/SetDialModel.h (94%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial/include => include/set_dial}/SetDialPresenter.h (75%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial/include => include/set_dial}/SetDialView.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial_style/include => include/set_dial_style}/SetDialStyleModel.h (96%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial_style/include => include/set_dial_style}/SetDialStylePresenter.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_dial_style/include => include/set_dial_style}/SetDialStyleView.h (96%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTACommon.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAView.h rename code/sdk/application/wearable/nativeapp/nativeui/{set_desktop/include => include/settings}/SetDesktopModel.h (58%) rename code/sdk/application/wearable/nativeapp/nativeui/{settings/include => include/settings}/SettingAdapter.h (94%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingDesktopPage.h rename code/sdk/application/wearable/nativeapp/nativeui/{settings/include => include/settings}/SettingItem.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{settings/include => include/settings}/SettingItemView.h (93%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingMainPage.h rename code/sdk/application/wearable/nativeapp/nativeui/{settings/include => include/settings}/SettingModel.h (93%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingDetailsPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sleep/TargetSleepTime.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchView.h rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempClickMea.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempContinueWarn.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempExitInter.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempExitPrompt.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempInitInter.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempJoinStudy.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempLittleTip.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempMainView.h (76%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempMeaProcess.h (92%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempMeasure.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempModel.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempPresenter.h (95%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempPromptWear.h (90%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempRemindWear.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempReport.h (87%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempStudyAbout.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{temperature/include => include/temperature}/TempWarn.h (90%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerSettingPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerTimingPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/DataView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/MenuView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/PauseView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/PrepareView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/PromptView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetSettingView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingView.h rename code/sdk/application/wearable/nativeapp/nativeui/{uisample/include => include/uisample}/UISampleModel.h (89%) rename code/sdk/application/wearable/nativeapp/nativeui/{uisample/include => include/uisample}/UISamplePresenter.h (100%) rename code/sdk/application/wearable/nativeapp/nativeui/{uisample/include => include/uisample}/UISampleView.h (100%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_language.h rename code/sdk/application/wearable/nativeapp/nativeui/{uiservice/include => include/uiservice}/ui_service.h (97%) rename code/sdk/application/wearable/nativeapp/nativeui/{videocard/include => include/videocard}/VideoCard.h (91%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherAdapter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherItemView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherMainPage.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherModel.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageSecond.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageThird.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPresenter.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherView.h create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/main/src/LoadImg.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageMainView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppView.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopPresenter.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopView.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAView.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingPresenter.h delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingView.h rename code/sdk/application/wearable/nativeapp/nativeui/{set_desktop => settings}/src/SetDesktopModel.cpp (83%) rename code/sdk/application/wearable/nativeapp/nativeui/{set_desktop/src/SetDesktopView.cpp => settings/src/SettingDesktopPage.cpp} (55%) create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingMainPage.cpp delete mode 100644 code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingDetailsPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sleep/src/TargetSleepTime.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerSettingPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerTimingPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/DataView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/MenuView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/PauseView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/PrepareView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/PromptView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetSettingView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingPresenter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_language.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherAdapter.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherItemView.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherMainPage.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherModel.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageSecond.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageThird.cpp create mode 100644 code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPresenter.cpp create mode 100644 code/sdk/application/wearable/ohos_deps/wearable_onlinelog.c create mode 100644 code/sdk/application/wearable/ohos_deps/wearable_onlinelog.h create mode 100644 code/sdk/application/wearable/service/device_msg/CMakeLists.txt create mode 100644 code/sdk/application/wearable/service/device_msg/device_location.cpp create mode 100644 code/sdk/application/wearable/service/device_msg/device_location.h create mode 100644 code/sdk/application/wearable/service/device_msg/device_msg.cpp create mode 100644 code/sdk/application/wearable/service/device_msg/device_proxy.cpp create mode 100644 code/sdk/application/wearable/service/device_msg/device_proxy.h create mode 100644 code/sdk/application/wearable/service/device_msg/msg_center_device.cpp create mode 100644 code/sdk/application/wearable/service/device_msg/msg_center_device.h create mode 100644 code/sdk/application/wearable/service/dial_market/dial_market.cpp create mode 100644 code/sdk/application/wearable/service/dial_market/dial_market_msg.cpp create mode 100644 code/sdk/application/wearable/service/msg_center/include/notify/phone_msg_notification.h create mode 100644 code/sdk/application/wearable/service/msg_center/src/common/msg_center_self_cmd.cpp create mode 100644 code/sdk/application/wearable/service/msg_center/src/notify/phone_msg_notification.cpp create mode 100644 code/sdk/application/wearable/service/remote_msg/CMakeLists.txt create mode 100644 code/sdk/application/wearable/service/remote_msg/remote_msg.cpp create mode 100644 code/sdk/application/wearable/service/remote_msg/remote_msg.h diff --git a/code/sdk/application/wearable/alipay/service/alipay_bluetooth.c b/code/sdk/application/wearable/alipay/service/alipay_bluetooth.c index 65aafbd99..c394f7ccf 100644 --- a/code/sdk/application/wearable/alipay/service/alipay_bluetooth.c +++ b/code/sdk/application/wearable/alipay/service/alipay_bluetooth.c @@ -17,7 +17,7 @@ #include "securec.h" #include "cmsis_os2.h" #ifdef SUPPORT_OHOSFWK -#include "BluetoothWrapper.h" +#include "bluetooth/BluetoothWrapper.h" #endif /* Gatt service UUID */ diff --git a/code/sdk/application/wearable/nativeabilityfwk/CMakeLists.txt b/code/sdk/application/wearable/nativeabilityfwk/CMakeLists.txt index e98bcf649..63e56e84a 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/CMakeLists.txt +++ b/code/sdk/application/wearable/nativeabilityfwk/CMakeLists.txt @@ -19,12 +19,12 @@ set(PRIVATE_HEADER ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/applist/include/ ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include ) set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/Ability.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/AbilitySlice.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/NativeAbility.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/StartNative.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/transition/ZoomTransition.cpp diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/Ability.h b/code/sdk/application/wearable/nativeabilityfwk/include/Ability.h index 9606728be..f6a6877ef 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/Ability.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/Ability.h @@ -16,26 +16,101 @@ #ifndef NATIVEABILITYFWK_ABILITY_H #define NATIVEABILITYFWK_ABILITY_H #include -#include "SliceProxy.h" -#include "Slice.h" #include "wearable_log.h" #include "TransitionType.h" #include "soc_osal.h" #include "gfx_utils/vector.h" #include "graphic_mutex.h" +#include "Slice.h" +#include "SliceProxy.h" +#include "SlicePageManager.h" namespace OHOS { const static uint16_t gSliceInvalid = 0; +const static uint16_t gPageInvalid = 0; const static uint16_t gSliceDefaultPriority = 4; // 页面默认是最低优先级 + class Ability { public: - void AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy); - void ChangeSlice(const uint16_t targetSliceId, TransitionType type = TransitionType::TRANSITION_INVALID, - const uint16_t priority = gSliceDefaultPriority, bool enableSlideBack = false); - void SetDefaultSliceId(const uint16_t defaultSliceId) { - defaultSliceId_ = defaultSliceId; + void AddSliceProxy(uint16_t sliceId, SliceProxy* proxy); + + /** + * @brief Switch to specified page in the current slice, matched page will be created, and current slice will not be + * recreated. if slices or pages is being switched, this operation will be canceled + * @param pageId Indicates the specified id of the page in the current slice, it should not be zero + * @param data Indicates the data which will be transfered to next page, default value is nullptr + * @param type Indicates Transition animation type, which is declared in TransitionType.h. The matched + * Transitioncallback should have params: enableCurrentSnapshot_ = false enableTargetSnapshot_ = false + * @param canBack Indicates whether current page should be cached and can be back from target page + * @return Returns true if the pages is switched successfully, returns false otherwise. + */ + bool SwitchPageInSlice(uint16_t pageId, void* data = nullptr, + TransitionType type = TransitionType::TRANSITION_INVALID, bool canBack = false); + + /** + * @brief Switch to specified slice. matched slice will be created. + * 1. If pageId is valid or default page is exist, matched page will also be created + * 2. If slices is being switched, this operation will be cached and run later. + * @param sliceId Indicates the specified id of the slice + * @param pageId Indicates the specified id of the slice, if pageId is invalid, default page will be used. + * @param type Indicates Transition animation type, which is declared in TransitionType.h + * @param enableSliceBack Indicates whether can return to current slice from target slice by sliding + */ + void SwitchSlice(uint16_t sliceId, uint16_t pageId = gPageInvalid, + TransitionType type = TransitionType::TRANSITION_INVALID, bool enableSlideBack = false); + + /** + * @brief Switch to specified slice. matched slice will be created. + * 1. If default page is exist, default page will also be created + * 2. If slices is being switched, this operation will be cached and run later. + * Note: Method SwitchSlice is recommended, this method is reserved for compatibility. + * @param sliceId Indicates the specified id of the slice + * @param type Indicates Transition animation type, which is declared in TransitionType.h + * @param priority Indicates the priority of slice, default value is used currently. if needed, config it in + * XXXPresenter::OnResume using method SetCurSlicePriority + * @param enableSliceBack Indicates whether can return to current slice from target slice by sliding + */ + void ChangeSlice(uint16_t sliceId, TransitionType type = TransitionType::TRANSITION_INVALID, + uint16_t priority = gSliceDefaultPriority, bool enableSlideBack = false); + + /** + * @brief Get SlicePageManager of currrent slice. you can Use SlicePageManager to get page info in the slice. + * @return Returns nullptr if slices is being switched, or js ability is running + */ + SlicePageManager* GetCurSlicePageManager(); + + void SetDefaultSliceId(uint16_t defaultSliceId, uint16_t pageId = gPageInvalid) + { + defaultTargetId_ = defaultSliceId | (static_cast(pageId) << PAGE_OFFSET); } - uint16_t GetCurSliceId(void) { + + /** + * @brief Get current slice id + * @return Returns 0 if js ability is running, detail refer to comments of variable allSlices_ + */ + uint16_t GetCurSliceId(void) + { + if (allSlices_.IsEmpty()) { + return gSliceInvalid; + } + return static_cast(allSlices_[allSlices_.Size() - 1] & SLICE_MASK); + } + + /** + * @brief Get prevoius slice id in the slice vector, detail refer to comments of variable allSlices_ + */ + uint16_t GetPreSliceId(void) + { + if (allSlices_.Size() < 2) { + return gSliceInvalid; + } + return static_cast(allSlices_[allSlices_.Size() - 2] & SLICE_MASK); + } + + void UpdateCurSlicePageId(uint16_t pageId); + + uint32_t GetCurTargetId(void) + { if (allSlices_.IsEmpty()) { return gSliceInvalid; } @@ -43,30 +118,35 @@ public: return allSlices_[allSlices_.Size() - 1]; } - uint16_t GetPreSliceId(void) { - if (allSlices_.Size() < 2) { + uint32_t GetPreTargetId(void) + { + if (allSlices_.Size() < 2) { // 2, minimum count if contains previous target return gSliceInvalid; } - return allSlices_[allSlices_.Size() - 2]; + + return allSlices_[allSlices_.Size() - 2]; // 2, index offset } - void SetCurSlicePriority(const uint16_t priority) { + void SetCurSlicePriority(uint16_t priority) + { curSlicePriority_ = priority; } - uint16_t GetCurSlicePriority(void) { + uint16_t GetCurSlicePriority(void) + { return curSlicePriority_; } - void StartSlice(const uint16_t sliceId, const uint16_t priority); - void ResumeSliceWithoutJS(); + void ResumeSlice(); void PauseSlice(); - void StopSlice(); - void StopPrevSlice(); void StopSliceTransition(); void BackToPreSlice(); protected: + // targetId consists of slice id and page id + void StartSlice(uint32_t targetId); + void ResumeSliceWithoutJS(); + void StopSlice(); Ability() = default; virtual ~Ability() = default; struct ProxyStruct { @@ -82,17 +162,20 @@ protected: // 预加载的所有slices Graphic::Vector allSlicesProxy_{16}; - // 历史记录的所有slices, 当前只使用了id - // TODO:: 整页面的能力恢复功能待考虑扩展 - Graphic::Vector allSlices_; + /** Processing rule of allSlices_, its item value consists of slice and page. slice | page << 16. + * 1. When switch slice A to main slice, clear slice vector, and then push back main slice into slice vector + * 2. When switch slice A to slice B (not main), push back slice B into slice vector + * 3. When switch js to slice A, clear slice vector, and then push back slice A into slice vector + * 4. When switch slice A to js, push back 0 into slice vector. You Can get slice A by method GetPreSliceId() + */ + Graphic::Vector allSlices_; SliceStruct curSlice_; - SliceStruct prevSlice_; - uint16_t targetSliceIdFromJS_ = 0; - uint16_t defaultSliceId_ = gSliceInvalid; + SliceStruct nextSlice_; + uint32_t targetIdFromJS_ = 0; + uint32_t defaultTargetId_ = gSliceInvalid; uint16_t curSlicePriority_ = gSliceDefaultPriority; - void PostChangeSlice(const uint16_t targetSliceId, TransitionType type, - const uint16_t priority, bool enableSlideBack); + void PostChangeSlice(uint32_t targetId, TransitionType type); Ability::ProxyStruct* Find(const uint16_t sliceId); }; } diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySlice.h b/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySlice.h index a4acb09d7..09a8c81e4 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySlice.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySlice.h @@ -17,7 +17,9 @@ #define NATIVEABILITYFWK_ABILITY_SLICE_H #include #include "Slice.h" -#include "wearable_log.h" +#include "Presenter.h" +#include "View.h" +#include "SlicePageManager.h" namespace OHOS { enum class SliceState : uint8_t { @@ -27,93 +29,33 @@ enum class SliceState : uint8_t { PAUSE, STOP }; -template class AbilitySlice : public Slice { public: - AbilitySlice() - :view_(nullptr), presenter_(nullptr), state_(SliceState::UNINITIALIZED) {} - ~AbilitySlice() {} + AbilitySlice(ViewBase* viewBase, PresenterBase* presenterBase, uint32_t targetId) + : sliceId_(targetId & SLICE_MASK), view_(viewBase), presenter_(presenterBase), + slicePageMgr_(targetId), state_(SliceState::UNINITIALIZED) {} - void OnStart() override - { - if ((presenter_ != nullptr) || (view_ != nullptr)) { - return; - } + void OnStart() override; - presenter_ = new P(); - view_ = new V(); + void OnResume() override; - presenter_->Attach(view_); - view_->Attach(presenter_); + void OnPause() override; - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStart", typeid(view_).name()); - view_->SetupView(); - view_->OnStart(); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStart", typeid(presenter_).name()); - presenter_->OnStart(); - state_ = SliceState::START; - } + void OnStop() override; - void OnResume() override - { - if ((state_ != SliceState::START) && (state_ != SliceState::PAUSE)) { // avoid repeated resume - return; - } - if (presenter_ != nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnResume", typeid(presenter_).name()); - presenter_->OnResume(); - } - if (view_ != nullptr) { - view_->Draw(); - } - state_ = SliceState::RESUME; - } + UIViewGroup* GetSliceContainer() override; - void OnPause() override - { - if (state_ != SliceState::RESUME) { // avoid repeated pause - return; - } - if (presenter_ != nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnPause", typeid(presenter_).name()); - presenter_->OnPause(); - } - state_ = SliceState::PAUSE; - } + bool ChangeSlicePage(uint16_t pageId, void* data, TransitionType type, bool canBack); - void OnStop() override + SlicePageManager* GetSlicePageManger() { - if (view_ != nullptr) { - view_->TearDownView(); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStop", typeid(view_).name()); - view_->OnStop(); - delete view_; - view_ = nullptr; - } - if (presenter_ != nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStop", typeid(presenter_).name()); - presenter_->OnStop(); - delete presenter_; - presenter_ = nullptr; - } - state_ = SliceState::STOP; + return &slicePageMgr_; } - - UIViewGroup* GetSliceContainer() override - { - if (view_ != nullptr) { - return view_->GetRootContainer(); - } else { - return nullptr; - } - } - private: - AbilitySlice(const AbilitySlice &); - AbilitySlice &operator=(const AbilitySlice &); - - V* view_; - P* presenter_; + uint16_t sliceId_; + ViewBase* view_; + PresenterBase* presenter_; + SlicePageManager slicePageMgr_; SliceState state_; }; } // namespace OHOS diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySliceProxy.h b/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySliceProxy.h index d942f0c62..1cb8f8943 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySliceProxy.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/AbilitySliceProxy.h @@ -17,25 +17,26 @@ #define NATIVEABILITYFWK_ABILITY_SLICE_PROXY_H #include "AbilitySlice.h" - #include "wearable_log.h" +#include "Presenter.h" namespace OHOS { template - class AbilitySliceProxy : public SliceProxy { public: - AbilitySliceProxy() {} - ~AbilitySliceProxy() {} - - Slice* CreateSlice() override + Slice* CreateSlice(uint32_t targetId) override { - return new AbilitySlice(); + V* v = new V(); + if (v == nullptr) { + return nullptr; + } + P* p = new P(); + if (p == nullptr) { + delete v; + return nullptr; + } + return new AbilitySlice(v, p, targetId); } - -private: - AbilitySliceProxy(const AbilitySliceProxy &); - AbilitySliceProxy &operator=(const AbilitySliceProxy &); }; } // namespace OHOS #endif // NATIVEABILITYFWK_ABILITY_SLICE_PROXY_H diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/BackDragListener.h b/code/sdk/application/wearable/nativeabilityfwk/include/BackDragListener.h index a851b5523..4cca1dfbe 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/BackDragListener.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/BackDragListener.h @@ -9,16 +9,21 @@ #define BACK_DRAG_LISTENER_H #include #include "animator/animator.h" -#include "components/ui_view.h" +#include "components/ui_view_group.h" namespace OHOS { class BackDragListener : public UIView::OnDragListener { public: - static BackDragListener* GetInstance(); + BackDragListener() = default; + ~BackDragListener() override; bool OnDragStart(UIView& view, const DragEvent& event) override; bool OnDrag(UIView& view, const DragEvent& event) override; bool OnDragEnd(UIView& view, const DragEvent& event) override; - void ClearStatus(); + void ClearDragState(); + void SetParentView(UIViewGroup* view) + { + parentView_ = view; + } void SetCurrentAndTargetView(UIView *cur, UIView *tar) { curView_ = cur; @@ -39,74 +44,46 @@ public: { time_ = time; } + BackDragListener(const BackDragListener &) = delete; + BackDragListener &operator=(const BackDragListener &) = delete; + BackDragListener(BackDragListener &&) = delete; + BackDragListener &operator=(BackDragListener &&) = delete; private: - BackDragListener() {}; - ~BackDragListener() {}; class BackAnimatorCallback : public AnimatorCallback { public: + BackAnimatorCallback(BackDragListener* listener, uint16_t duration) + : dragListener_(listener), curtTime_(0), duration_(duration) {} void Callback(UIView* view) override; - void OnStop(UIView& view) override; - void SetDragParam(int16_t startX, int16_t endX, uint16_t dragTimes) - { - startValueX_ = startX; - endValueX_ = endX; - dragTimes_ = dragTimes; - } - - void SetAnimator(Animator *ani) - { - ani_ = ani; - } - - void SetGoToTarget(bool goToTarget) - { - goToTarget_ = goToTarget; - } - - void SetStopAction(const std::function &action) - { - stopAct_ = action; - } - - void SetTargetView(UIView *target) - { - targetView_ = target; - } - - void ResetStatus() + void OnStop(UIView& view) override { curtTime_ = 0; - dragTimes_ = 0; - startValueX_ = 0; - endValueX_ = 0; - ani_ = nullptr; - stopAct_ = nullptr; - targetView_ = nullptr; - goToTarget_ = false; } - private: - Animator *ani_ = nullptr; - UIView *targetView_ = nullptr; - uint16_t curtTime_ = 0; - uint16_t dragTimes_ = 0; - int16_t startValueX_ = 0; - int16_t endValueX_ = 0; - bool goToTarget_ = false; - std::function stopAct_; + private: + BackDragListener* dragListener_; + uint16_t curtTime_; + uint16_t duration_; }; + bool StartAnimator(); + void StopDragging(); Animator *backAnimator_ = nullptr; - BackAnimatorCallback backCallback_; + BackAnimatorCallback* backCallback_ = nullptr; UIView *targetView_ = nullptr; UIView *curView_ = nullptr; + UIViewGroup* parentView_ = nullptr; int16_t left_ = 0; int16_t right_ = 0; std::function targetAction_; std::function curAction_; const static uint16_t DEFAULT_TIME = 200; uint16_t time_ = DEFAULT_TIME; + bool goToTarget_ = false; + int16_t animStartX_ = 0; + int16_t animEndX_ = 0; + bool isDragging_ = false; + bool isTargetViewAdded_ = false; }; // BackDragListener } // namespace OHOS diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/NativeAbility.h b/code/sdk/application/wearable/nativeabilityfwk/include/NativeAbility.h index 2b1a26890..5ccd53d0f 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/NativeAbility.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/NativeAbility.h @@ -41,14 +41,9 @@ class NativeAbility : public Ability { public: static NativeAbility &GetInstance(void); - #ifdef JS_ENABLE void InstallAbility(void); #endif - void ResumeAbility(uint16_t targetSliceId, uint16_t priority); - void PauseAbility(); - void StopAbility(); - // SliteAbility, AMS控制的应用生命周期 void OnStart(const Want &want) OVERRIDE; void OnActive(const Want &want) OVERRIDE; @@ -57,7 +52,12 @@ public: void OnStop() OVERRIDE; int GetNativeAbilityState() const; + private: + // targetId consists of slice id and page id + void ResumeAbility(uint32_t targetId); + void PauseAbility(); + void StopAbility(); NativeAbility() {} void ResumeSliceWithJS(); ~NativeAbility() override {} diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/PageTransitionMgr.h b/code/sdk/application/wearable/nativeabilityfwk/include/PageTransitionMgr.h index 39e695435..5b58fecc8 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/PageTransitionMgr.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/PageTransitionMgr.h @@ -14,6 +14,7 @@ #include "graphic_mutex.h" #include "TransitionCallback.h" #include "TransitionType.h" +#include "gfx_utils/image_info.h" namespace OHOS { using TransitionAnimatorStopCallback = std::function; @@ -75,6 +76,15 @@ public: // this function is called by application when slice is on pause phase if it need to custom its slideback snapshot void SaveSlideBackSnapShotIfNecessary(UIView* view); UIImageView* GetTopSlideBackImage(); + /** + * @brief Check whether slide back is enabled currently, equivalent to: + * View::GetBackDragListener() + * Note: Don't use canSlideBack_ because it will be reset after transition + */ + bool CanSlideBack() + { + return (GetTopSlideBackImage() != nullptr); + } // remove top slice back image from rootview and delete it void ClearTopSlideBackImage(); void SaveCurrentSourceIfNecessary(UIView* view); @@ -105,6 +115,16 @@ public: return transitionCaller_ == TransitionCaller::BACK_TRANSITION; } + /** + * @brief Set current app's recent img source. Should be invoked in OnResume method. + */ + void SetRecentAppImg(uint32_t resId, std::string file); + + /** + * @brief Set min lasting period of an app so that it could be added to recent manager. + */ + void SetRecentMinPeriod(uint32_t minPeriod); + private: PageTransitionMgr() {}; ~PageTransitionMgr() {}; @@ -112,11 +132,17 @@ private: void SaveSlideBackSnapShotInner(UIView* view, bool custom); void SaveCurrentSnapShotInner(UIView* view); void ClearSlideBackHistory(); + bool SnapshotRecentSource(UIView* view); + void AddRecentAppIfNecessary(); + bool FillRecentSnapshot(bool& needToFreeSnapshot); Animator* animator_ = nullptr; PageTransAnimCallback* animatorCallback_ = nullptr; std::shared_ptr currentSlideBackSnapshot_ = nullptr; std::shared_ptr currentSnapshot_ = nullptr; std::shared_ptr targetSnapshot_ = nullptr; + ImageInfo recentSnapshot_ = {0}; + uint32_t recentAppResId_ = 0; + std::string recentAppFile_ = ""; std::shared_ptr slideBackHistroy_[MAX_SLIDE_BACK_NUM] = {nullptr}; uint8_t curSlideBackNum_ = 0; UIViewGroup* currentView_ = nullptr; @@ -137,6 +163,12 @@ private: GraphicMutex operationLock_; void ClearTransitionResource(); ImageInfo RectifySnapshot(ImageInfo& dstInfo); + uint32_t lastTransitionTime_ = 0; + uint32_t recentMinPeriod_ = 0; + bool recentMinPeriodSatisfied_ = true; + bool isSnapshotRecent_ = false; + uint16_t recentSliceId_ = 0; // invalid slice + uint32_t recentTargetId_ = 0; // invalid slice }; } // namespace OHOS -#endif // PAGE_TRANSITION_MGR_H +#endif // PAGE_TRANSITION_MGR_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/Presenter.h b/code/sdk/application/wearable/nativeabilityfwk/include/Presenter.h index 76276cc2e..b8cbc7a4c 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/Presenter.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/Presenter.h @@ -16,20 +16,13 @@ #ifndef APPFWK_PRESENTER_H #define APPFWK_PRESENTER_H -#include "components/root_view.h" -#include "KeyInputListener.h" -#include "dock/focus_manager.h" -#include "PageTransitionMgr.h" -#include "NativeAbility.h" -#include "BackDragListener.h" +#include "View.h" namespace OHOS { -template - -class Presenter { +class PresenterBase { public: - Presenter() : view_(nullptr), model_(nullptr) {} - virtual ~Presenter() {} + PresenterBase() : viewBase_(nullptr) {} + virtual ~PresenterBase() = default; /** * @brief Scheduled by slice when it is started and before transition animator starts if exsit @@ -42,39 +35,15 @@ public: * @brief Scheduled by slice when it will be visiable and after transition animator ends if exsit * * You can set custom input event listener, request focus, and start its own animator here. - * Please call Presenter::OnResume in your implemention */ - virtual void OnResume() - { - // make sure root container was added because it maybe removed during transition when current snap is false - if (view_->GetRootContainer()->GetParent() == nullptr) { - RootView::GetInstance()->Add(view_->GetRootContainer()); - } - // Reset the default key listener - RootView::GetInstance()->SetOnKeyActListener(KeyInputListener::GetInstance()); - UIView* backView = PageTransitionMgr::GetInstance().GetTopSlideBackImage(); - if (backView == nullptr) { - return; - } - BackDragListener::GetInstance()->ClearStatus(); - BackDragListener::GetInstance()->SetCurrentAndTargetView(view_->GetRootContainer(), backView); - BackDragListener::GetInstance()->SetDragToTargetAction([]() { NativeAbility::GetInstance().BackToPreSlice(); }); - view_->GetRootContainer()->SetOnDragListener(BackDragListener::GetInstance()); - } + virtual void OnResume() {} /** * @brief Scheduled by slice when another slice will be started and before slice transition animator starts if exsit * * You can clear input event listener, clear focus, and stop animator here. - * Please call Presenter::OnPause in your implemention if default key listener need to be cleared. */ - virtual void OnPause() - { - // Ensure that key listener is disabled during transition if exist - RootView::GetInstance()->ClearOnKeyActListener(); - view_->GetRootContainer()->SetOnDragListener(nullptr); - FocusManager::GetInstance()->ClearFocus(); - } + virtual void OnPause() {} /** * @brief Presenter lifecycle scheduled by slice when it will be invisible and another slice will be visible @@ -82,14 +51,39 @@ public: * You can destroy non-ui resources here */ virtual void OnStop() {} + + /** + * @brief This function will attach view to this presenter + * + * @param view view pointer defined by developer + */ + virtual void Attach(ViewBase* view) + { + viewBase_ = view; + } + + PresenterBase(const PresenterBase&) = delete; + PresenterBase& operator=(const PresenterBase&) = delete; + PresenterBase(PresenterBase&&) = delete; + PresenterBase& operator=(PresenterBase&&) = delete; +protected: + ViewBase* viewBase_; +}; + +template +class Presenter : public PresenterBase { +public: + Presenter() : model_(nullptr) {} + /** * @brief This function will attach view to this presenter * * @param view view pointer defined by developer */ - void Attach(V* view) + void Attach(ViewBase* view) override { - view_ = view; + PresenterBase::Attach(view); + view_ = dynamic_cast(viewBase_); } /** @@ -105,13 +99,6 @@ public: protected: V* view_; M* model_; - BackDragListener* backDragListener_ = nullptr; - -private: - Presenter(const Presenter&) = delete; - Presenter& operator=(const Presenter&) = delete; - Presenter(Presenter&&) = delete; - Presenter& operator=(Presenter&&) = delete; }; } #endif diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/RecentManager.h b/code/sdk/application/wearable/nativeabilityfwk/include/RecentManager.h new file mode 100644 index 000000000..76e9598db --- /dev/null +++ b/code/sdk/application/wearable/nativeabilityfwk/include/RecentManager.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) CompanyNameMagicTag. + * 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. + */ + +#ifndef RECENT_MANAGER_H +#define RECENT_MANAGER_H + +#include +#include +#include "gfx_utils/image_info.h" +#include "gfx_utils/list.h" +#include "graphic_mutex.h" + +namespace OHOS { +#define RECENT_APP_BUNDLE_NAME_MAX_LEN 127 + +typedef struct { + bool isNativeSlice; // true: native; false: js + union { + uint32_t targetId; + char bundleName[RECENT_APP_BUNDLE_NAME_MAX_LEN]; + }; + ImageInfo* snapshot; +} RecentAppInfo; + +class RecentManager { +public: + + /** + * @brief Get RecentManager* instance. + */ + static RecentManager* GetInstance(); + + /** + * @brief Set max recent app size. Once current size > max, the oldest will be removed. + * Default value is 0, and it will not record any recent app. + */ + void SetMaxSize(uint32_t max); + + /** + * @brief Get max recent app size. + */ + uint32_t GetMaxSize(); + + /** + * @brief Get current recent app size. + */ + uint32_t GetCurrentSize(); + + /** + * @brief Add a native app to recent manager with its snapshot to be cached. + */ + void AddRecentApp(uint32_t targetId, const ImageInfo* snapshot); + + /** + * @brief Add a js app to recent manager with its snapshot to be cached. + */ + void AddRecentApp(const char* bundleName, const ImageInfo* snapshot); + + /** + * @brief Remove a native app with given targetId. + */ + bool RemoveRecentApp(uint32_t targetId, bool deleteFile = true); + + /** + * @brief Remove a js app with given bundleName. + */ + bool RemoveRecentApp(const char* bundleName, bool deleteFile = true); + + /** + * @brief Remove all recent apps. + */ + void RemoveAllRecentApps(); + + /** + * @brief Get a list of RecentAppInfo. + */ + const List& GetRecentApps(); + + /** + * @brief Set scale ratio. When an app is added, its snapshot could be scaled and cached. Default value is 0.5f. + */ + void SetScaleRatio(float ratio); + + /** + * @brief Get scale ratio. + */ + float GetScaleRatio(); + + /** + * @brief Add a sliceId to black list so that it will not be saved as a recent app. + */ + void AddToBlackList(uint32_t sliceId); + + /** + * @brief Remove a sliceId from black list so that it can be saved as a recent app. + */ + void RemoveFromBlackList(uint32_t sliceId); + + /** + * @brief Clear black list. + */ + void ClearBlackList(); + + /** + * @brief Return whether the sliceId is on black list. + */ + bool IsOnBlackList(uint32_t sliceId); + + /** + * @brief Return whether it is updated. + */ + bool IsUpdateCompleted(); + + /** + * @brief Set dir path to save recent snapshots. + */ + void SetDirPath(std::string path); + + /** + * @brief Return dir path to save recent snapshots. + */ + std::string GetDirPath(); + + /** + * @brief Return whether it is enabled. It is enabled when max size is a valid value and dir path is set. + */ + bool IsEnabled(); + + /** + * @brief Used internally. + */ + void PushRecentApp(RecentAppInfo* info); + + /** + * @brief Used internally. + */ + void RemoveOldest(); + + /** + * @brief Used internally. + */ + void DecLoadingCnt(); + + /** + * @brief Used internally. + */ + uint32_t GetLoadingCnt(); + +private: + RecentManager(); + virtual ~RecentManager(); + + void AddRecentAppWithSourceInfo(RecentAppInfo* appInfo, const ImageInfo* snapshot); + void AddRecentAppInner(RecentAppInfo* appInfo, const ImageInfo* snapshot); + void RemoveRecentAppNode(ListNode* node, bool deleteFile); + bool ScaleSnapshot(const ImageInfo* src, ImageInfo* dst); + ListNode* FindRecentAppInfo(List& list, + bool isNativeSlice, uint32_t sliceId, const char* bundleName); + void AddPersistingTask(RecentAppInfo* info); + static void AsyncPersisterRunnable(void* args); + static void FreeRecentAppInfo(void* data); + void AsyncFreeRecentAppInfo(RecentAppInfo* info); + void ProcessPersistingTasks(); + void ProcessTask(RecentAppInfo* info); + static void LoadRecentApp(void* data); + List recentApps_; + List persistingTasks_; + List blackList_; + static GraphicMutex recentAppsMutex_; + static GraphicMutex persistingTaskMutex_; + static GraphicCond newPersistingTaskCond_; + static GraphicCond persistingTaskDoneCond_; + uint32_t maxSize_ = 0; + float scaleRatio_ = 0.5f; + std::string dirPath_; + uint32_t loadingCnt_ = 0; +}; +} // namespace OHOS + +#endif // RECENT_MANAGER_H diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/Slice.h b/code/sdk/application/wearable/nativeabilityfwk/include/Slice.h index 9e87062a6..047cc6085 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/Slice.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/Slice.h @@ -18,10 +18,12 @@ #include "components/ui_view_group.h" namespace OHOS { +extern const uint16_t SLICE_MASK; +extern const uint32_t PAGE_OFFSET; class Slice { public: - Slice() {} - virtual ~Slice() {} + Slice() = default; + virtual ~Slice() = default; /** * @brief Called when the Slice is started and before transition animator starts if exits. * @@ -54,9 +56,10 @@ public: virtual void OnStop() = 0; virtual UIViewGroup* GetSliceContainer() = 0; -private: - Slice(const Slice &); - Slice &operator=(const Slice &); + Slice(const Slice &) = delete; + Slice &operator=(const Slice &) = delete; + Slice(Slice &&) = delete; + Slice &operator=(Slice &&) = delete; }; } // namespace OHOS diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/SlicePage.h b/code/sdk/application/wearable/nativeabilityfwk/include/SlicePage.h new file mode 100644 index 000000000..127f32941 --- /dev/null +++ b/code/sdk/application/wearable/nativeabilityfwk/include/SlicePage.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: Slice Page + * Author: Hisi Graphic Team + * Create: 2025-4 + */ +#ifndef SLICE_PAGE_H +#define SLICE_PAGE_H +#include "components/ui_view_group.h" +#include "Presenter.h" + +namespace OHOS { +class SlicePageBase { +public: + SlicePageBase() : pageContainer_(nullptr), backDragListener_(nullptr) {} + + virtual ~SlicePageBase() = default; + + virtual void OnStart(void* data) = 0; + + virtual void OnResume() {} + + virtual void OnPause() {} + + virtual void OnStop() {} + + UIViewGroup* GetSlicePageContainer() + { + return pageContainer_; + } + + BackDragListener* GetBackDragListener() + { + return backDragListener_; + } + + void AddViewToPageContainer(UIView* view); + + virtual void AttachPresenter(PresenterBase* p) = 0; + + SlicePageBase(const SlicePageBase&) = delete; + SlicePageBase& operator=(const SlicePageBase&) = delete; + SlicePageBase(SlicePageBase&&) = delete; + SlicePageBase& operator=(SlicePageBase&&) = delete; + uint16_t pageId_; + +private: + friend class SlicePageManager; + void SetupView(bool canBack); + void TearDownView(); + UIViewGroup* pageContainer_; + BackDragListener* backDragListener_; +}; + +template +class SlicePage : public SlicePageBase { +public: + void AttachPresenter(PresenterBase* p) override + { + presenter_ = dynamic_cast(p); + } +protected: + P* presenter_ = nullptr; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/SlicePageFactory.h b/code/sdk/application/wearable/nativeabilityfwk/include/SlicePageFactory.h new file mode 100644 index 000000000..49dd1c7b0 --- /dev/null +++ b/code/sdk/application/wearable/nativeabilityfwk/include/SlicePageFactory.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: SlicePageFactory + * Author: Hisi Graphic Team + * Create: 2025-4 + */ +#ifndef SLICE_PAGE_FACTORY_H +#define SLICE_PAGE_FACTORY_H +#include +#include "SlicePage.h" + +namespace OHOS { +class SlicePageProxyInterface; +class SlicePageFactory : public HeapBase { +public: + static SlicePageFactory& GetInstance() + { + static SlicePageFactory instance; + return instance; + } + + bool IsSlicePageExist(uint16_t sliceId, uint16_t pageId); + + SlicePageBase* CreateSlicePage(uint16_t sliceId, uint16_t pageId); + + SlicePageBase* GetDefaultSlicePage(uint16_t sliceId, uint16_t& defaultPageId); + + void RegisterPage(uint16_t sliceId, uint16_t pageId, SlicePageProxyInterface* proxy, bool isMainPage); + +private: + SlicePageFactory() {}; + ~SlicePageFactory() {}; + SlicePageFactory(const SlicePageFactory &) = delete; + SlicePageFactory &operator=(const SlicePageFactory &) = delete; + std::unordered_map pageProxyMap_; + std::unordered_map mainPageMap_; + std::unordered_map mainPageIdMap_; +}; + +class SlicePageProxyInterface : public HeapBase { +public: + virtual SlicePageBase* CreateSlicePage(uint16_t pageId) = 0; +}; + +class SlicePageRegister : public HeapBase { +public: + SlicePageRegister(uint16_t sliceId, uint16_t pageId, SlicePageProxyInterface* proxy, bool isMainPage); +}; + +template +class SlicePageProxy : public SlicePageProxyInterface { +public: + SlicePageBase* CreateSlicePage(uint16_t pageId) override + { + V* v = new V(); + SlicePageBase* page = dynamic_cast(v); + if (page == nullptr) { + delete v; + } else { + page->pageId_ = pageId; + } + return page; + } +}; +} + +#define REGIST_SLICE_PAGE(sliceId, pageId, V, isMainPage) \ + const static OHOS::SlicePageRegister (STATIC_VAR)(sliceId, pageId, new OHOS::SlicePageProxy(), isMainPage) +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/SlicePageManager.h b/code/sdk/application/wearable/nativeabilityfwk/include/SlicePageManager.h new file mode 100644 index 000000000..c69ef48f4 --- /dev/null +++ b/code/sdk/application/wearable/nativeabilityfwk/include/SlicePageManager.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: SlicePageManager + * Author: Hisi Graphic Team + * Create: 2025-4 + */ +#ifndef SLICE_PAGE_MANAGER_H +#define SLICE_PAGE_MANAGER_H +#include "animator/animator.h" +#include "Presenter.h" +#include "Slice.h" +#include "SlicePage.h" +#include "gfx_utils/vector.h" +#include "TransitionType.h" +#include "TransitionCallback.h" + +namespace OHOS { +class SlicePageManager; +class SlicePageSwitchCallback : public AnimatorCallback { +public: + SlicePageSwitchCallback(SlicePageManager* transMgr) + : isStarted_(false), startTime_(0), pageTransMgr_(transMgr) {} + void Callback(UIView* view) override; + void OnStop(UIView& view) override; + +private: + bool isStarted_; + uint32_t startTime_; + SlicePageManager* pageTransMgr_; +}; + +class SlicePageManager : public HeapBase { +public: + SlicePageManager(uint32_t targetId) + : isPageBeingSwitched_(false), sliceId_(static_cast(targetId & SLICE_MASK)), + targetPageId_(static_cast(targetId >> PAGE_OFFSET)), + curPage_(nullptr), nextPage_(nullptr), pagesInBackQueue_(4), // 4, default queue size + presenter_(nullptr), view_{nullptr}, transitionCallback_(nullptr), canBack_(false) {} + + ~SlicePageManager(); + + // Get current page which is display on the screen + SlicePageBase* GetCurSlicePage() + { + return curPage_; + } + + // Get specified page in the back queue + SlicePageBase* GetSlicePageInBackQueue(uint16_t sliceId); + + // Get previous page before current page in the back queue + SlicePageBase* GetLastPageInBackQueue() + { + return pagesInBackQueue_.Back(); + } + + void ClearBackQueue(); + + bool ChangeSlicePage(uint16_t pageId, void* data, TransitionType type, bool canBack); + + bool IsAnimatorRunning() + { + return ((animator_ != nullptr) && (animator_->GetState() != Animator::STOP)); + } + + void BackToPrevSlicePage(); + + SlicePageManager(const SlicePageManager&) = delete; + SlicePageManager& operator=(const SlicePageManager&) = delete; + SlicePageManager(SlicePageManager&&) = delete; + SlicePageManager& operator=(SlicePageManager&&) = delete; + +private: + friend class AbilitySlice; + friend class SlicePageSwitchCallback; + void AttachVP(PresenterBase* p, ViewBase* v) + { + presenter_ = p; + view_ = v; + } + void StartSlicePage(void* data = nullptr); + void ResumeSlicePage(); + void PauseSlicePage(); + void StopSlicePage(bool clearBackQueue = true); + void StartSwitchAnimator(); + void StopSwitchAnimator(); + + Animator* animator_ = nullptr; + SlicePageSwitchCallback* switchCallback_ = nullptr; + bool isPageBeingSwitched_; + uint16_t sliceId_; + uint16_t targetPageId_; + SlicePageBase* curPage_; + SlicePageBase* nextPage_; + Graphic::Vector pagesInBackQueue_; + PresenterBase* presenter_; + ViewBase* view_; + TransitionCallback* transitionCallback_; + bool canBack_; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/SliceProxy.h b/code/sdk/application/wearable/nativeabilityfwk/include/SliceProxy.h index 7d1cc3b32..ccbf2be7e 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/SliceProxy.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/SliceProxy.h @@ -20,13 +20,13 @@ namespace OHOS { class SliceProxy { public: - SliceProxy() {} - ~SliceProxy() {} - virtual Slice* CreateSlice() = 0; - -private: - SliceProxy(const SliceProxy &); - SliceProxy &operator=(const SliceProxy &); + virtual Slice* CreateSlice(uint32_t targetId) = 0; + SliceProxy() = default; + virtual ~SliceProxy() = default; + SliceProxy(const SliceProxy&) = delete; + SliceProxy& operator=(const SliceProxy&) = delete; + SliceProxy(SliceProxy&&) = delete; + SliceProxy& operator=(SliceProxy&&) = delete; }; } // namespace OHOS #endif // SLICE_PROXY_H diff --git a/code/sdk/application/wearable/nativeabilityfwk/include/View.h b/code/sdk/application/wearable/nativeabilityfwk/include/View.h index 1243e46b1..207926648 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/include/View.h +++ b/code/sdk/application/wearable/nativeabilityfwk/include/View.h @@ -17,26 +17,35 @@ #define APPFWK_VIEW_H #include "components/ui_view_group.h" -#include "components/root_view.h" -#include "common/screen.h" +#include "BackDragListener.h" namespace OHOS { -template -class View { +class PresenterBase; +class ViewBase { public: - View() : presenter_(nullptr), rootContainer_(nullptr) {} - virtual ~View() {} + ViewBase() : rootContainer_(nullptr), backDragListener_(nullptr) {} + virtual ~ViewBase() = default; /** - * @brief get container view - * - * @returns container + * @brief Get container view + * @returns rootContainer_ */ - UIViewGroup* GetRootContainer() const + UIViewGroup* GetRootContainer() { return rootContainer_; } + /** + * @brief Get back drag listener + * This method can be used in AbilitySlice.cpp, and also can be used in XXXView.cpp + * If used in XXXView.cpp, you can use it to check whether default OnDragListener is configured. + * @returns backDragListener_ + */ + BackDragListener* GetBackDragListener() + { + return backDragListener_; + } + /** * @brief Scheduled by slice after funtion SetupView and before transition animator starts if exits. * @@ -65,76 +74,50 @@ public: virtual void OnStop() {} /** - * @brief Scheduled by slice to create root container add it to root view + * @brief draw container * - * This method is called by system class AbilitySlice, you should not override it. */ - void SetupView() - { - if (rootContainer_ != nullptr) { - printf("OnStart Error: rootContainer_ already exist"); - } else { - rootContainer_ = new UIViewGroup(); - } - rootContainer_->SetPosition(0, 0, RootView::GetInstance()->GetWidth(), RootView::GetInstance()->GetHeight()); - RootView::GetInstance()->Add(rootContainer_); - } + void Draw(); /** - * @brief Scheduled by slice to remove and delete root container from root view + * @brief This function will attach presenter to this view * - * This method is called by by system class AbilitySlice, you should not override it. + * @param presenter presenter pointer defined by developer */ - void TearDownView() - { - // Todo: Only remove root container, and application should remove other children in its own implemention - RootView::GetInstance()->Remove(rootContainer_); - if (rootContainer_ != nullptr) { - rootContainer_->RemoveAll(); - delete rootContainer_; - rootContainer_ = nullptr; - } else { - printf("TearDownView Error: rootContainer_ was not initialized !!!"); - } - } + virtual void Attach(PresenterBase* presenter) = 0; - /** - * @brief draw container - * - */ - void Draw() - { - RootView::GetInstance()->Invalidate(); - } + void AddViewToRootContainer(UIView* view); + + ViewBase(const ViewBase&) = delete; + ViewBase& operator=(const ViewBase&) = delete; + ViewBase(ViewBase&&) = delete; + ViewBase& operator=(ViewBase&&) = delete; + +private: + friend class AbilitySlice; + void SetupView(); + void TearDownView(); + UIViewGroup* rootContainer_; + BackDragListener* backDragListener_; +}; + +template +class View : public ViewBase { +public: + View() : presenter_(nullptr) {} /** * @brief This function will attach presenter to this view * * @param presenter presenter pointer defined by developer */ - void Attach(P* presenter) - { - presenter_ = presenter; - } - - void AddViewToRootContainer(UIView* view) + void Attach(PresenterBase* presenter) override { - if (rootContainer_ == nullptr) { - printf("AddViewToContainer Error: rootContainer_ is nullptr"); - return; - } - rootContainer_->Add(view); + presenter_ = dynamic_cast(presenter); } protected: P* presenter_; - -private: - UIViewGroup* rootContainer_ = nullptr; - View(const View&) = delete; - View& operator=(const View&) = delete; - View(View&&) = delete; - View& operator=(View&&) = delete; }; } #endif diff --git a/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp b/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp index 8be4e9709..82e0d033d 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp +++ b/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp @@ -24,14 +24,9 @@ #include "common/graphic_utils.h" #include "PageTransitionMgr.h" #include "gfx_utils/list.h" +#include "AbilitySlice.h" namespace OHOS { -const uint8_t MAX_SLICE_ID_LENGTH = 16; -struct SliceOperation { - uint16_t targetSliceId; - TransitionType type; -}; - void Ability::AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability AddSliceProxy sliceId = %d", sliceId); @@ -47,49 +42,39 @@ void Ability::AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy) allSlicesProxy_.PushBack(proxyPair); } -void Ability::StartSlice(const uint16_t sliceId, const uint16_t priority) +void Ability::StartSlice(uint32_t targetId) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability StartSlice %d", sliceId); - if (sliceId <= gSliceInvalid) { + if (targetId <= gSliceInvalid) { return; } - + uint16_t sliceId = static_cast(targetId & SLICE_MASK); Ability::ProxyStruct* proxyStruct = Find(sliceId); if (proxyStruct == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "no slice %d was found", sliceId); return; } InputDeviceManager::GetInstance()->ClearInputDeviceState(); - Slice* nextSlice = proxyStruct->proxy->CreateSlice(); - if (nextSlice == nullptr) { + + Slice* newSlice = proxyStruct->proxy->CreateSlice(targetId); + if (newSlice == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "create slice %u failed", sliceId); return; } - WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::StartSlice Size = %d", allSlices_.Size()); - // 记录最多gMaxHistorySlices个页面id - if (PageTransitionMgr::GetInstance().IsBackTransitionRunning()) { - PageTransitionMgr::GetInstance().ClearTopSlideBackImage(); - } - if (sliceId == defaultSliceId_) { - allSlices_.Clear(); // clear slice history when return to home - allSlices_.PushBack(defaultSliceId_); + if (sliceId == defaultTargetId_) { + allSlices_.Clear(); // clear slice history when return to main slice + allSlices_.PushBack(defaultTargetId_); } else if (PageTransitionMgr::GetInstance().IsBackTransitionRunning()) { allSlices_.PopBack(); } else { - allSlices_.PushBack(sliceId); - } - if (curSlice_.slice != nullptr) { - prevSlice_.sliceId = curSlice_.sliceId; - prevSlice_.slice = curSlice_.slice; - } else { - prevSlice_.sliceId = gSliceInvalid; - prevSlice_.slice = nullptr; + allSlices_.PushBack(targetId); } - curSlice_.sliceId = sliceId; - curSlice_.slice = nextSlice; - curSlicePriority_ = priority; - - nextSlice->OnStart(); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability StartSlice %d page %d size:%d", sliceId, + targetId >> PAGE_OFFSET, allSlices_.Size()); + nextSlice_.sliceId = sliceId; + nextSlice_.slice = newSlice; + newSlice->OnStart(); } Ability::ProxyStruct* Ability::Find(const uint16_t sliceId) @@ -110,46 +95,102 @@ Ability::ProxyStruct* Ability::Find(const uint16_t sliceId) return nullptr; } -void Ability::ChangeSlice(const uint16_t targetSliceId, TransitionType type, - const uint16_t priority, bool enableSlideBack) +SlicePageManager* Ability::GetCurSlicePageManager() +{ + if (PageTransitionMgr::GetInstance().IsTransitionRunning()) + { + WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "No valid SlicePageManager during slice switching"); + return nullptr; + } + AbilitySlice* slice = dynamic_cast(curSlice_.slice); + if (slice == nullptr) { + WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "No valid SlicePageManager when js is running"); + return nullptr; + } + return slice->GetSlicePageManger(); +} + +void Ability::UpdateCurSlicePageId(uint16_t pageId) +{ + if (allSlices_.IsEmpty()) { + return; + } + uint32_t sliceId = allSlices_[allSlices_.Size() - 1] & SLICE_MASK; + allSlices_[allSlices_.Size() - 1] = sliceId | (static_cast(pageId) << PAGE_OFFSET); +} + +bool Ability::SwitchPageInSlice(uint16_t pageId, void* data, TransitionType type, bool canBack) +{ + if (pageId == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "page id should be valid but no zero"); + return false; + } + if (PageTransitionMgr::GetInstance().IsTransitionRunning()) { + WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "page can't be switched during transition"); + return false; + } + AbilitySlice* slice = dynamic_cast(curSlice_.slice); + if (slice == nullptr) { + WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "page can't be switched because current slice is nullptr"); + return false; + } + return slice->ChangeSlicePage(pageId, data, type, canBack); +} + +void Ability::SwitchSlice(uint16_t sliceId, uint16_t pageId, TransitionType type, bool enableSlideBack) { + if (Find(sliceId) == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "slice %d is not registered", sliceId); + return; + } #ifdef JS_ENABLE ElementName *elementName = OHOS::AbilityMsClient::GetInstance().GetTopAbility(); if (elementName != nullptr && strcmp(elementName->bundleName, "com.huawei.launcher") != 0) { OHOS::AbilityMsClient::GetInstance().ForceStop(elementName->bundleName, type); - targetSliceIdFromJS_ = targetSliceId; + targetIdFromJS_ = sliceId | (static_cast(pageId) << PAGE_OFFSET); FreeElement(elementName); return; } FreeElement(elementName); #endif TransitionTarget target; - target.sliceInfo = targetSliceId | (priority << 16); + target.sliceInfo = sliceId | (static_cast(pageId) << PAGE_OFFSET); bool runImmed = PageTransitionMgr::GetInstance().BeginTransition(TransitionCaller::CHANGE_SLICE, target, type, enableSlideBack); if (!runImmed) { - printf("pending change slice id:%d type:%d enableSlideBack:%d\n", targetSliceId, type, enableSlideBack); + printf("pending change slice id:%d type:%d enableSlideBack:%d\n", target.sliceInfo, type, enableSlideBack); return; } - GraphicService::GetInstance()->PostGraphicEvent(std::bind(&Ability::PostChangeSlice, this, targetSliceId, - type, priority, enableSlideBack)); + GraphicService::GetInstance()->PostGraphicEvent(std::bind(&Ability::PostChangeSlice, this, target.sliceInfo, type)); } -void Ability::PostChangeSlice(const uint16_t targetSliceId, TransitionType type, +void Ability::ChangeSlice(uint16_t sliceId, TransitionType type, const uint16_t priority, bool enableSlideBack) +{ + (void)(priority); + SwitchSlice(sliceId, gPageInvalid, type, enableSlideBack); +} + +void Ability::PostChangeSlice(uint32_t targetId, TransitionType type) { PauseSlice(); + if (allSlices_.Size() > 0 && allSlices_[allSlices_.Size() - 1] == VIEW_AOD) { + allSlices_.PopBack(); + if (allSlices_.Size() > 0 && (allSlices_[allSlices_.Size() - 1] & SLICE_MASK) == (targetId & SLICE_MASK)) { + allSlices_.PopBack(); + } + } PageTransitionMgr::GetInstance().SaveCurrentSourceIfNecessary(curSlice_.slice->GetSliceContainer()); if (!PageTransitionMgr::GetInstance().IsTransAnimNeeded() || PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) { StopSlice(); } - StartSlice(targetSliceId, priority); + StartSlice(targetId); if (!PageTransitionMgr::GetInstance().IsTransAnimNeeded()) { ResumeSliceWithoutJS(); } else { - PageTransitionMgr::GetInstance().SaveTargetSource(curSlice_.slice->GetSliceContainer()); + PageTransitionMgr::GetInstance().SaveTargetSource(nextSlice_.slice->GetSliceContainer()); PageTransitionMgr::GetInstance().StartTransAnim(std::bind(&Ability::ResumeSliceWithoutJS, this)); } } @@ -158,7 +199,7 @@ void Ability::ResumeSliceWithoutJS() { if (PageTransitionMgr::GetInstance().IsTransAnimNeeded() && !PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) { - StopPrevSlice(); + StopSlice(); } ResumeSlice(); PageTransitionMgr::GetInstance().EndTransition(true); @@ -166,6 +207,17 @@ void Ability::ResumeSliceWithoutJS() void Ability::ResumeSlice() { + // if new slice was created, set is as current slice and resume it + if (nextSlice_.slice != nullptr) { + if (curSlice_.slice != nullptr) { + GRAPHIC_LOGE("Both slice %d and %d is valid during resume", curSlice_.sliceId, nextSlice_.sliceId); + } + curSlice_.sliceId = nextSlice_.sliceId; + curSlice_.slice = nextSlice_.slice; + nextSlice_.sliceId = gSliceInvalid; + nextSlice_.slice = nullptr; + } + if (curSlice_.slice != nullptr) { WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability ResumeSlice %d", curSlice_.sliceId); curSlice_.slice->OnResume(); @@ -177,8 +229,8 @@ void Ability::ResumeSlice() void Ability::PauseSlice() { if (curSlice_.slice != nullptr) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability PauseSlice %d", curSlice_.sliceId); InputDeviceManager::GetInstance()->ClearInputDeviceState(); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability PauseSlice %d", curSlice_.sliceId); curSlice_.slice->OnPause(); } else { GRAPHIC_LOGE("No valid slice to pause"); @@ -199,21 +251,6 @@ void Ability::StopSlice() } } -void Ability::StopPrevSlice() -{ - if (prevSlice_.slice != nullptr) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability StopPrevSlice %d", prevSlice_.sliceId); - prevSlice_.slice->OnStop(); - if (prevSlice_.slice != nullptr) { - prevSlice_.sliceId = gSliceInvalid; - delete prevSlice_.slice; - prevSlice_.slice = nullptr; - } - } else { - GRAPHIC_LOGE("No valid prev slice to stop"); - } -} - void Ability::StopSliceTransition() { PageTransitionMgr::GetInstance().SyncStopAnimator(); @@ -221,15 +258,17 @@ void Ability::StopSliceTransition() void Ability::BackToPreSlice() { - uint16_t targetSliceId = GetPreSliceId(); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability BackToPreSlice %d", targetSliceId); - if (targetSliceId == gSliceInvalid) { + uint32_t targetId = GetPreTargetId(); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability BackToPreSlice %d", targetId); + if (targetId == gSliceInvalid) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "previous slice is invalid"); return; } TransitionTarget target; - target.sliceInfo = targetSliceId | (gSliceDefaultPriority << 16); + target.sliceInfo = targetId; + uint16_t sliceId = static_cast(targetId & SLICE_MASK); + uint16_t pageId = static_cast(targetId >> PAGE_OFFSET); PageTransitionMgr::GetInstance().BeginBackTransition(TransitionCaller::CHANGE_SLICE, target); - ChangeSlice(targetSliceId); + SwitchSlice(sliceId, pageId); } } // namespace OHOS diff --git a/code/sdk/application/wearable/nativeabilityfwk/src/AbilitySlice.cpp b/code/sdk/application/wearable/nativeabilityfwk/src/AbilitySlice.cpp new file mode 100644 index 000000000..37810c795 --- /dev/null +++ b/code/sdk/application/wearable/nativeabilityfwk/src/AbilitySlice.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: AbilitySlice + * Author: Hisi Graphic Team + * Create: 2025-4 + */ + +#include "AbilitySlice.h" +#include "components/root_view.h" +#include "dock/focus_manager.h" +#include "wearable_log.h" +#include "PageTransitionMgr.h" +#include "NativeAbility.h" +#include "View.h" +#include "Presenter.h" +#include "key/KeyInputListener.h" + +namespace OHOS { +const uint16_t SLICE_MASK = 0xFFFF; +const uint32_t PAGE_OFFSET = 16; + +void AbilitySlice::OnStart() +{ + if ((presenter_ == nullptr) || (view_ == nullptr)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Presenter or View was nullptr for slice %s", sliceId_); + return; + } + + // if back to current slice, delete slide back ImageView of current slice firstly + if (PageTransitionMgr::GetInstance().IsBackTransitionRunning()) { + PageTransitionMgr::GetInstance().ClearTopSlideBackImage(); + } + presenter_->Attach(view_); + view_->Attach(presenter_); + slicePageMgr_.AttachVP(presenter_, view_); + + view_->SetupView(); + view_->OnStart(); + slicePageMgr_.StartSlicePage(); + presenter_->OnStart(); + state_ = SliceState::START; +} + +void AbilitySlice::OnResume() +{ + if ((state_ != SliceState::START) && (state_ != SliceState::PAUSE)) { // avoid repeated resume + return; + } + if ((presenter_ == nullptr) || (view_ == nullptr)) { + return; + } + + if (view_->GetRootContainer()->GetParent() == nullptr) { + RootView::GetInstance()->Add(view_->GetRootContainer()); + } + // Reset the default key listener + RootView::GetInstance()->SetOnKeyActListener(KeyInputListener::GetInstance()); + NativeAbility::GetInstance().SetCurSlicePriority(gSliceDefaultPriority); + + UIView* backView = PageTransitionMgr::GetInstance().GetTopSlideBackImage(); + BackDragListener* backDragListener = view_->GetBackDragListener(); + if ((backView != nullptr) && ((backDragListener != nullptr))) { + backDragListener->SetCurrentAndTargetView(view_->GetRootContainer(), backView); + backDragListener->SetParentView(RootView::GetInstance()); + backDragListener->SetDragToTargetAction([]() { NativeAbility::GetInstance().BackToPreSlice(); }); + view_->GetRootContainer()->SetTouchable(true); + view_->GetRootContainer()->SetDraggable(true); + view_->GetRootContainer()->SetOnDragListener(backDragListener); + } + + slicePageMgr_.ResumeSlicePage(); + presenter_->OnResume(); + view_->Draw(); + state_ = SliceState::RESUME; +} + +void AbilitySlice::OnPause() +{ + if (state_ != SliceState::RESUME) { // avoid repeated pause + return; + } + if ((presenter_ == nullptr) || (view_ == nullptr)) { + return; + } + + if (slicePageMgr_.IsAnimatorRunning()) { + slicePageMgr_.StopSwitchAnimator(); + } + slicePageMgr_.PauseSlicePage(); + RootView::GetInstance()->ClearOnKeyActListener(); + BackDragListener* backDragListener = view_->GetBackDragListener(); + if (backDragListener != nullptr) { + backDragListener->ClearDragState(); + } + view_->GetRootContainer()->SetOnDragListener(nullptr); + + FocusManager::GetInstance()->ClearFocus(); + presenter_->OnPause(); + state_ = SliceState::PAUSE; +} + +void AbilitySlice::OnStop() +{ + if ((presenter_ == nullptr) || (view_ == nullptr)) { + return; + } + + slicePageMgr_.StopSlicePage(); + view_->TearDownView(); + view_->OnStop(); + delete view_; + view_ = nullptr; + + presenter_->OnStop(); + delete presenter_; + presenter_ = nullptr; + + state_ = SliceState::STOP; +} + +UIViewGroup* AbilitySlice::GetSliceContainer() +{ + if (view_ != nullptr) { + return view_->GetRootContainer(); + } else { + return nullptr; + } +} + +bool AbilitySlice::ChangeSlicePage(uint16_t pageId, void* data, TransitionType type, bool canBack) +{ + return slicePageMgr_.ChangeSlicePage(pageId, data, type, canBack); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeabilityfwk/src/NativeAbility.cpp b/code/sdk/application/wearable/nativeabilityfwk/src/NativeAbility.cpp index 12a9cb143..1b5ae820c 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/src/NativeAbility.cpp +++ b/code/sdk/application/wearable/nativeabilityfwk/src/NativeAbility.cpp @@ -78,37 +78,40 @@ void NativeAbility::ResumeSliceWithJS() #endif } -void NativeAbility::ResumeAbility(uint16_t targetSliceId, uint16_t priority) +void NativeAbility::ResumeAbility(uint32_t targetId) { GraphicService::GetInstance()->SetNativeUIRunning(true); NotificationManager::GetInstance()->SetNativeUIRunning(true); - if (curSlice_.slice == nullptr) { + if ((targetId & SLICE_MASK) != VIEW_AOD) { allSlices_.Clear(); // clear slice history when jump from js to native - StartSlice(targetSliceId, priority); } else { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility ResumeAbility with slice %d", curSlice_.sliceId); + allSlices_.PopBack(); // clear invalid slice id + } + StartSlice(targetId); + if (nextSlice_.slice == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility ResumeAbility %d failed", targetId); + return; } - if (!PageTransitionMgr::GetInstance().IsTransAnimNeeded()) { ResumeSliceWithJS(); } else { - PageTransitionMgr::GetInstance().SaveTargetSource(curSlice_.slice->GetSliceContainer()); + PageTransitionMgr::GetInstance().SaveTargetSource(nextSlice_.slice->GetSliceContainer()); PageTransitionMgr::GetInstance().StartTransAnim(std::bind(&NativeAbility::ResumeSliceWithJS, this)); } } void NativeAbility::OnActive(const Want &want) { - uint16_t targetSliceId = gSliceInvalid; - if (targetSliceIdFromJS_ != gSliceInvalid) { - targetSliceId = targetSliceIdFromJS_; - targetSliceIdFromJS_ = gSliceInvalid; - } else if (GetPreSliceId() != gSliceInvalid) { - targetSliceId = GetPreSliceId(); - } else if (GetCurSliceId() != gSliceInvalid) { - targetSliceId = GetCurSliceId(); + uint32_t targetId = gSliceInvalid; + if (targetIdFromJS_ != gSliceInvalid) { + targetId = targetIdFromJS_; + targetIdFromJS_ = gSliceInvalid; + } else if (GetPreTargetId() != gSliceInvalid) { + targetId = GetPreTargetId(); // for forcestop or ternimate js + } else if (GetCurTargetId() != gSliceInvalid) { + targetId = GetCurTargetId(); } - targetSliceId = (targetSliceId == gSliceInvalid) ? defaultSliceId_ : targetSliceId; + targetId = (targetId == gSliceInvalid) ? defaultTargetId_ : targetId; #ifdef JS_ENABLE if ((GetState() == STATE_ACTIVE)) { @@ -117,7 +120,7 @@ void NativeAbility::OnActive(const Want &want) #endif WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility OnActive"); GraphicService::GetInstance()->PostGraphicEvent(std::bind(&NativeAbility::ResumeAbility, this, - targetSliceId, gSliceDefaultPriority)); + targetId)); } void NativeAbility::PauseAbility() @@ -153,6 +156,9 @@ void NativeAbility::StopAbility() !PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) { StopSlice(); } + if (allSlices_.Size() > 0 && allSlices_[allSlices_.Size() - 1] == VIEW_AOD) { + allSlices_.PopBack(); + } allSlices_.PushBack(gSliceInvalid); nativeAbilityState_ = STATE_UNINITIALIZED; #ifdef JS_ENABLE diff --git a/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToHexagonsTransition.cpp b/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToHexagonsTransition.cpp index afe3c799a..da9c42185 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToHexagonsTransition.cpp +++ b/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToHexagonsTransition.cpp @@ -9,7 +9,7 @@ #include "TransitionManager.h" #include "NativeAbility.h" #include "components/root_view.h" -#include "AppItemView.h" +#include "applist/AppItemView.h" #include "hal_tick.h" #include "wearable_log.h" #ifdef JS_ENABLE diff --git a/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToWaterfallTransition.cpp b/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToWaterfallTransition.cpp index 18331afd7..a5bb73077 100644 --- a/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToWaterfallTransition.cpp +++ b/code/sdk/application/wearable/nativeabilityfwk/src/transition/BackToWaterfallTransition.cpp @@ -9,7 +9,7 @@ #include "TransitionManager.h" #include "NativeAbility.h" #include "components/root_view.h" -#include "AppItemView.h" +#include "applist/AppItemView.h" #include "hal_tick.h" #include "wearable_log.h" #ifdef JS_ENABLE @@ -47,6 +47,12 @@ void BackToWaterfallTransition::OnTransitionStart(UIImageView* current, UIViewGr focusView_ = itemView; break; } +#else + if (itemView->GetViewId() == sliceId) { + focusIndex_ = itemView->GetViewIndex(); + focusView_ = itemView; + break; + } #endif childView = childView->GetNextSibling(); } diff --git a/code/sdk/application/wearable/nativeapp/CMakeLists.txt b/code/sdk/application/wearable/nativeapp/CMakeLists.txt index 852d5a3c7..779b0cc29 100644 --- a/code/sdk/application/wearable/nativeapp/CMakeLists.txt +++ b/code/sdk/application/wearable/nativeapp/CMakeLists.txt @@ -7,54 +7,12 @@ set(UI_SAMPLE_ROOT ${ROOT_DIR}/middleware/services/gui/uikit/sample/uitest) set(PUBLIC_HEADER ${NativeApp}/nativelauncher/include - ${NativeApp}/nativeui/screennotify/include - ${NativeApp}/nativeui/bluetooth/include + ${NativeApp}/nativeui/include ) set(PRIVATE_HEADER ${NativeApp}/nativeui/ - ${NativeApp}/nativeui/main/include - ${NativeApp}/nativeui/clock/include - ${NativeApp}/nativeui/bloodoxygen/include - ${NativeApp}/nativeui/bluetooth/include - ${NativeApp}/nativeui/indoorwalk/include - ${NativeApp}/nativeui/rebootdevice/include - ${NativeApp}/nativeui/activity/include - ${NativeApp}/nativeui/heartrate/include - ${NativeApp}/nativeui/callerlog/include - ${NativeApp}/nativeui/makephone/include - ${NativeApp}/nativeui/rtcservice/include - ${NativeApp}/nativeui/compass/include - ${NativeApp}/nativeui/connectnewphone/include - ${NativeApp}/nativeui/alarmclockmanage/include - ${NativeApp}/nativeui/alarmclocktimerconfig/include - ${NativeApp}/nativeui/alarm/include - ${NativeApp}/nativeui/temperature/include - ${NativeApp}/nativeui/offlinevoice/include - ${NativeApp}/nativeui/settings/include - ${NativeApp}/nativeui/set_desktop/include - ${NativeApp}/nativeui/set_card/include - ${NativeApp}/nativeui/add_card/include - ${NativeApp}/nativeui/set_dial/include - ${NativeApp}/nativeui/set_dial_style/include - ${NativeApp}/nativeui/key/include - ${NativeApp}/nativeui/player/include - ${NativeApp}/nativeui/applist/include - ${NativeApp}/nativeui/phoneservice/include - ${NativeApp}/nativeui/screensetting/include - ${NativeApp}/nativeui/uiservice/include - ${NativeApp}/nativeui/uisample/include ${NativeApp}/nativeui/uisample/uitest/framework/include - ${NativeApp}/nativeui/aod_view/include - - ${NativeApp}/nativeui/alipay/include - ${NativeApp}/nativeui/alipay/include/AlipayList - - ${NativeApp}/nativeui/alipay/include/AlipayTrans - ${NativeApp}/nativeui/restoredefaults/include - - ${NativeApp}/nativeui/videocard/include - ${UI_SAMPLE_ROOT}/components ${NativeApp}/../service/smart_voice/smart_voice_service/interfaces/innerkits/native_c/include ${NativeApp}/../service/smart_voice/voice_engine_hal/interfaces/innerkits/native_c/include @@ -79,14 +37,15 @@ set(PRIVATE_HEADER ${ROOT_DIR}/include/middleware/services/bts/common ${ROOT_DIR}/include/middleware/services/bts/ble ${ROOT_DIR}/include/middleware/services/bts/br + ${ROOT_DIR}/middleware/chips/brandy/nv/ ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include ${ROOT_DIR}/open_source/openharmony/foundation/distributedschedule/samgr_lite/interfaces/kits/samgr - ${NativeApp}/nativeui/main/include/dial ${ROOT_DIR}/middleware/services/media/foundation/sample/wrapper ${ROOT_DIR}/application/wearable/service/msg_center/include ${ROOT_DIR}/application/wearable/nativeabilityfwk/include + ${ROOT_DIR}/application/wearable/service/device_msg ${ROOT_DIR}/open_source/openharmony/foundation/multimedia/audio_player/interfaces/kits ${ROOT_DIR}/open_source/openharmony/foundation/multimedia/audiomanager/interfaces/kits/audiomanager ${ROOT_DIR}/open_source/openharmony/foundation/multimedia/audiomanager/interfaces/kits/audiocommon @@ -98,6 +57,12 @@ set(PRIVATE_HEADER ${UIKIT_ROOT_DIR}/proprietary/src/ui/innerkits ${ROOT_DIR}/application/wearable/service/dial_market ${ROOT_DIR}/open_source/openharmony/third_party/cJSON + ${ROOT_DIR}/middleware/utils/dfx/diag/ + ${ROOT_DIR}/middleware/utils/dfx/diag/diag_cmd_router/include + ${ROOT_DIR}/open_source/openharmony/hiviewdfx/hilog/lite/interfaces/native/kits/hilog_lite + ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator + ${ROOTDIR}/open_source/flatbuffers/include + ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter ) file(GLOB_RECURSE SOURCES "${NativeApp}/nativeui/*.cpp") @@ -105,6 +70,8 @@ set(SOURCES ${SOURCES} ${NativeApp}/nativelauncher/src/NativeLauncher.cpp ${NativeApp}/nativelauncher/src/NativeRegisterManager.cpp + ${NativeApp}/nativelauncher/src/UICardPageFactory.cpp + ${UI_SAMPLE_ROOT}/components/ui_test_lottie/ui_test_lottie.cpp ${UI_SAMPLE_ROOT}/components/ui_test_tiger/tiger_view.cpp ${UI_SAMPLE_ROOT}/components/ui_test_tiger/ui_test_tiger.cpp ${UI_SAMPLE_ROOT}/components/ui_test_running_ball/ui_test_running_ball.cpp @@ -215,9 +182,14 @@ set(COMPONENT_NAME "uikit_fwk") set(UIKIT_NATIVE_FWK ${ROOT_DIR}/application/wearable/nativeabilityfwk) set(UIKIT_NATIVE_DIAL ${NativeApp}/nativeui/main) set(COMPONENT_SRC + ${UIKIT_NATIVE_FWK}/src/View.cpp + ${UIKIT_NATIVE_FWK}/src/SlicePage.cpp ${UIKIT_NATIVE_FWK}/src/BackDragListener.cpp ${UIKIT_NATIVE_FWK}/src/PageTransitionMgr.cpp ${UIKIT_NATIVE_FWK}/src/TransitionManager.cpp + ${UIKIT_NATIVE_FWK}/src/RecentManager.cpp + ${UIKIT_NATIVE_FWK}/src/SlicePageManager.cpp + ${UIKIT_NATIVE_FWK}/src/SlicePageFactory.cpp ${UIKIT_NATIVE_FWK}/src/TransitionRecord.cpp ${UIKIT_NATIVE_DIAL}/src/dial/parser/DialBinParser.cpp ${UIKIT_NATIVE_DIAL}/src/dial/parser/DialBinParserManager.cpp @@ -244,13 +216,13 @@ set(PRIVATE_HEADER ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/applist/include/ ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/format/interfaces/include ${UIKIT_NATIVE_DIAL}/include/dial ${ROOT_DIR}/middleware/services/media/foundation/sample/wrapper ${ROOT_DIR}/middleware/services/media/foundation/player/interfaces/kits ${UIKIT_ROOT_DIR}/proprietary/src/ui/innerkits + ${ROOT_DIR}/open_source/openharmony/base/security/appverify/include ) set(PRIVATE_DEFINES diff --git a/code/sdk/application/wearable/nativeapp/brandy-auto-ota-cli/libuikit_fwk.a b/code/sdk/application/wearable/nativeapp/brandy-auto-ota-cli/libuikit_fwk.a index f8834ae8545d8059d3bdb2c962d88da110d44f46..eede3b370d311bc364d6e0d0be12ddfaae8351a8 100644 GIT binary patch literal 423236 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

`*S}}Lw;OhB-)kMdngCxIe&odATNvP5 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 CO_V4A literal 240634 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


$PPb@l%T=D1Uws_`F)d9ep>C^p6E8gs5vL;;TX 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 A(EtDd literal 240634 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 diff --git a/code/sdk/application/wearable/nativeapp/brandy-native-js/libuikit_fwk.a b/code/sdk/application/wearable/nativeapp/brandy-native-js/libuikit_fwk.a index b1ab9d2d0d1b9d1126089aea9eb9f39c253bcac3..e3ce469ad2221f5d9d6892dc293568ebfcdf16c0 100644 GIT binary patch literal 423236 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

jWuCE<=N!Q8 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�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∨v_%j-- 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 F`#(FElxY9} literal 240634 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 diff --git a/code/sdk/application/wearable/nativeapp/brandy-xts/libuikit_fwk.a b/code/sdk/application/wearable/nativeapp/brandy-xts/libuikit_fwk.a index 7864f090a629acfb390f5a5207419b7272001aa1..337b034d5ee9c4252e2319ac1d3b83b956b321c1 100644 GIT binary patch literal 423236 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

-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 G;{FfX)|6KO literal 240634 zcmeFa4SZcinLj?sP5MT`Hfez-fN9d!0yiNyFKvqGCQWW>O5bcs1uT2Hy}4~JO_Okw zmX<{=w1E~23l@-8bR!nFRCG~!6HyD>YGF~Ui|_svSziEAS!7*BW&hvr%sl7JJ@?); zt=*sC|2LnUobU6@GtWHpdS>R%nKSjgcskMb&T;2dWV*=ghS^P#y4w1Nii%q8<^Hdz zh|FqgY|{M8#wk@WR;kvKzs|LJlv4li`d`n3g0-JgM|Exes45ul+WV*~_$yw8@pr0Y zx~{uQ75=~LSn?ot$>N43^Otl)X3dQ!*0!bNYZj*Z2a-L>bR@E*hjhn4JUtLywzwlU z>%#UGspOT>Wfy>$L%-;TWY0iU4X5P%+--F_!o?i}^|4qaQX7k{Uf+`#NcHwa>SD1C@$U6W&1s*vVM8=3 z(s^=YmdT7`&4)QQcu(gMH5hZ7#8zWnyaT!3Q5R!YUof%+CAv-W^CTz|Y3)wN(eEL${kCfZD?DUx94kWxs#|HV8>q)CRg)Z zZZ$T|PsaP^#`}{x8f#ikW@J`QJ$X|zyxp#^?ZF}qra4Mi=UOz3h{>6{$kO%w}E8`iZsqmu1WRijMrHhMMn~u<Zwi{d>fEP6-jdYH0#*)5dI?e_Y zjk1+mJ9E^I*)9E>dJ=p%Navxelb^OD=5x-(9bG6%-E3Q@X01pjP_x^a%z8gji_n!H zAvtq&WoP5?g9WShuoZr|%&M>Jh;K-CNb~FHiT8DM^$xVJUYtxM`}^Z)in*WC+4){K zE4Qj1j36_V=*DKBb&Y7Ly@~jMbY#PJSjf9MRvtNtF;FzRAc_GS^VIG1mcwJ&1_{LqYM*iM3o*$t=_~u?nfT$k;@z% zo9>Q>E2g?8=56cxbQ+`Vj^6d@MDm!5sKHeuWt~+(!&ws1rEI!VV@O8X4jZ&VPat$H z*3UW49`uMjFvQi(JExB`_>~5h=RxG?IMR6kFCBvAt6RvbT>Vh~j;lV})9JKvx1Ahe z$`TxjOUEZel8kX~o*a{Lt4_`_bjlfV97}k2SUr+%Gb6$g1+X#LzNf((T8(H_)s}kBfmn`yO+OQ)ibryWVpBV=QA&OuU!@s& zew;Fg1K{4C*j34NZ;k=*af+la5{yI-!JQ|AOc3UDBnOuCEbGMtI_XU$@Yt-yh$f5g z^^jg@JWH~qxIQvWm64({T~Ds+k`e&2q(@5xYF1;A?Wa#nr(r=U z9ffV-BV07d^SsbgWjmuEfk>XI{Bd3qIELqrn~q}*ZoBu9JcQinjzZoPnLCupcnWE) zm|SEnaORgfPTizU&vAWd*wp0j-P}yf|8z9rv*&FYz2`{Ezy^@#@koNuLK*4#V>+4E z*P~_n+?-1i!-j8Kh6NBT&Zm!{M9-?5d?6VR`qqskElo?;_jhpu>aRTOtQ|>M`y7%5 z$dLqb3-@T{bFLz0F!L5lTf}*wBrKNzC4p~{hNpz{z&UiIxml*=kbfh zt_7R=?yQ5^MU>g?{Y#TQovEHROZxhw>-q*V*4MJ+>+0M4+mhY!P0QBz^yomc@WP3< zBW_n6@+H`>!A=-sQeACpZ_nx!?6Ins_aZVU|BoplDuV1sKuRy7o4#XW7w-F2A}+TPof?H`TK=p6*YkrJ?IdYTmdaxgv|Wt0jz0 z&(!PcGW56ipch$<8H(Q}MCvmn5HmAWI=_H#-e8eACIQsNpO#XI_H}EbOPgZtOJeid z7v>Gep#&4I!zHg+pTy6FBMa%qXa?g)A8tt>R~SbYuCCU%v@NwJH4yI}S-?o6A8=uO zRkC{o*%E2;!?dImBMs)}=G@+mOVhn;(pc9UL4wo7JXH77X$ zVtI1oKr8wLENVIvlZY$X=u5Wrtiils^=e;b6I8B3FA+}+NS;PGFKdnW=@|$*j@g3! zP?=3K!Wbm94&^7=Jo2+6F;6SDs*Hg7qR1E{1=@VZ+%n)7;iSXFlH7ngCj4C6Ii|16q^ld3uTGK5rGx^?(jOpL2}{a+k+n)W~wDDAFK94V$jx z(B9CO9l5IJHph-SOl{6B5|~=#7IIr%eu?3t$!I&dRY()E)9?EAJ@}b7$sg_4#rtIG zSGT$)^YJ?q1~i?~IW2vC?0nig7k6OzRzE-9-?gMme35fa82rS$V*|bBmo9Le!6T@K zzIZC#&aFTg{&RGP(PXp(n*&lkn4rYFu@IMzb@R8?j+U5ik=8tHdFn!Bu>r10=^rF# zTaMWYHGp5lk7%?W&DKFxMq0JvBz~K#k99Q07Q?pT6Gp=qu8P2RRuwF`W@^(pV3l>u ziFM45dBRR!ASNi_78twO4lOAR9Aj&fn_~FQzn>Zw=vj*78O&=idA7J?eoW^9g6mvK z;mOW@W#$)Yn54Nqy`9N+M6?t?H%6nY^zV!M=fzrg=gwcN;H5wPn=asBBL8;gTY5a? zJ#$yo2WMPCfB*3s33|D6Ab-}yEt`=hOt}Z*Df}9rYt9!`Sw$J8v;_vSU$_Yi@T8dfYN|CwqUPDtGpG4658LGSk7oP>Goz9)ps) zd=tiF(B)QYuVLve9Y@*FBG^eI>m8<2_aBp*5zc6X?cA;_EKjXV>TUr;0C#nu%dQ~9 zyR|Fcv&R2@)1R|tshrc&*}1$I$-*?5yA3(a$)6@2h5gBDn4Yb!KA@Eol@Vxe^5obF z>cy|N_&{9Gn)MC~vuf(j-~XyJ{jA(PzH@!q>-o1i2y9rL>gnWg&l^zc(OaSy8zN&P z8QEdmn7?1FF0vTwmK%~XG0Hm|mfsYls(Bp(p5$Ev`CE$ZkUa5@^{Y0Zt)Kz2uFlR< z=lsB&_2jqDG~0!EnvS7slYy3L7{U6Ox%d~JBqc*tF8_?3U3`)1Z*Wy%RyxU4MfGn2f78?JCcaY=OsliX zq8~}vO`;2#%OPeDq-JNVlIU*9${p2$l381cHp!Ooj7+b!YdUq@KE zC)Oqh^kQ19GwE+ZhqseM9j#_bsS&@h;Z?__nx;syhbwKd)av$&`qOnyvDU66-d{|o z3;t5$i3^0I@_?by@5+{(T+v#8q?oqJBwfm(#zRojP=V5f<{u~ zymdKtzP6FRiRz2(XywP9tdSj`De~&vu%5%MwTt$V$atN7jv;8~@IuTw`Vbj=a>Tft z%p*J;-P{?8X#TBw&a?3dN`sPCrA*m3>2%ilL+r$V{B%sw06hht=KaWfA)OI=2w z74?3wbId^(UfR5qFzPBQ>S}A@YyL-SYiG?uawCn64JOr>jeCD|;k<%^0wu0M{Z{#u zQg@uAR0y68T41JHt~#{;6wqb3C_5e342$1}`%H_^#QiLb&&EA$aW(EW7DK(NwK#%% zoyGOIGfwJn#5K#}*|;}Z{7!rSJ9}@&y~X0WxVKu|Ztn|lzW~>PU24K?oc|G;F;?x{ zS~cUq>til${OX~VrL!ih>Kp4Dht#`ntp3@d=CKFIw>;f)?QJhk_z*(8;!XI;cKbf-zNh7j z2UXS3y{hW2u}bJ|2cA2vbnt+R&buZmdVV+Q=cm1L+H0r%d_rmQ=J8c`?ippIi`B!7 z^}1qpj~AyO$EJsycd0S^wtAZPmkt(<5}l=kTZ;r!Vkc~Yf8mY;YS$^KMr%-)n67x*uT{OVBiM4Rh}SH3u5%-qnFv4vZvj4IkPqxgh-qjiJV z-oE9wX+`ye_ckxMt?QP=SMF9@ZYwHEv_7cz4IWxKp{4KdU%I6*t89v+6}t;?HGkN| zz3%Z~%<&hpV%}9$lo>N)MVuGjJMPfR@hzb##YLfeXjP%HsaX52cyLT#LeRpX`?q$giB`S8j^`wtyJO3N}*`8~w`eWY~U zzUI=&;|f{^ciuL(;PJuI+kvn9%xz=mefHqN!o)Lok3kGY%wvhMIC|*5cMTP^|735_ z%CoLxUL9IlKkCWmz7Hl2A1s{E!rbip`@-AzENFAVLTv=g6usM>Pxfl$?*Z3R^ySzhqsUQ;uQ zP3;_2tQHSmGf(u6J^1kxrWaE_^sRQaXjf?xwfTehszc2pv0$*`!=?^iH8DN;^2w#e z#f5&YKGgi&q}`MJmdiB#e8Ov}>Anop<50HtSM1u4n*He~_idfuGUwnor~PhP;>vHU zn(a5ud~{~wLqAgzfAvuJEx*4-D7M{~FWon|U@*JZg>E~bii@AxGo&@wZ2#KSeOpWa ztMPwIv5lsxe}0?W}aCPx*O#@ee3Iq(g)SF-I80T z{*P&YZc^g9J!%SjOr6)X63+x(%46Eu3hrFQ+?Q}HA;Ea04dd(xEbH8xd}m{beDE#H zs4_mzFm{+&kL)G!1jlL;kG$v85InQ8J?1sr)4O(;%psIN=a_0`7K@!x9x zOYq;uZm3%qk9csE4-L(zXyfSw$nPf;gZ&KTSa z)VXSrr8jGOj-|{kq&VX9T}YMt1W-tw9-!YEpr;1tssKGbKyxJNyO285CxAkVBTCifWFIrMYDzjkQKUgR~R(=oGAs@tLe1p0tO7XybK`Xu1F4t)yna)+(}zR#i0 z1orKDtBQcW$g^jvngjX_hi(Dw=hsx#4tlBM|1Qv+>ljz1E(YB!q^eSJ(90Y;1v>4} zSAh0=fwR?BpilGs&sJMNpX$&%K>M|*THOY^%=14-eH65B|2gWPL9+~vi>UiSb6zL( z=RhwO67BB^(A^IGZ=fG?=x0D5a_Ap{mOe_Mz5W8UZ-2dd8MJR-z4`;_30`>48hsaX zEFm}KwpOJAb>r>et&@Gk`D$+pVgpyjL7C6;Czt5nm~ zKU$i7R;7BII$&v#y4`&zL;g(lJ4>@quPi)A&9qJ6u%;twrKMSuD+_01}f~9NWH&MMq{imgA-&FNZ^%mQtCTjZc)HF-;HdQsNIhF>g?TuNQ@lVC`_PqiB zdmR6XcwQc`G~=6yp7J?MbEJdbTNT?TZ1gR_!z0InA{MT_AE0v`D~V0?{)v#eetSNe zKs5{J&aI8jQs&-h?+y0er0ftN8o0htZew)f!ovlQPOa^3{R+YN~Utf}L$ zMQ+)4qFEhJb$d#VSm6*9yTjMvP0#LL9JLq$o!A&Rw#MR#E7qsdNobSJ1ljuZPYZcZ zKFv4fT$fyj-xP;2)BK1O>+J8vFSI?K-7rEMhFsW~LO{n#dvqX`$&Y3J**0(J15x#k zB)mXpUf$Ec4@*Wj$z+`QYtt1tR?0a%>L^c6mEWgq71Kp1Z%E*56xK@f4jJ;fb5l>8 z)guw__sh$(t`VEEafYt@hH|jud}AHQ>RFD%yKvg7V|YUpFFg0GiQ+94bCPcB`cs>fS>&AR*<`%4}W@OR=<*4NyfgFk;a^{s}03GFP+2>&`xTzB9{;&YeLxc z^uK=0YkXC2nt3j@b);$6)%mY^*z1bLJl7<#abtW{YD0uu0kBBb-yh@dhggb7m1d+$ zTDp6f1-b!Ohd$dRHN2W&yBj_mTwi(8WUagTd7oE=!``>2@DGkyR%ST7I?wWngUj;0DV&UHmEcOr!pKBnc>+lbb zSooZKhi8&&)X)pf45sM8R ztCmracU;2f9H-p!iG@$IO8W2*j#&8oEw=0mrDv_gZLiQ90MVex`Nh(*tQ;Bw0+7XC%RrTzE^M@&8)L{-^>rUmCPb_?vZ`pby z@0RuZC~x`1BEJ>5gbLt@g?|%p$(7`qH8bH?f)0l@Ti4aFU8cMptZIunO_IDNW?1IK zI9!sq#KNBhT(S}W;D{xz3Si+A3x6iCCGgBeZ9Kj0r6vFK#7%P=9QZesF@!BXXx zPb~Z&0++lO|KNy4PbKH@ELb>V;h*d9iG|N~KuJ5X@K=#<^%D#KI^eSR8~wz>zX7=1 z@`;6i6XiD>d1B#zkn)yKEd1TTCD#~vV&OkV{@4Bf4}>i~gV+kS0k<~b zAKWTjf)5kh<+SI4t7qXK+)KEs?K1gz#MR2m0(Tm4*e;i!1zdfu;Ws$^73ABncad+G z&r2X$!iL2=F0r3c3ZGc`v|0GX!mj`hpND^NOk>G)8fq*uVe+pxd}84@lW*%evGC`U zZ=WN?!Y=|2+vWao4rV{x`cC|VW1hGEorZd^Om(xtC*vmdgjjS^Ug`<4@R^pf&G-jL zEPVDeQcsA5e-^OR6Jp^vlb<7vWJ$Xq7J0TQ$!B8Wvl@k4@DGl~9Gz%gCnb`ACOsC9wCN1K*M5ln0#mbeZ9iw(rW*KOwl zFyL7KTNi4Gbw}Vu2D8mpTbVlYIkfmmnaR`!6ZlNQ`;YmKZiyS!)5Aw-%I&vF_kz*!^ zeVktB)5p1p$Z@EgPmV(_k>k)gpWLmE+}2^_h8(%~4I_7-Bgdg+zIY#jAID8BHxBFa z$?b=q$kEn(a);n2>E+NcpWHK!9EXSb@>FT@VbgY+HeWzGI>U#*6)@K9O;oc0MIMMfMFtk3)*!otb_JT+I zrdU7fdlr{#UmEhXMV#pS0T`}*;R>@ii~3krl3uRgxcYt#1>FB4PV`L&&((KFg;Ku< zkNS{wPv4c`F*xT?bPplW3Ip|j(U%VBySWm3?;t^aNV=zw`|n(R$8l$X=X1T?VFBE?7Ip6uD)@|$eE%HchR>!pzjgryA1x+$F?K-z826|2YtEh zdorN!R2Wrj_3>v7(f9j+zJ<`obt-Z2*6z0feef;)O=qm+q^Y7cxcd97E zUG$vM!dtsX0f?IosV;(j=K<5cx8tH8)AdIHSKq17 z$9gZ0esp}NNz2)Y=R?kIM(f5GpvvQX?`W8C+er)wg-7Few*5hq3 zowrQO^Hxsy?}VJ|B)z|f9J-i3@uM8$6DM-K+oWo*9gsVWi_589xR~AvxEKxed2VGX zo?B#EC;HeHT)C}C@5Ip}W$Fm2bLwVQxb8^rJkP4Fo7JQP9QmE+XAT$}8g#TX)qkts z>HOoeGnbfYE9)E6NZf&oV-w|Cq&h+55-seGl$;TYL}h|7`JI-0!t`AMT&9_&(e}Y4NA*{a{uzru zYwvuH)3yigUB=80Tlx{)KWFiy_WpT$f6U&$VDDeV{Yw__$Nh1OzijVcvG+r`KWXt( zxc{5QU$gha_WljrziIKm+xs)Pf6L-;+xvHL|E|T~v-j`g{sW7DZ12zF{u7ITf&23o zzhLh#;{HpEU&8%Y7XRAbe}ntWxcDyXzO4%*^P{&M-0Z!3{d7g>%xKZaezhgKU4`cD zQl+y_R@Xc^zJ2Vkx8Pm)35#x>cjC~(OQ*bOsRa}F64kamGw;kHixw=vJJ=sW48Pc{ zymw-^9l%@1L&DwBCMYzcT_rZ%qu_f#-hsrMjO}Xb(7r+9(-til+>CcK7RaFv^?KDe)_H_g~B_q^UXW3&o_^0obpwNztHgaHji(4xqUENc>AIG zRh31rS5*|f{@kP&@m8?N;{8hRE&W3aMdp=BujP^1yO3`|`|q}!wBS8byp`#{vCp?F z7e*IMe7*&5p6d55`L6p}+e6X8(CLp~)4sE)y>MG|)u&+11mBiWbbDxU?8l1!<3H|w zy=wf}!iwG0GrwixLI2%cyghs8<}nYSpwyNa1J;RCU%fuT{-F z@EXS-coSNkd)*hWlT^xG-uJBvKk(Yl;;nzIn)bk-co+Xt2Zy5L$CQp;IL3XKI5d6X zs1KZ4TpXIdV^rewXaU|){o|JD<3}e>c~DV)aKZXtO}r}-uVIV zItaN@gA3j}nWro4jFziKH-7xYm7@!OC3YJdi&g2UXNylCsyeBAbYj#Ag`wz<&d^An2xIP_l=tPW&fS)(A_7X zhPVBhZz``C+zBSTl%3|oUYfV(@NFJ1aU)e{AyqT8^VrXUs+)>N`EA#{yR#}mb;k)2y@3lH8pNq3wsyVi zgtrzK3vUZ*?u3@o?L~#3DE{229WC~Z2yj19eDA13EzeDSapH;2I3PO@Hjnj33FefD zEqH2eKX`WWgQLbQ8oHw(I&{YmcTc`zbD6H4u(1y3Csb8F;5|phmJ=pVFAyyEohv4* zowtoDIQyQv=c3GC96bN2!GiO}7tfPlZkc}I#n6ncFIH9Tc`gnj{`U)Xlw>HRnFueztL0B3v@pl0fDXAZHB%@};j z>r+j+wCOV?s^gFC7R{2kADCENJhZE3yHk<}4~!oBBy|+b^K)tjMle!7E4|#|DHF&W zoHKzZ|LDZ{;*y%}KRL)e&v)9#mV>vBKJ>%H^~E@gr|4Cr**o!L%k-jGLo?c5MQf}m zdKDv;S9csbe8_*!hNic@>bI{Q^B+f>Dta}uO-brP7Zy*P@-si@E&MES0&80`K~n&4pr?a8s(iyar%Sixt7tN)xM=Vewx>_X4kZ5-;%2rJnWsZ#2DC$ zyjaQ}EUb>7=amsk)wAx*KV<8_Y{I2q66z3%Q(V=!2F{_=1V)iB&VE7gSZ=tC*9; zFSsW&aV|0&s~n}Hu2U0mE>n6U&t<~6@LrzER8?`W!Ypa@pAXWC?FYBuq?heKJ2h$$dxjmVb_p-FZ9Cbh@r< z=M0?FQ!ww^4~Z|%WkP(R8P}b}6Jgqm#x!2cwpzq_%{7?UY?-$GxWuu&V9VRCJ4x-n z_Ikuu^pPB`sc*8_v|!LLn~L548>ji;Jf4;lAD=&c%2$IW?w&t{({1nsiMN7oL*c|9Ie{CXVg1}{Qg^HP3_=#@bDB#*_5HG%|)XQwec*p%+b@YCsf^u-snc2 zZMC(?AEmH=ni75f@ZM*Bewt{JJ4ctCEw*_l?TC-u$9|PEABWa6wVeM95ed0-{CU>) zT^ZUECye#RzkW#b%*GfUqfvi6Nh%i)r!+;S?%(`)=1j9$k1xamH|H~brW|zrOsVYK zIVWo2>tFb@Z);vBs17|ZW7&KPqKO>4U{J%4u@}KFHt1SKbl&Rb7`HY;Y z^Mh)erE`Ura?Y$X1@oS6F=y6|QWJ|Gyz%VS4_4F-x>}3X&>f~PN1y7|^nF_|N1yA( zyMO2Q132AH;t>9!1637s&@1m!X05}w+qc5hH3_k8zu%JGTF3hRgXss=5A_*i*>!*6 z_l(V@#nBM#)irxeyTrF+fAK+saR!@y5{y#*Npw7i5a;{7g=co{UFeUo-1swFgzH0F zmQCHcVTRiI(8=nPH{J5Y&>f{4zWwK&qbdqZN2|iKfALV|XOmx1i$4}jb0|8wxZp|j z5XEB;qUBu3ma}c)mfPBjLbu~gz>~55a!RrwH2H3I%Z<0)xa-EVZ@as&xVY<xeR zLFpyq3hqVQF1(#*BhI`fQ4|erYo@>9^1Q*&?QKO1Zu@NUgUz40t?Gjh6!ARFq20c| zX#sto&Z*CEd0JuU_D)~lPUyQu>l52A72CJGEjmW5XHDhPWy{+RjyZSxLrmR=wl()H znlbn_*e>bhbCBi6xeo7B?cGpgu%ahpeN(!n8-DkjPfUMk!s3q^iTRP@?FNmv^={0? zHtZ43VryBt^y>G#JKD0WW$wagMf*9IR`|!tR;y&o_1 z6O2>uIX@lm>q;dmqUm&R`qGN`Oz%IpVtVJL_@b))GIz!5bnm)~%lj+(yL#7mcUE90 zT1Ef*zCOGiYxGpC!Vv=%tJn7=_~P=^spHgKM(dlAKa#FwMbG+m6}_vCCatIo-`ML- zZ>mW3SFGzzCo2Z<0)9n(xB`i=@m-k$T$QXybSH7LS|?*1K`v zPX~@D2b`26+O+wOcg2-m$sU`-Mz@z`ULMRv&Ws=*7WY=*lL(zj92tk4gpE37)RM1w z67in5A^YPSl1|R`_r&{P>Oe(mb;Sm}M9(bjS>N4_L*A*Y1JXJg#?k@V4#>8zUYtze z6UOoMCO@)w$J6{$xnCPnYw!t1M3pB#of9z0(;j2gtMTolps$9q!i^nngiV|$Xx&f$v-M_SOT>@v=uZhZ`f?r6A+`zVvbBQ(6Q z!}p}ve2iY-q=|J1HvYr(&hYfk_vW{)e{HI-V!&^?evX)K1D{b$b>b7N_^6cM^!t%# z{i{<+JfVi|+T;D3dJ+|AnSGvBM+lMZ8Rn^n(nd|ty{~B?rtDFKYm)t@Bho3MwYD*h zQ_-GIoqakD_;oX%Gv|-;tAcBiUVgWtk7NCkLr8P&jz12^pc)nCM1AwM58q^S!hB?o z&soyPkG3L>`~uIg&gjkYp@2xeug-qyXIMqUc;+}(2cNOvc%xn3zQ9NSY@X^uShOY` zX$%ZP@JU>JK6jRH6>}cn8V|BfpJ3PxzVvc_I%HL}ep;+H@R^d?_{7M(4g8R;%55pW zteR}M61kFjbcx8Fh77Kk1RR-_GX=S<$mZG9=)*s{IM9k=AR!+Gmh*b%T-dIk+B~#} zA1Blws1M{&o&JzZb_D-F;+S?4$(dVO+3==3Q@AxF8QEvfW_Bb;K7*D!-h3C*Ute%( z?x^w|&!9cUl40Bn^ob3wKX+aEE~Ix}x%7oT0Tfd24$v0|==TKZO9ON)K*s}gB0wht z^qK&j3ealNf9;PVQYT z1pVD&<8Su={nQr*3Sk|02@QcW@qI|Yr$u@Ut^)NlLeGWNE)Nrg)Q1B!cklTwq_~66 zcOf<86F?z-VzbW*sgL`F_UGWcZ=m?BkUsI*rMcVBcOmsDp8yIe?)>vz zNPXHTfI^Bp0DTwIJNjLkI|6+da!wN_H>4i+JvGgpg1!qmrx%kOQlIxdHO<|Fz6&Yt zBJ^EIaW|pwLTbOdX0)OI4z~jJgzpIy0=*6X^kYv&|64%c3e5USnrE0Y*H>AZ`^`t8 z&cEH#Q$e?YX3s|Xvq0YgdXl9-1e))})LD86G|y39Xz6=FvyDu(bO?J*E&zRzrN@K* zIOx@uo(y^{+QccAz65jyXtVeA36%hy23>Cb9|3(M==qj@0`#{)&$9H>pie*>I@i+Q z1|0=`wxyp1-3NM#rR&Dw99Yl|mOc;k7eF^zdLHQia>6eKU4b^Y!unqVdIRW*mfi#U zdeHTj{uJm(9r_W_zXHA7`ac1>1#R>#mOcf0@Rov}W9g}&xi?($?`+UN0WJC82pa3X z`rHbZ*WZC|1kEQO>2}c9f@b?C?YfZqSC>TnIT)b79H74vpbrJ;rvmiT0s3nJ`s)Gu zaDe_sfd2OY{Y-%Vc7Xm)fc{>9<_=lkg)kl%M1IkY$5o)7Q}qOJ`*0PgA89QALRs{W z#Y^8q>e&GOT!8**fc{y4{zZU(Awa(vpkE5mzYfs93DB>opCEmF))+TWy#RVZNWAgz z3TU<^e%F3=?o-IqZxQX4^E?fEZJn?d{b zFHze-^Bqm&mZ)1m?{Vnep!bV6#-DeAUf}qD0<>RBOVk6POC0|%fIh>azYO|XhyFU~ zZ4Uii(90eAC!pWw&@Y01z@dK&dZuUJyVM^+`}y-O6+*}1`*)}lK>Pk3suVP;gmo9H z@(lTRtEvq7cdN5O*NC{fST%rN<|N}pie852rgAcc(Cw2S>rBM zCxLDgQpMCMp#A)hsS413dx)zuK|kurCsZBiCmj0ip#5Gnq1r&h1nZJ&5oo{tCDjVh zOFetmsLMeAT*UGHw#z~L<-bPtgWl@+Uk&wWH|H?p|7I6LvIEBO%YdX)lH!N_PS1e2()i+uNumruTb}b z_S@eT>NBAI_J4)?Jm||k{a2_1pzn9+uY&gL=N0NZp#Ac=Lj45v>yG>{L7(B#o7AhI zPxI*asy~CS^yv4iQ5g75^5|>STR{8r*QirL`~A^1YAWb5PkxI!3$!2K7F7@0Z*PO@ zJkT|s{Gf`0UhL3|L3ca!yFowX(3gQexJK= zZUQ~ep+5xLPyb#ulo5WPx;KNqPkjcoZ~woj&u7q|RtG>Mi>>>j0DTXs{|wN-4bWc2 zv+`a?XlYCo9QU{QjTI+(7|;7XIr&Hb4KKf@nDCsX`7Y$tY;v=|;pNvPYES0s8U)y(2(>G(bNbpucNr*5t~<_o@?00pQqYR$`XkYH2T%&go(p{;ifC13XoIT`dXt$1Gi; z{lBJe4ETR6Kz}Ykf5WBmc=(Y^L+398^#6dSEn?3s+XeEOi7y_hwU(ysQ`I-rK1-hj zx&*6mKLAZX314al1I)&$>f5T_(kA?O)Fw;ATZempfR=9zeH8vBm_I#2#c&I8m0-S; z#`+fBG^DLWU8?@chUb{SvT&C=i3?xWG0w>Wx-~#gv-((nN-$rz$oeyzN>p6!u=I19 zPN*jX;hzuCGH3%G@lfegoKG@*7k=I~q76f2HcTbOm^o_`PV4r71&u zK4EDVW2O2B^+QYZ$y{0Zel^Y+5>Wo_me%$aZda=U{;2@n8=!Xu=zp~|vu&#Sg*v4I zz&geksW8OLxJ|{0<;yJ1@~*`1C;x0|kUBk2Sz6nV(-7V|l|GUm|D?8N&_n9imS!`r z#L82+Qj6=ek}L6hN{6MFY5zTHy`?Ed`~K0=CjahHpSE;^mfx$sZs}%C?^7>l(D$hl zJ7i+|EAjhE*wRZi{V%FDgZ{L-#L_ILO8mZZm8H+p^aJWnOPlmOsJ@gzKcs$UXjg zaK9Sk3<0VCBumqOqIz0IEX`^$5$om4EzSI$ikWiS(j0b7RbNrpTbl7t#Z2r@OM}#D zdcxAwKNVjjeKz1fmK6og_&=lOTl($bO;!J{uFvrQzIxcwVeS7t^$Sb0Sf{EVs}t=I z*4Xo`s<*V!|Dw9y8R9bi2Q9r+hkrp$nF(MW{oihB6aF`9Wx)T|0R5E!{pSFErZa@5 z{zQPjGeCbaK>v4uK8qF4I_kS9KyMGwj|S*p2Iz{jMVl$VjsU$iKtB?ozaOCg7@*H! z!C6Opn*(%bfW9t3-yNV21n6G|=t<6$gYnG?&=&^i%>nuo0s7wp^a}yHz?sr8zEcDA z+yK2MK<}_LA1hO_a{kGHzslO=Rg>uJg};#DSXpeja`}e+-5AMcMEp3V9T8U<-Iq2U76jP#Hsteo6HC8vX2XY zLspnbleIe5nZ#bu-h}sw%Qr~^65S@h-z;@~7Iu$gXFEULH!#Qh8XY_Ej=#blSoFki zmW+!;OwQ>~_~|lVew16EGxi62JD)SSN8UADvyflez!!3PtKnyCW3hP`E^b}kzGQJM z=6_UUWV^95B0qYQ#0-9xSKGr+_iDf|_Kw)FIeMEo--z;eN@Mf)$c>X&`N3cvJwN?B z(&+2!j`UJil)Lri%N`O1KPs%_;zxx?8dqIi?l+`RpR6{1O?kxHX63e=uL5P*j8C%| zTO<6Sv$k4)0ofq0^dc<25l7y@$mI(V zX)5Nuq1-XDV2pNVsz&;Q)+3Gw--mTy%R!%M$GCwncHkQURz2IJiO5TCotNA?)=J}h zRLQN+c)2CI%6vKWP4axS9~phqSZhADZoV^KE8hwCzrk+4APx`nW%OG6@pLfQcKEe+ z`-Sv~e12TMCoUf!m!OeY#KZ!?$})Fuz5NEceAK+&e(t=%-sKbPjaD^i6Dfev&}buR zMAxZR0vJO9MApWJK;|Rp0LBo=nB;*Yp>&;{JC`3rr-`%hb#UJOueck!$@R|!L>M1~Hz~sBy{%B4eCZu88JPs|lkrx0 zokRyuYZH*Q1;`o$WU`JyJvp0I;MMzz?Puk4eT?1)bUrU{O_Z{WNR9$nui3GP)d*x2 z%$5|*mg)pQU*6gRp0ysxCKn}SivT>EA|T6alJDN5;A}27dC>#;JgW|JUQo%~Cdp9* zu=xmNEkOWloz#iQ97*XMNz5EC&N-qBEH9kc4W3Oikc|n*6aVYoLN!YLYm{U(N<*E+^vD<3^1Ke2=c`{5Dw1P} zS=WIVO*x3;E3jr_q(5*!dw$Ep<*CHlzz3N;3&ejmUOHZ$T4&b}GK1E`FWQZlu9I5g za(tLxe}^ZQ=vo_Fvp$~g^wj13!h6%Q-rfPeCYQqy`-qwYwdPH`E0giHu|)6so&hw{ z7(QH=#7l(M)1*zFYBm5~%^UWWyr_J~J;$5}T}y03ynB7pyi}=QRWx%;CzX87+)HGh zQp@>ewPDJvE~1B|-uwUa&Cw4?U|%}bGl1CBj55+-52@%#rZ?csh8!7~B{FMiZ~uS| z7Ttgs{f8MrAqvS&e@!k|rszEE8|X?WUTWW}jiBbV_n@-$ zB;1;nEm>FJ-rt6gSZ!Knj+gM?!OcAz(O>y<)!6x)$-33PO|$)p&7yb@-jhw|$Uj}( zBRND_^L+(+W)ys<)Q`$}yVfS(441u^znAponOo&c4bvWsZL`k$!t%Q0u=%m^gkqdTTo#)oP0k=ZSL zWxoS&?6aRn5u|kv`Dx2h2}h8)qYEXe8`+ENu}ga5=<+4=v!gPl>GdLwvYKc+>|r}* z)bKf0zBk>DchsZN1yQ_B&YEBAbneUHvFw87wXwFoCCei*wJy1?KZ%+mRz;i_v1fJQ z{D^cSx)hVf*c|IlNI|QwPZH-HN@wAEd)6CZ1?%wpG-cG#i&n!;#ZSrD^H0Ydc zjVHR2^KdFjP?Im1BO{yK6$^dfh;#Bz<{ARlLv4-m)_r_d1m(;@#QFT%A11i5&P_dW z_F{>6zh4{V+k>;(`&Zyxq25*;vJp@9Bs-lPvYA&`huo8;6z8y&T&Xip$-oK(KD~(r z-MW~U{H6=r7wH-uWuuX%mS@PI=jirpjo#3SOw-eOtVX>al5PGRSU*3RTGKUP{6_X5 z_dZpMct#e&`97)GmTM3?t0PzEHo`c}M@&V%lwoaq4+du`d?(bc`tFn8_U5zO`^{cE%mMM-hZo<->t3hxzc&w9qH4yUSrMvf@$zO(7HP?2|aGdib#85 z&*&XRf(FjoBb`s4gEzd^f1HewI%kVASK(xe9ItpYs?c##%86%hPwc8>x;Mwf^EgFP z7YRlZ^Q)}%271yw2V}p)SD=O(&riNm!BUPp!fzge&QGFz;&4HI&Jy*um$Wn@6*jCHqrXC8PcQ zo^qT12E=?(G$;GwY<469am=6fSxPyy1^rEY7r3TG^r)gM)!jLFQ+p={q6wO0L^9H& z2Y<{ReZZ1mB2sV-3*(!5*AKK(70&B3`IZqCv#eua6Y{jnj|0O6Z~|VL1|p5~dU2{> z+$)X@wUJ1Bzwe)ISQEl8>CqB_>ev`$`({b1Xjo86M`8QM##jui482!kH%O-LlBc^H-BHNf zCrIWVG4~)bT?$7db(}hErpMbik?R2$sgK3hBnPmkraL)+--2^&_OQd@<7g3@!Z6QV zT?SI|a`o0aQ5n5MlRPZ!v_lpUu{v%ZHD*nbnUN8$Uc&injz#(76^qzB; z^ejy$+tTqX^>nR)GjBgJ867R6@#G@4bJwq4olNUR0loAV2r2zkE%f*H4~#ruMwD}w zB^P1cdVSiRxQJ@lv#_^k4b1QFcaz-^;AUm9NywUD!OVe?Yx0yzM5o>Q>humL-C(6N zietC{bxV4%$bd5(y>(_R-8h`ABp^Umx@#RyRsfi^%=`x6#!;8S%L;_L*ve&RJTsi? z>$0+g;JIYhk@-m0OXjjVvUDl-CmwZxj>haTT+iWx1dP)4)ql2T)E+)y&8kk;xFymk zeoK=$uoG)H&U&{yoZ_I-t`1}?;VPN&%+?~cwB8JFVABF{f7gXn#6es3mH zMp~X!b|ksQR%Z!P&Wwe)=4J*#et%$1_Jz7O2JLO^z#s!FTUSZ@R91bu`-1 zkX4R3MC&@bEMjy-(vN;4e*AkZQ ztuyLbB+|Bi9hVAqZ>TF{j-EEcmC*Cor#vAU8ReWhWIS=)3K_-T_LFdxti?-Q7T0T} z)ZgP?(rx&}!e34PI>RRx{(vJ-Ed2M8Zx4)MYz4a*Vs=i_KX2O&+>_d&-ZOg z`iwlW@Mn^Lh2awmzuDmv3%{HEw2>zk{zmfq4WC%}H#_pg!e^F=JhAZaBY(i?Ar}4v zz>+Rv;XeUfy57hW3x5)Dcn|);@!c}Pe7z@pH@SEh3YYLNC%%VVg;NWG|5-zQ!d`f< z!H?nAdauE!;U@V&Eb;34u+PXapTnOpIE-5>69h*Y2}>+tM*)XFiGOfMTfP+tQ}%9# zRH_1(=$r;zZu!K*r#&T`Oui8dzkz&v;0m$u&jT(y!MvACOg`&ZGp=&WCl>y4;F5nZ z`iVu)W#nIN_{72=ApgCFPb_?9eThAgiCFj#k^g=pPb~cJ0+(Hke{jUY{~>U>Uou@DJ`;T*Ch;aJl6Z3;%WCviIO09I@~VVM@8>6APbb1&V%R;g6%d)lV#Zo@G_C z8UNsjg>-|6s)h0im) zq&*S~{{diWkHo_7Lww;+>1fqv+}i%d;BC0IT70X6*>#5RH!?%GRe#!GHqr2B4E`eV zXAS-~@dF0Ggj@B42ET&a1Xd8Z*KoC2%rl6>4{NrX4_y6-!HdcNoWbno!jBrvA`u&S zo=@1?b02W)=Z#DeZe@dDz!6K@*-pwWpIG=4fJ?74^2EX~11`JX@QHqu~<^zY;k782-W4;R=62Lw(LxwZ%GbZ!%%C^49W4oVWjI^kn6&<&Pw98(?DD z%>}v-BxYI|e-o~9%O@88LSRWdaYov|2nL)^`M{)qEo zXP$hp{1NBFt$Fgn^4)xxk7ShGX5uB5d{_otcDvyd3x5T0x#bfJpY=!Tq+6H%p7OR% z5{rB%u+&Ln;rEbl>m;%8b)9@13^-jbPZ+!bw`z;W0hg^bd}0ZE5^%ZY6AQltSf07W z!kCl)^Q zLDJ&p$pZ5E;DsX=dA5C-FAxjA54da%{=pFoe*n1L@`;7d`XhD{3;$}$TRVw`zZF>Q zBo_Xi;Xg{g&3|Iy zA0q!s{DUJF{$XHgN5sN^8Cde4SolSSzC5w;CjpB+#KPwpr82H27XGQQBmA^BN1sDD z;j0GEC;w{(Uq<|OgID2Jeb`_Y=LCzpiN9g^yKxJD)8KCt|GUAzCVs}?5~L;kErVwP zPoN;&MdVu>RsmOAtjEvaF)|!8hgsR-z6;#?J%fJ=JmLEW7b1xf;IdBqgCiFHQs8pSCl>xCz*4V>g+B(k?FaY= z*MuwlLk;y9G5miF9);V{^vNefzT{)bBsgM;i~V!SU54-W)$DIYKCAEjxRH1JUZ$&r zlQ}pyjhjK2-fj5A67NmGCHELUvGAV&7I|XfKLsppgjo12a;e+I!k+=$_9Og*+lFg` z#g712|Cn5JR%+|B8shvW*t6HzLo9k`l5fWY#KLbN-?n99;p?*d2^et9&+u~^s-rEh z3Ir>=*VscW`lkVxTRySyX=UqLM;5N z9X_$}KL{+(8e-w^ro3Gn9 za{PlM7XE9%<(5w@{MUiY*5V%=vG5CFO1b3|3;!fwY0JdIKN+~JTdUD$DGR?0{Bp}D z7XBHOxB7{NUrBk(Cl-E~@+=TIV&T_P-tvis-#~e*hgkScl(&3h;Wq6p6j<_^ zSooJw-u5%Z!tW;kllTWmEc^|?W$QFs5exq+;Bw0+7Cx7y#C~GoUrTvwKe6z4089Ts zEPOuuCj5tqSGUuj8a&tGvv|TkGyJQFe{S$~#J@239^&T>{tWR81|J}11%#vOY8%%p zz^%U|7iTfUp6Ztj=Ce=u1Hj>589v7+B6GBTNEuW}84*j`X8@P=8vVq=KMT0r@`;6C z16S{;E08PE3ouk#KOPJ;S&p=&j{(eh=u=s$`2X+#KLFsOJ77R{8xY_|A~dK`<5%f zfXnJzEWZ%Zi2NvE$$w(uj{}zcCl>yxz!ER9@TUPwA4n|xnZVKq5(_^}d0W23!q`9+s3&dGODz2Pz~z=tEc}I(xB7{N&wfVI>-IU9P`=0LCl>j?r@ZA8 z3x5^mt$t$Ruco}^6AQlwSkgr-eD+I{&&0yN0a*GRV&QY#)%I&+XC-c}zcKh++^SzT zxEZ(be;V9I%!&iog=@lZHB=wOE&Qs%L&X1O@O{L5xWOI975;Ax6;)T;u&)72yc~y1 zycNL0XJ1tPdlQy@sqn{xRn~9##FDNFz~z=tEc{8pWdryJM=X5yz2%lqEPUpPct=U zXtw??LYR#S?rL1&KWeDIhYYkPnBfx(U-xfY4d3nGzVGNE7WwDM|ALVx7XI(Zw|a<$&n6-E5DR}i`E1Z| z#KJ!n^n_x=KLfaJl)*EBt4ABW)WMelhsPNHUBqJz-cLNvVBMBaF!*Ki86h0IfC-jA z3b^EP!zUJd^6|$&rtDVp93iGW@4DVvzSLXtPsUYp(C8-?{cKa=6a9Eg4*1xW5!>80 zsBQa7w)`ZzMmBgnQ90snoGIiv001mehSM?Nw zFDJG#PXM=;8NN}I{%;YvDl{h|CY_C9@%?COnK%p^HcWTNcob_ zJQR6ik*A-?6AM3|Jq%m&w6RC@fMxdDebw;A9`dQPtcfT`pKSSVozZr_-N?K8wVjqP zc2bIYTVnHvSn`c^uk354O%Y4FP6IBtd}86x1TOiyv7cD<)B=|sHhPFfp8bEhGpIGFXM$sebr9PIm=#g>cYE?E;G7Cke7Wlexs z`0pg2gF!fA;V%F#`JUku3!ixsKEv>99L#5Q_^pP|d?@*@kKM4j`phup?emmaMTY!> zU;8=>E;pFvTfjv-INDtBC4*VM1^W%AU%_upyU=?6)8YS@!++WEX@9{hd1QX$$h>N> z*7-Y!|AfKXwtqEP+u+9a-;TVEOY8Z)!?({wt>?>m^!&k*clF%J7)=`~c+$vdJ!c!f z&Z}yJbzYrgFzbIo#9-F>0$TtT#EphOjd-@fGl|bNnEx~K`L#SY-(=)_wiDNP4A%K(+hzsA6nx+Cb-wY(QaGJ&#Ri8dGs@sv;?V{-5RWmK*-u{DBv)oA`%DzK?ja;SUg>Z16_n|6^pXCjODZn~6^`GFyp%Z1~%VPc{4<#LpW3 z&BRj-|5oCk82%l^Wrlwz@pFbhL|kt8dx-zT@b?n`)ZqJwe`fIg#P)-l4-lVj!ahR$ zb0hN@@fn7{pZKi?A0VzU_z>|_gP$gT-h@3&{DQ&H5LX(R?-ExT{6pdwjm)#ezcl!# z#Qe|?-1EfK4StDuhQahJaO?To41WyyGp$Tb|E6^VaU8;mv$V{;OAwA48c;PjS0b)z zR^c7q8XOuBuOZhv$~Vt@qj^qe%b_6G85zNY+C~&5-umL1LHd;r`_>4KKFzi`M}+xL z8OsbWZ&Nyl?$|f9bG|cZPE^ZOVcssuKK>=rsE--;kIu+*3>MzHaZlZ_M|zQ)eF#=& z%)tYuf`{s4N*g>tUC{Q1ln zQP}Kwhk3m{=Lw;iR@=}cIa?@aK<6BSyys#bOF-`&u44)89LaSo!Odw~UUieFzkdQ~ z_W4LhiUuLxc;6f{ttz7<$#Dkk8`5;=lRlYQ|E5boj<5R+U-RC0^~m|gPiA4{Y&mZ{ z`}2J6=S`UweL8cd?{oZ_dO7Kg^Sv3fnOLuN()PE9T>Lz)p^lj7iz?(yvE5 zvhHwPRp&gz?td|>@*ijC_4XOZ1s&a?c6oH*U< zmdHp?<_UM18Ev$>hheyf-5p6bT)fPeW!rxlhguq%eC#l55tI;~{E0pJ9*Rt4a5A&6EqO5q<!{nm*%5>y&Qz+@*00bN^f!dyHyw=Gw98%FLJ}uBRS3XGXFd zkt-`k8ZKwrk1g<<=qtZYBk7Qn37s{RH{@hHP|DeTXvTU7rGsUAyn?*(=8lWahDLHOEnR?%Mjl7J(fHFFIv)||ii!fJea2wy0wNvHY~8*1VM1L@Q%e7FcB(lz{o1b;&w zsVl=qt%;6s1MqlUuj1;*&(=k_^9sr}gC}xV4I{VEk$c}Tau+#r*9;@q>B!wbj2tt8 zznL=~+)|V;9UC2e+-{UlZmXk@+k^7S?QryQ>rg(qI~+M~6UryI$C2X}qI`1P_aNnw z9!8FPA4HB@aP#To{s)n}dKfwGfe^WehLL;Lk$ZR;xtAQdM~9L7J>;Z(xjiahIu!iG zzTLyfaci~6af?zuecXyGa@@X@PmWvZ#6E6q$|o0g^l__GKDj1GAGa*!lWTV5xSc7V z9N(3bba1OvKDp(N9JfK`le^531CAWGIOUUj%#r))FmeYRIc|;0r|)U_ zNj>29sC;s)Ba&Wjg~}(#JQF!?lgcMY9U{lAQu*Y#rBmd%jVhnq@8Kuu7#K#5+xJB7 zrD5c_txn>l4f*2b7B`XOw$yxb+*T&>a+_y9xv(Sm>M(LmPQ2F-BiHQ6@p!p>@y>VR zy?Ge9<&M7p9!74ZqmNr_^Tpfc=-WArT%V)w)?wtXcJy&;ZN7N7I{H|5^2y!o=zDD# zxjP(v+!C8l-yTN}Tle$I-S5Q9t*-g>J>uy5(=c)e9J#~8$Q^d#<<`S|@qX9Q$1S%a zSB~d0)a$cKa8o~ppX-F23MS=3)-xzaKf1T!V*5Ih9Jf3Nr$99^=qmWiaJl*}LLj~;AWro0 zhzD2ha>&gRA>2joN5F2p4`3jB9(auR0_(?ktDsElvjK+?XcGA1MBf<@()ujpW$2p* zA?jO%i+xahMUlkm>s1IR<_TY^jUJuCWbz&^Z8&?(Ar7kx6O zXts<)S1Yv=VX5z3jy`Uara5*ywt5EoR)7{K`nVOFHi*7y?^EhepsB9|m)O@T`oN<* zYqWX)$WXq0?-YI3qvHL3e}5r(qVN5p4|lpI=tEX}&a%~2qR%qI(8n2K1F7Qnqt(qHkM3-~1btx(q_JkH;m#Tig5NfW8&b$LFay(f9p;zP-@b z1|IdT!6o{ti!<}@#S@kKU=DpVA;&PyxaeNOJ0zQ}J|3?p`uYRXSa6<^8hg1E#wb`u;!a z-UPm?>RcP&$w@*cX*eMYiRcMQ7~)CHNy6yRgybN>NRg@5DTE|QG$b(z6ub^#5=sCq ziXb4`)C&}&r4FFhS_{3zPq=8QRj>8hUadpbs>NRIwHEF7JbSHo@0FbshPL|$P(k}&;`ax!r~RIWJ+^b&Yr-b!JqP_0vkN=h?SsA3Bjn#GD46+I zycuhfAu!sz9-G*^TI}hFyn;bSY%>6f-)fKE>(Jx7l;T9MUBcDG(_7WMwhXron}qwQ z$KD46g!`pO@8|&Ge(nkPB_mu6u}-+t(BIklr{nh(>;>R2PSQ~ZJv;w2@geNZffCcf z*Xbo49UgmUrQ+I`7{gxd-QuxVa*t&dz@PU11)JF0=dm{t_HfC~aboW$9(&EO$97J8 zH(?WdUwQ1!gS}CXH8*~L@z{F^_Oi7-3?+`e3Fwc_{JU|0_!UBraVXIdK4REgY1nJ_ z*xL$wk=n;~9($j{-Y^}%cEjEeJ@%f3y(91!C;7L_V=sA|+uwIWS@Q2gkG)MpBiEPT zd+Z&CJ;}fC81^y~`sUx`u!pMaIEmkE(bGOpLoZT$n*lvLpS9jmge&=iF4#%OX&CqH za?^T;U@uZVjfb9TFaBONFZ~q9tuySs;Ia2M?4@Yi+(|kPdhE@FJ*oG6El~3L9*lct z{62-fNcnOFI#pBe3+P447mibAI#wWD$(K8fa7SbOG3~{tMIO&bLeI3f*+|C*!`_=7 zduPGkneZ1U`SQBQ-gAb%jZl_+*^R`R@tX{Lk<$ABNHcz)8}=}iIQH5wKHBzlM5e)B zxkL_oiC+`+Y@lCkiM{td_MU{jX;7j)G-b!$3{)aB ze%oO$Qh!weJu`mR_uTmllJ3}hz+>;w0Qol@Y%Mia~&|^Mt$0p?##JFdscRCj9 zh}0j9hMt+;wr;om?lkOu%VVz=_KM*zPSP>QV{d!6+fVL-vc&IJkG;*XS0cu+7kf8( z>^;}*mPZft#NKX?y;ldY_khRV8-~4y411g>nfW*DjL7Z$uO7W(=*@&3agvTdd&2#^ z+dW_S5tJnzBQTzs;dTsQZy5Bx?@!Rnl|*1K=~(U2 zI}?o~QoVn~qnAB^-fuj5LFh#q7ZQi|&6h&xq3JtL;ui}&Ghb4WFHp7H$CKDgJ_kMa zra%cr=^cagW<%>! zY|mhm^o~M*V%DowFoq%2abhnMdZxWfBmee6TkOr&_6oIyJ7I4<=9uCb7Po7(p4iV0 z^i2ot(Jhd0m1xx>-1C8%j(@`@;oj-7cYeUK&W67@hDrBR(bEB65$N0hiQZcty(Q2? z7wb6Di$#Aztd|Y2RtNf)ucU(uBoUYBaJ#?n*1zY#OFBk-?5&4AvpmG!NRPcIVJ{nY zm@kJ6d$YtIIJ#|t$o4J~d$yKky>8e$3{K*A6ZBYr_0kB|F4)7*aT33WMNj)s&#b4? z1|AnZoiEfg=S^boGw4OZmgF<_%yuq%N1;b7`E1?q=F2a^(~tRiKKe1!-je~WX$M{$ z{pePE^gazl&cAl(nc-#|;l2br67DacXXc-k+4njt_2|Ba%rfIgy-4Xzgq|7hG$Y*q zfE@|_WA5h(SJL~m*wcFJ zVQ(2Q>+|c_#NM}u>wM9AZLr7jUYw*O50e^VsV`@ZRBLB>_2zr@N}wlole!YWE1*X# z^(y{f-S+#2)?+?x5PQIM(_k-B{@pJ2l$sTQy=-8n_jlMNy%iaK(>n+DTJNt9fL>o4fp)4$oZE5Ju}?xM*e+Zgxln?Hx2fV!e1P1&|T}X_Z;l;UKrEyAvVdE z%^rIbvn>mh<0Ku=dh{-XUZi@k-xKaSOs=77hx#h6i=8KDl8}}3yiV{oAoBwvgXNEY5_ zH!69-koLJZ{#I+J5KF6YpkBG+xE@q z%wIKU%CISO_7B^i8TaMT%-D}U-;lV*n$+Dsc8xW57xBHl`JK*jbEaEa-IJqIJ7L-1 zgS1s3Z3)&ntG2{V`+4%u1NW>f?|q_V3-Y}~jv3WyIcd7$qL%9BMfEj-a7#;5%T<9Z za#|+`a%!(?YpHH*t#7MuY7Ep=H;!%#ET{`KE@^0JZfi-jX4PF&-`ZB!;w}SY4P>Xk zYG7e?eM4O>4AxXHX{`&iEpM(vh=J;cmb&WN<$)G$ysp+f2SGO3PAz0}a?jl>UE>uI zG2-3VG*mZU6Ifc;(#rIP3iAu{LxC}s^^MB{Q>qcg*-Z=EzFpl?mv>3o+(0P52>w$F z3MP!TN-u^f`-xO5suVCLCAMX0QDJ>yb3xT&{w?HR4gZ!kz}({MkOLREum;c@C&+Aj z;$o~%{wA1vpWREjjIYlb8~t%H(r~^$JvRN#D{z$A^SRE~=S-3Q>_uGX!%4syS{#Rc zRG%3!^@rL02mNsRYx}Rop5y5}Eo0|6pT*wDbw0aCGG%kbrhWEMuJiRdL!$pk>n?b! zevx{~);9d-651}=zLw5*ih?B$g>>(p;jy^$aq8M(zKTuavJ1o z4S59Q4nrOVd7&XY5Wr_;nj+*ZkBoy2=j$`F@_2OlhV$8@t4sJSbg_o>^|>O#VLVG$oQ5x&8Ge)s5BH)V1W-G&fuMm3##dyQ-?G zb7z#zsrbf>sw!vYv`~b1vnKZM)$Mh_ylZ>mmB^~lL^ss3>V}2|c#0oy1K45mt;5PG zQwpla>3y-@7ux$!mD(3pDZWta6>7eyYJ#m-r1_$%Nm?$_`;ZEtSSu7)jki6DtCT{q zHc+e&EUpUS4Hd+wxN4$R<-D2VCO~JK{i?C}pUhaK50G~%Pv(#?B2ZgBbLsKo5h}ua zv~KJomVs4OWxqL5RkP^2s%w^1x70coPbL}@XD(@7G=*h0>*CpkRaSFLePi3gK1Mm7 z!)9akwWnm+eg#`H5pOk5ZKB?1S7B1&Rn)8S^>0z-A*|12p9A@e z&{*MkKBS?24j<$M9**<(AphVBu$AdSn0-Pz20QM#@mTKJw`6FZSa_Q7b8v0{(j)p^Y8~pEPM)ZP){!GI-{pc zoX?c$Ne#!rGJRor8gT%BaPzPUUSZ&o!2a{`2S+SnG5@755ev`yR+foBxB_fJ9t2m8 zEtq9P`+G8Z*$U6ZE-y!6#v#ZE!mYxVH`<1Fos>2b2THH@{{KdMZ%7hAv7;1O9KXY(bBx9v>PI{(6x>L74WsVUO=s(H_Shu~!Mswxm?H+q6xDd?om-aXp5POHTy+UnZJ`CKaF?S4$8{aYHUhY4!;xOOD z(HBT|BJ874PQBk9L_z~$9VdnvFN1TT($bTd49=R=R@!s0})*`qfTdaU2# z7%ts)&?A=k)gpewATxfP9!dP}^w_%$_84z*V(&JOJwCThTiiIU5_^ZVJ(dAoE$mHJ z(EevSxcy4&iPwG5Go7UOE$G3kS^TJ1DFXJQ$30XX_aXG=BT}4VvCJ7imZSH6Mn%!NwU0K0Tk5z}|T6pf-AqU?Kzd7~t&Zw!vr5(K7 zxxVh(k%a5%9beWA*?YS8n*XI!W46h?fvmuJQCTDJv9jVXj!Nnr9+R{-A*yD5LY!|$ zqLr2Xpyk*Zu{VYHL|*H3kGMSER8;aAcyl&c&_~q@V#YcAec1*Y0 zX@As%2;(Q#1KlgjeLEAa_$edyCx^4f>^W9hnl)uh7z7{UPY9o{RP*8krH_+XUnfM#5$h_Clx`loVPitn{*{MTxp)1OASn_89!nwslcs_k1|`WDr~ zrj~$vdF>nGooLOjURq~*40!virm1mZ{WXDaS2woFeXjwHmd>1c;}zcwm(D7kQW*|Z zoO_iKcAym@;!a#cLtV>c+$?LYzo8EM!~p|tY%-FATUR)?W>H;jW@e&QX2;1%&77uL zOB$`?2HvuyG0RDLJkL@t$v!WcA|m`hh5sx==KJ$g4LJt$Irp3=$vO=( z&%KmOveF>W7ZLXONufIpneWeMJM!18b0JSLyTZSW^qjheHjmQsx=ex zLPsIhx(xE|hCClK>!5O}7S~pIMnoLXbAy)**?|BjzUPe0F&yu4O5XEcq965V8SIPW zTzZX1zQZGL^~m4z$Z}7R^V^Y_)&9}r|7VXJYjimbe~3qxdxnf7{c}A2<2~|pEmPNz z{^tfQ@3G}1>o*?#{{xZ8leq=jf89>|!#C#0HNba}W?g(rUqW*4 zit?6hK5u{8fVV3n-<|CjwZei(<2yh9p-k~ss%?|^Tu;_!VdQbzw#xgr>OO6OzE2BT z-Iy(?(l=lW^bJ-J>dq^G-0Ka=&EG<~8ys?uR`+vZPm~MQ4O}n`a{8Q#BCaWjJGMpo zmTr-bgL^MnnRo9MD+@*VK9xRjqTcI!zwl9^73*Zl-Qsa}5D0U;4s*O#7_Y+~ufra% zZ#R$Ex0}b~Hgo^Gu!}L7YpSs@_iU|et7^3t;{K;|dsW|i{yWxIbuWp}E~>Ini)yhr z9+oTqCZ?d_hB|vuJuQ~=i)r=^UECsWvC10is#~bmC$jqPuD;ehx8f2z+F|!zulb!X z)ucibDq3f%>EbtW++m@rI$gSS~`h`Umt>swNa5-vOBj%XS)btb^6;oTYxY-Hm z@5;TV=BX`B$SOC&eeO-`Tew9taH6oZu5>|tLw(zF&oaPH1SUBCWsC5HS>5c0`kK0M zTcppRwJpF=^2EV7ecUCjWexRM1<_;QSPU1Ls+N@w^*g3;c3X8zo3<35d2um|Hd4?G zc|a@U=hU?kdy=CZo>>zyBz4{D zyeX>J=WxKeCLL$b=WCu=_%nh1W%z?57QO)3UrttC9~GYSDSz0e?YWikR2BQg!p{Vj zd%wiObKWHPeu;&@jQSj`;E09iye&iX#KPAC`}HJ^Son3o5+7pWyMg@|;Sa7GoA8|1 zNj?w@&-s$%1F`T&$WOx`9I^1cF7D?^0UWXLx#XuSo>=%2@;W}m!t?rgIxp105ev^b zeTL?Vg`WrPzgX!L3(xto(HsB1+6AQnL`a1uKg};&dnkN>%16az1 zSorniD^)y+h2KhE*DGS-w;MdM@H}rxy+qj|7Jd|{V7lTb66{9s-to`-zbKGi=&E^Of|nDx~X^24dlP?wX-_V&Mb8>0|K+ z7r-Vwqm`j~V&U6>{g>hoj#&5(U@1pp;kT04`ozMsO-cC@3(s_w<>C(xw|1=Zb8Kjz zx8?;EF2^pIr!f13vV4VW4StbEMqeZD9>i!(#>#KJS1 z(uXR2V&R#j49yb@&vqeglUR5*o1hi~z~#mGgBym;KgWhP7X4&UW%@ZOR{fyHuWIU3t-SwCB6 zw`I*oLnm{xI*?fO?Y7JdZ*X>7*7|I}ndjTIYReMVKlrRuzjIan8B*s}lW#Pi;*3Ai z1QDNz?*A~+-*qY=PrmX*%K3`RKwt8Rc+L|cCjX14Kc2^b^r=d}T>qz?Zk=4}2D~2e zPbww%gzeb|)JI_c*B-1w6J3CYtEaMdgDu8?GPX0ZamvlM z%+0G;0#5X1YaQxwD#^Yh4jWyi+ByI1Kj<>CQIGuwomY>3bfdAwV>^)^ry$;Nd5u+^ zgc}6Gc$R37Y`xbBEd-^~=yTZH?C-!!Mu z8J&kZN3FUWc7MMDbG^wcx65})@1RoWiLK=abJwKCS_zU*Jzau) zJMgY|TB7AUJ=ba<)f+#f^VUtiG(0zzcC9riXN~o%C9y|l|2g)^=)j(1qemXVQ&KU< z-2C^=J%p!wDh56F!47MbQ!2S@#d`bbu0b1;y5e5xyn5BnRZ$lSf5HCTbsHv+z%j2G zPjb!Z{GDT?W=mqstj=@lx-%PczTZ6oxz+c*^FYe*UH#cNQY3_%=C0i3>rJv^yC%KA zVO558$F7xOyr1s8Pd?;%ya^tcT5(f1TfBleo-;o%&RyI1%ZcW>^B7Opzn{QN-l@&a2>>X8B;od<@o*z4P zr<3}guAa3u-%S{dG8-)Ra@Pp*&7E#7-_kw`PqyKW_V$elmT%Kot9|FQ@v~5RZaMU< z$+BXw!a(`4OQx<2J4feq4a&-&^Vjyy<%q-fFS4vX$FfG=g_7-xOT{yAj^4%!D=U5b zF<)oBm6c>aANN-`O{M!?T+ypyWWQhEyWD!PvnP6#QLZ&>lH%KY*ILUXl;crB!JXHKHI*j`HOsqAZa^8^4@$L3iKUkZ{ng4KJcL zgt}ermE}f#4|g1k?HbdXQOrg>NB>^?P#5Q?AAHYsYSlDH5N5YrpL?Z z7F_fPvjz9`X~C(X4fi8r4id3n>^CEdPoGF$VT8{*Ei?m+pqXD7tFb^Wyc4;)V2JKW0o zs6D$P&X@Lq^JL(qCpLNsLVyJJrpzo{pZb znl%Y2KD40J)6*>1hni^1XrrmIE8H65jC!j}oIU_Ocvj%9W20C{U}r;YN#bKMd(j#t z7CmcMhTRdBI$7CszP$eVsOhQ6YvX>~;d>diE$8AvMIY_37P?2>CdaprUOVUm)P;AA z-n_auw`*bN$3|V?6O5xUcFR$|XO~;CiCu{sI?5B@YC81!Pb0KnEByiV1a7K(x>lCI zwKd`6{yo7P>9O5zo9ypDGeg3?X>Q=YsHyF_F~{bit_pj#gM7K=$7+(1;_wmS2{Gp}`Onp-w*n!b-Z*U$d5^;X|H=RO_l9*O5$@0)htij*fXLG|s7u~2Wa z4;*8C%U_3n=gic&`O)qu+k@x5YoZd)OpV=lnxw=WXAVZSr@bHbV9wrvTfcqb1Z%^R z&n%Z|pZh?RA%%wDAeLFWfXJL!tKE(8@=S+CJfBiaomK@uKev`AHDAei-T04WtN(G$nR1+4w{Dud z5p$>Z?TLNb!NvpZZO6XTzI{4++XUx1cJ{Uv(P_r`Iifp)&eXBdx-Q45{?iRFD$Mw` z?}$Mk+HtG~edw6`BvvKctYI&sw`ni$9fZ7a`ogPvd)B7@WGHI;gV(MPU>tQu4tJ*8 zzVTwbWx%=8byoYPwU+Ph2d(ze;RMX??rz6S(QQM%XV1a;K~j{#bSA{M@A!8swJyiX zTKzyw)>23{7d*1hQQUc-^JK}jG^syNAHYPba!ZnVhx2TAl-udFH=(|Ut zcar(+*j>i4eP+UL?})x+TM1TZ>U|#P6X-#f??-!ZLdady)A5&mn4u1rxVw41F5p^U zU$6mZdam5QF&kx2Zshj|f%cc{V{5v0SXuWx5aVk4Hg;fkyWO6#aF%2EARR}_vHn%! zPs1}hS5A$-n{)fj=WAjTq@|>GE*L2b9M>&)tJrrJOk49u3bsv$9`0wjr+L7}C}`!#N8N;XErLKIdS~ z*H|*IMX_Y|Mrao+f;rvSPjzF@l6fS;oN#8I#39t}=FClV+jEjQ=lZhdj^4Ok_dFC} zII6r3MfEMO*j}IAR@`?-%(Cf9P-TNN0H>|E;Y5Y2opU*FNz|;v+)kGTMp{4nYBxPB zjhdA)ezcb)Nr71&CA{{8`ZwCBPwBPQMfm{=-J-r_wH!E(`XB5 zPg(ap5Z}JhY*XzUYmF9mXZEk{b|N90WqhRkM40O}7f76sSKjLi-11J0j$Gc`ow=G>-W7=_ zTizx2TEpIS&f%_qzS=m4=~;uh`*#zPF^_UuygQGwXXiNkw9nEvRbb?)w?`hFi{9P7 z6*&EV)v{JJ>b0uwpzoUz-3q8PONT-l?%Ur zQ1yS4o=2UEl{ocuYddQCZzA+fN5+fBO>=+jxx#ST!PSAaaj{XSy~8UFN6PWG zp%eD-UF1?%9l-gT%bLATJNt%F484R8QK! zGMttCRQ&$%ew?MaSKM=Y`&&I4R~n%Xu857@<)(ZT<`(YT#pCw(w_?Rf*iqr`t*Nnz zQK@nD(Hml|_ziKEb4_<_gd^tvbE23G$FS#viOi#Qo zrzJ$$a}sg zLYZ#BM`yAIUoj}};L7r->Asw#_!phHehb$-FOEwo#W)t#JR^FONMoZ4=21$DpL_7j zxi#w&lYPCPCSLWs<_mAv!q zK#d4K80UNT*NLuGw30Qx-d`t{_O2{{EO9H&*%Ga!*J6{;iTz33%u>8(yySH2@{L`1 zKl#y(zMY@_?GXC1q_4&PjmLDxtiI!|clR87q}$Dh{%P9h+yy|-c2E1WiB^A|lCMcD z-Tu?HiTZF4`?ui-lZM7drFMSyx7ByxZR!27(eT;4;hh{SHk@?(XVK69%TSmU@$QxHkNK$KBUht) zb2+YqKiY*+YK?uD3U^W1I~I*!kA5g?%=TlQ@ApqjO0J|Os=|jO+Ht+T=FGiAr*~%G zJATdTk+Bs?32D(u*0`v}pV;@Ha4n{2pnFib7PA4@n_l$XgTg&A)vPi{X{{e&-k z2v=gqS#E!LX>U)5FD)0>IP@Mmy?KxJs(Rcb9>!!4<)3+aMpL)nD>g=U- zhFVo%MyGql)$Px7p5TnXJtsDi_m|eD#wPei9m1S_CEkWNeUegoljzfTmj2P+{<*gP zocH&7N4>-dcc~uEo#l)`;k}a6yqC>VFMJZ;x#a5F*?b#3kh3H|(NeGHls4AR0zYNR!T}A+ zn>_Yw>6z+% zeRL?5LuaN^slcL&14dfCGZnyV`EFbWeg~eJ6j<0=S9e{Yzz!MjzYna97qM!Zmsho_ z2sc(Q#<5u0@}!Tbt!u4msc&}H4>-<&3!4M=t+Jdp^yW6#;sqOK!hk7XVyo!PWF2s_ zZ=k%NS>1xAtL@xhgo3MU(V5Tpw-yI9g+!kymA0Lh2!{HWqOHaxOtS+UFd;S7&DH9y zDb%(=V^dq8bxCt`Qw#QO$ONneew>U$kgZ6FohYL|+0b4`9IFi=XOC;cOb>&^+UNC) zu^6t-9=p=?DIIkHlZH2{pkA@~ngLVS(1a#ZzxW!Jsj8Xgw4%1QR@6?;SvGL(>l3TG z>zC9u*3_MRyz~Lbiy7;3U2UMPDNtRD^&|8V$H{B=07+CUwB5{@)x`2TUXW&*npDF$ z*_{4{txn@^faUeq)VEbP94|zPshRx&C;tO10M}k+^@6$vLoRKpQPe;!s<}_Q!%LJi zTbiyx(YDUPYOsc(DNW17$6#ST0z0q1wyw$0!V7;j*BSD~)eUv^wN0%xO$cJ3h`B{2 zi{~TJ7z|ivr_?v9B+Hu3c-UwFC+{})IV@}`y0EYhUD1g3{})!{b;bdVk^cYa8Xjdv zl>4u%&!_fWck1ix^9eK8MOu?Xo`o9)wP<_g3{#&^FS?FvbeN87a+vPKYZ&O4!1O`= z*U8T`&EXloERUSyk@-Zg>wK1eNk~&Z>m1h;$mguGu4td7UsQ7R`Q)$be9jvWiu3i$ zp9!uqkk8_id#>~K`SKP0`81#FeAd^U=YVej9SwP|_GY<6*-t;3`la@Bpk(+=WR$U* z1vy_oxy-sn>y}_o{ngl)W8*WDl%L0*Ve%PL%CBJm9c)Ef{x9sG!p4}>|2^#g2ODb! zWj-gIh>fpyQN9Ftq9OC$NWO0;_N#z5V`ENHe-ZF6v5nF4^}v6@#^)sIe+Hk0#U{sR z0`qz2Y1;oB;G401UCZNue~OLIi}HA`iSax(iT|y@i9VGF^j`;g2ILB@zX|f)kcVpd zH;^BMEb;w4WUec5vG)H2^0_DsJTh&EHyM6m$gD}U&u5UALYDktSlc0s{f&^Hge>86 zt-C19^2PsM$Xr)~Esyr{p_>btugXxK2)Pcjr1xJSFM%xOvmf$m$ZX%#|98l{4gCv% zpTQ>a=Nc6+8S*cHKfosT{dhL_3qzg@IT0Is0@^p7&kCC&>gQCCe33`4u)YUdnb->8 zLwgSZUy4oQXCC0QOTlG)_~OOnL0Hq!p^~gAklkm%ldS2GXBhsoAYW<7mqQLX@@dur z$ZtFH5bIjVUl?)=$N`qsn+ixyYWr6K7c&k(Eo49^9}hJ z~kllALQmx65dkp_F$a@T# z>qWk8$a5ic%_rs3tg9fOX~=bu3k-QN@dmwik@?((sp0?O~8uB4S?uGoZA-@3m4MYA9$d!it24wkm2;=iU zWVimEVSNHQ+tEM6`U_R-AQ!#H1w|XGIYsim6o@(g-1hSjI!>xaV zJlKiPaO*H+x4sRxUWV+(cewRi$a4(+-$Qom+i>fTkokU#a>K39A)jf;QHhonFyutY z2MjqCa)%+G33sH8adpX-$2YIq#ZxduU zy=Pn9klprsw$%gK&A+p)J&@h;In(+nWOsbZw4Q}L$FZMj{Q`1}A^#fkIzxU7vfH0$ zS|35)WcdFNWOsbew4(6#$ap9HnN}iXuH&IxrZp7udxm@#yLLEav|g+hI~F` zx4+7?rb52i@Sh3!B?%7aSKosCfgvw|{FNbJ2l*`L_$+G)&KAi8T$VQxx?eBA}Ga$cb_-8_P^Ebyj2eMoLbF6WY-TWABT?l!y zbNp!QBFJw3kG3v_Txs}U4%yA$(N-dU#-aL9*^U^P6+6Jjinl z|M8HocI1%tb;xaoJPqk-qmW-R{GW#Gw%;P_S;%gEEV6z9x!lnI zHRRof{1)WT4f!L;+YR}DAa6G0D7>)ysv##qcKhohD-CkGlm2nmS&&aR-j z=%YWungn^Mqd&=-0(qn%UkrJsBcEr@f$a9D=UG=ne#-D)1lb*L&$C(}ml*#40=dyi z&v{lSe>>0mSIFZHdk;Z&$Aj~%$04sUj^79QLPP%`t zTEEruYFo~-ua!_g(Ux*=I>n|d8m4I(|(#qzRDwad*okuDz|THfHVv)7=)-A;p9WK~^M`Hd;1STMPD$%3kisy_EZ?Iolgn}vn5=akN=D65)T zI%{@#R@J=HSyeMiFA2*>Z?W32z5X&+JC3~ma#0`aq4C~ldcrd&R#kkXYHCGg_*${n zXQ^o0J{K`QDf<)qKY(L|V1L7R9AjiWpd)F?=ioXT!A%VLm+DwRku{NwN%%)wN})GQDUL0N%q3T z)oo2JWWwGg*qJ&H&mdjY(zHaaGuF3^CA#)9(00V_#j6!!_MTK4#@RR9nO*8R7$X`^ z09*oFnPnL%H1KNNp4u?UeSpDv93@g9PJ!5~X`f8o3qyu!_lc57#+|Yaopj+E@phgZ ziD0^r%XyznY(s`Y=V_6?22aLJVS$@y_W_f>cI*77T383{=Slh+J1G+r z-AKt(DSfS|D4l$*^gOI$7*pTqo?B7604=P##(Abit;DC=z5A348~(|pz^qHg<1j|J ze}^IC37S(kWEPA4(9J()!hTNY)J+r?x+QBq+SAvPD%}AW{Vxo$So%HKQ&#xT=rysV z;=qsksIRrFh4Tyas`u`y|7xXu`D(lSRd!iuU%t+6_p4m8Kg0@5pcec$*5nU4i}E`M zsYUsrBMbW5T?LO;y6(r^MOKI6qwew*cpV-XS>azBGd}#TzE6O)|DA(`vHQ9y_%^)$ zJ^_G)RH$^u=>`AC=>(0_Q5z>w01!m}J2KiQZyi8Y#UG6N!~qx;9vBrl z05NBO4}pj4uNc5fW&3y?hw(a~@uC5stN^I&08jg9`H1)KVki;z{ zal^FF?m|MG6go)94V;b}kV-lAblgG`H&8lm=(?PcByR9^f{?gD&pATkR;VjNs8AwV zD3L65!UWO>0_mU%B?*NRA^7Qd1L-UR(y0Q{X#vtvlfE`oB(ab_6^x@JDVH7-emV|L z&kIVz0a7)KoQ_4Y{=!M9Sl2@UNs;uwq_kNeo!LOz7?6%WkWMC$E!umQ2#+ zUMLL*KxI9Ejuw%M1d*~yhIzK)Uw=DslqTT^oI! zV0FJoPV0qqu@*|>0MG$Q?JO+PnGK*LR;=@)5Tm9;=}ZJC@t4X&N+%dd#~Mh-3rHtU zKEOk}sz``*ROPEYg&0fhngUSFGy8!~8&RzN&KkWZjb()u<&8LXytsznl4+=Ggu%vd zU(1j5;N1}Wvn9$r@}b;6XZ5NUer%@LM2}7_(o%0MdKw)8rte-)wPDN{bydFSWs`-uPM3l z4b82vqhY5KCvUS`YEUaNH=ktFd`T+oXqz7>!gZ4Bn(L}+7F}1xw*nlU&?GxY-P3v} zPt^ygsQ8bxoN8R^x_I`us^bS3DlV<9ovkCmY*gPzD-^14x+2CoRAisa+OL!0RS>&U z)Hcj?Ki8z{j&qH{NoU`>)yF?n44aCXS--TYO+~9ueLA_LQDa-$!bT&p>v7+(kXRj7 zxUtsO4UNYq+m_a~v=#D;Tzr`%WM6RmMnkO-ZnoMMoeLgD>Kd!P?Wd1ch~X-R8Skx3 z_~_T=wbf=ePGp5~FNqi-=_VdQArwL&r49AhG|p^l z`#M&?8ZcpQh3$dQIMlUO);HEo!CRTvUD8xrXJnWtO@Pi+epn5ItDFDg+oui`7R{}g zQ@5h$2^v(K)+M4Q?T6-jS%DV3X zj1cwv>WpWtmuqhQQXDG4g);q`*hxm&jjwTR9kzu=N7XOgCy}51j)|P5_Q+#g1ni%ym;!h&KZe+* z%Bq{$8?s-RAlS`=NJp_yreFZP1{e7oYiGADM=}>JbC0p(f=rM%@%qOFgK1fPOHD(a zsDzj*RRrkN>iK?epQ7l007oc$Bv9FG6kC5?c9<9k`e_c7ID8(jZlJ{3_1nI-**{rq zX!UJ%vzOQ}?a@EPywY-6Q$thBb#=>CPE#lU+0%kX3ER&9&5}6dnmDonYxzxrdl(f5m9fuWu>yGsQqRb{ECj5 z+ukD!*%aLBeNjtwEx&!Kr-=A~Pa{50>ac3Wvg<9sENM>z=2S#XEi3Yz*(dZG_^LM! z*Orf~Gj9eiRaMn2TZZ@Bmxgeeq6+W7wzgLB#q_FrJ!8iSlBva0#n$>riV@@6=OoB; z23F1!BrB2kyf4L#eK_JG8>w%f_-84;*x=^?r_NS9vFI-Z_UnhTiG?2uTs9AXaD2X? z{F^qk-*pRKrZAt|$orPUyl3y%4-*rccKqK|;nJq?`M~M3@CQdMd?9d#=81(L51c+5 ze{jUYPX^A=JhAZQz<&L(AhGa#WFmMu{@`M;rC%Q9eE)?yj61gs%}ZLiAB8Rb3Y8XO zvB_s{Gc->uJma5!rPBANB}4OOS}vsiRZ5>&>`Vd9&^)p5)2V;8(kB*v2K6;hEIf-d zoiB;P5ev`k$k05o@C$&`=PP|;;aN{IG;h|KM(S59ePYpXp}yvcg};IN`hj&~;cuqC z=81)0Mg1COpIG=c)Ym+*@OM(555K?>3%?0CL-WMK-v^vtr}T-1zn}V=ClMjPM(Gm^&$@NK=B2)YvcE~=*DpA*-ikh-$MV-JJH*0|C$C@FAQrxj z{B=s7Sa{}@zd`Y4zTHKBvEqqE{~_}Ffm~wYe@?zh=@Se80{Lde6AS+~aQY@a%SlCl;PXF7<&}_#1%J&$G?g@BImXGx!Y66AOPU z^>zLb3%`o`nkN?Ceoj{RnZ&|x1(tXc3(sfKQ~9th9I^0xRx5agP22Bd1g}(h5BaMU zeg(Ufs}=qoc6n6_e@;AK;bE|uSFLaWIJiLJQRHhB9#6hjVLq3eSEn$mT^TzkxckXp zqcGduskFfW^ra0FOB##G>o!O%{DtIO5g;6~@QjMIHDcj!1Ws*J`ozL-r~VSf6AN#* zwWW&h*VewRc(bj2Ogp-55{n%Rs_Ey0paT{@1~^0W#KOl@{{p2>EPOKcHBT&jI?Rhz7+CrZV&NxJU)v`Z{(S0d zo>=&DU};~(!Y?GR+ZVC$E6Cr3KR9CHyMbklCKi4>u#C~f!n3YQJc)&Wi26F7#KJ!g zEb$~3ejj<=-id{Ok-Uy4vG7L?ePZFi0G57$Sa_~;ApHQb@OD4&Z95z6ejsI;!ui;x zELZrq*acbH;f`TT`4=17@6P3M(1YU`k$02ALEw~|6=t8DcZ{igj#zjm&wq>JiG^p|m-&F%51eXyf06c?F>u6U|7~Dt@5I8hjmz}`v%L?7iS$x< z!V!zU-F`JsEd1%f=~I+GvG6S449yb@KL%LxnOJzc{p$AKul;J?Y`-NqR>CC~J8a7m zuGy|vu$?JZJSol}S>-J78{1?E|FA)p>6|nS6#KN;JNVBf<=W zBNjd#Sn`=z_-unG7M|-*N&Jb0=eitXhgkTl4W3x|7{+6@9Uc4Kk(4flv&r*h7mlYu zDQj(Lzn30lgM)hwTktj;TJcCy+3gA^1Lu8L;gQ7a73R2;a)-i|2EUp7or>=!zd_+$ zz`?r|-c5d^!UxE2QutZoyA?i6yjkJ5slP>G_S<=y4=%zTG=e}nuY#S;sE6j=ILV&OjpmOhqP_|K_dW(RA(4=?;N>T8}@_!zVW z>0^n74**NMAQpZMaC*72Pb@s!REFk>g)gAK4wqQ?V(M$2SorgSB|gN$^PAz)rx6Q( zIeFc;6ARx)Uia<9!f!TsV&NYrujhos!tVo?d>|J70IlzUXZ z+4H?^3h%@&c(1~*65prr=fvMrI2Yv=>{fUy@%I(p4P1V|!bgBp{#D^uf%CR2{2}=r z3MV5zc?=M4C~)ux3UjQ<+okYK;s+F7K%E|iYl$CJnD3MaA5!>M>ixm;Pf#5;E081KbfI3(W8`&PAQql;PXBt959a*S?qhWuG5gpV)W1XN6N?@D{7$zK^ZYIbVFiDL zKe%Dog3MI7ZfwCvh;UsITM7ppI97|i$82b?xsu1shWi*>%3d2Gp{CmJsZ;6HH_%7j^WBpO;>u`xh|8roex5UDyBMYS75({5IezVFSV&O~3 z>v~HpJco1t7W}~x3(x74^zFpL$3QRml&x+h6aPfvvxu4TaMxlh`>72rc5T6D6yA+p z%Fh(0iM)LZA0gha@b9n-{#@Z?gq!kj3J(R&V?n{O-35CU4idA&fV+}9|3_g?3j{OH zG9D32TH=9aJR%l;B(Rhgzt7Solivy3P{|zm&Z0lZl1D z6RJ>>6KJhAZm z$m{k+EIhMP+843#Zx}qW@XT{*cf`Vv0hV@0EIi9X+8wd*>~GVj!!VrL_p-b)G*2x0 z<-n59#KO-3mUc%h{AIw>?udnFzbD}m3qPOwI$UDmSx=r2JapLh@`taGaY3|5IW1 z3BlJD=9rlB8-+&!=lxdU^NIgU;hEHVL*ZufZz{}717#eD;5fxec}rn-@p*46ybCz^ zj>0dHe^=pmiGQ!~Q0%09i6vcQ$m@1QEIiZY|5q4*BNqNjVE=Z-6ARx!euv_Tg};@2 zgW`#WUq@b_rxOcrx4TBAZ?-%3V{)EOEc!nuzfvzzK1`! z!PtWD+t3PNm-2za4`CPlgTjZ%f2c5rpS+J0rinaeJlq%9QvPT|dkw?jQH666Zr&#f zb1V-2N#W__|65`9MR}hp%($J(-0UpqOC2DVG|nLZ0~m%Q7Jfdk)JbCDYk{Rs5(~cw zIK2{oaKyql0B2~PSoj-&B|gN$uLhPnNi6(2V5yVD!mp>kwofelUDVe+vGCh~rL2jC z-%VcENn+tyrhax>aKysD0qlQ3@x;QjT1Xux7M{f>V*#=7Y+urcn{ADKczqwqZJQa)GsYV7j;T}N z!6v+2hqVq5EBhNY)LN5Lc0(acTC#zq&JYVf23YD0vG76aUxGh4V&MybGc->u{Dr_0 zF0t@4$?LKs7XE7Tdb}VOei8W|Rd&R}-%MWj|HQ(tCa?Q{V&S{V>;9iu_(#d>>$Jqe zKSTaO6)v&xhsi&rcw*sSBmYCi6ARC-LFyQ>@LvH-+aVVIxc#}#=YIXU<`WUT*zp5P z+aVU-p1+kNK)8PMH_aCt`V)br+=;~w=NMA%#KKPnmT-xMk3o1r3k2L?;wXjBBxa)F zMqtm1bOGc(|_u?r4T*zTX>6`p}zUV_5$(35ACi5WNUld;LO z%EZDmZt|QDv809VD9Fr)i^JyM?PAgKlV7HIV&Qpg`e^*YneCDNMuz5zMW5lOkHH_D z8HWJm49ydZeh^slpICV2r?f9(;ir>-SjCfA_{+%ac`UK;^MTWI@dq~_oA9;38JZ^+ zei5+5pIGg)Iu3%`{5WAO(^Ec^|?8JZ^+{$^mYPb@s=gkqmq_;tXNKg7bbjDkrj zAButVk`*o?f11LxfXfCe+(wF44Pj#&6c;0(y&&W7X4x57pZzeEc_Jmy00J>o_(*B zFR}2mfTetig`Y=#9ZzE6FQ>ldiG}wg{=pOwaAUCL4N-V9aFBx@+)UzBg%=SIRhWH6 zUYf#p5$j`jQ|ENWzejwA!VD&liG~Yc7aXqe81m@~FCf--*bm6F$HWq6#?!x7A8YXE z1E&|`4~|&$OMo*pPb_>naC#yB;E08v2ArXJV&Rz&Qr5)6Uk#id!XF&5@C$%5G*2x2 zLSPA(Sa|ji60X@-v{7Fx5sUsZ>T7{m_#3IO<4-L73ShBMEc|LtaDLfch>Nc_1ITKj=SYqJ=z|zMO3!e=veJru?CFJ$Imsog?W$EMa z2j?BvGBnS+D*7DD(#KO9&p2Tdeid+r=81)04=invSopiBulrtN;WtxX+aVTy8}&6$ zEc`BDY5T;&KTclvvBbjf1C~CPSoj0L(#H}D{~WNyhgkT-)YtJL7XDRWi4U>xZv&@K zz#km3@b3Xh39n%i4U>xoB~R|5exq$u*8#C_@{v-p2WiMqrQ$O zvG50|uX$qO4+BfS5exr1aQZ|$`WCV9Zvba#o>=&|sjux53;!PVHBT)3QD6y|Sokl< z>#>Yj_?T#yCw6#5F?co<;Z7$GC|pdOsqi%7kqWbK3}z|Z2%M6w@KW+Q3NHiB)BNqk zqZGg0z|T;BwBlbf_-Igh9F*WV1O~?{d?xu^g&CFLISL2K>#(K}>#!D4hn{fF#CZze zh+R1=EZptn&sBIE`2vM^VOJJX_#y1_^szBGCdf(+7l*C9NMS!QPdecO*aT+-=V={c zxmQjs`JV_}HclNo)WGS6KC!7EWCNl3*QJV*F%VfXI+x(A;iLSERgFV z=D2V_dEIXli~hsppHO*4Ec^lTtSoTE!t=D;&kh5QSojq3x_uD~KZE@J_=6)B{xV?c ze~5*@5?J~lV&UggU*{*W@U_&}JhAXAs9$ae+vgpG4(e;3SoBv@U)v!TejW8SPb~Z< zU@1pp;k$w5S|YLV0YoJ@5d<8~l}%E39&kB3c(}`n&r_Ilw&3{+ZzjG#;U|IfG|%xd zc%kBlVJAGBdimEC&t{odqA+*m`q+8oHEtj-RXV(P7G#G3cLVt{h3_LSS9mb|{di!h^TfiZ0L$ErSa|jWGB+a@p7S^VOcghCE;ok!EX5OxKBuAn zZz-Nw_{qTOZ1ix%!e0oSp?PBArvdxtDm%o&UrBzM;)#W?1(x&@3*Q1Pb%t1Y){S6T z*=YbSo2oGLFzUw&#}n^SIGOkng_&T6R)9LioG`viU@YBq zYDUbg=)e5?2@_%--hb)$6CQq2%f6q`ioK-IiQ7>*SNA!w+KIj^a>D3@{=N@~oY?OF z>+gV^IEKgl%18ghPvJW=k;=_jI4<(Ca3?w_(#mg zpDA1$%ew~Dz^lHQ(LK?pc=B7-$lJtWm}7J(AIk^ZF=$cTaTco0cU1;jGpfJJ!0SSJ zgFWFwQUe^|87uJ}4m&;djrDC+)h#X6%dLDaL5u~nto+8Nwz~X_X3WiNUYV{pdrZ-9ZFSkg?Ey!7r)fXh~+IzJYWrED4J=R~b$44A_IIq{x-4C4)BiQ3Cp z-%;20&M@pv^Vo~W#h}+B*emncD_Mf?oFXku?{LH3I*+~Ip^#b_VeQ29cRcpC-{6)n z+m7VlzkBS>!HMC~^ordx>^Y3j`rZo}l#Y4}`zoWOnh^{YZ z8}?>->@}h?9gSe`60f~mEo+&!muc9$+hgx)R3=_`5r-t%?oN-rMQEtm+FlkkB>!IV z*n1Zzy@?U*{nBG^T^GK4tMf0%u$KnIJY4GEQB+QSiNTJS#4iPUX8y&mLwnWnV_zom zyTW6S->=NJEvY}THxGI|rbPP<{jT~hG|QKdNzjk|!L0yh{Ayt@9lSWPcaz87BG@Z{ z67BI32C?^m$KK7bw^fW`FZQ;3>}`g(m z+B?^;hGSXnBH;N#9p=7(+5t4y`UJwUhG{d z_B3$>_6p!ndlRsUy-gl_EwGmje{o{(4v#(SUf13vD2u&AVow{`1be$8ly9%t(|QH4 zH%GUR^9*|v(ZAdIrz3LVS?b=uKFmpP5%d^`60O(K?Z)o{!`^bSrwuHGJ#@W}lk~QU zJ?*on8+nI_F#o=eP14&9J#$|22J9Khb?{CdF0U)nQSTb$fjAz+?J2D%@tBrleqUUL z%VYL>;umwjTVKlHFY)`0$KHI{LlbtK6IUdHnCn*1eH(fK8>v6h3wiW5Lyzef$8hO_ zAkFe9LHy9v?fkn4dx_ryvB!hpx?zv)P@LGiO6+Nm%U~}XnB`G{P3*0K9u$GV(fHz`V6bTX`0?^vIDULd$%J5V z@`O_O&@D;(MtIiLgaiqR$MP5Vco@$lOdOa7o+Ggp=b{8@jUm*zm%4AeN-6bY{+Q}l z?co_wbgAkO>rub1zaMHxn_rFCpBL@g?)j|x4edMpQI!|HVAS4y8OiA>8^W@m6PDkv zxOc`zzuN7F=!Fn|c;60{en$I!?RU40+kCfck$PxQ`OW1|Me{a3xpBrf*YCLMn_WA8 zd-ExmsKipt5Pf-RDkuNIvB+lsushrG+jBxmZ|CG=8iBN;XO}my-Pod%tt#qQTR=JQ{JxH#O-U zgz`?u+F{Cn)!4fGf+OD0xvK5m*k)9vM6OOt^M#Y%*-+^l%RMqx>*;Op_&1EbcyBPn zKlGhD>h}gazLc%T4%(jbQuKnJuzI>YV_l~5Z@6PwPcZVGWxkA(VJhlReR9sm$c+P& zZx}gzROE)&60gjR`u)kPKDd2P2 z)Mb}!M-=Hyej$nZEotqYZyPE{bhVBil)#kx+eh^Ha@*b!OJ8o9YR#?uD3ZAsbtt#y zXE%!vYhzLSoo&KL^b9KhZTar#jE(EJqc&_WyG0Ejaxj0hZ)P}U;FN(W3E|)^uy2nf z3{3I$q^b>-t#?!@Cy%<@nFGwD=m>SkO8oyUTir2eN6Kq)@@So#M~gN_P92mKn@8X6 ziewB*^6k=j^lbDZH;+!~K^}G1e%O&TLye8rratM`H(z*0${o?2DLK1y6a4<1#O{<4 zT{(L~34Ww`-%TooEu%{zQWG|n4MDy< z9=@uxHC&YvO&xUo1$&bAz5MF!A8)A4NlZ;C_HS3%cR;lL`kobwB`^069k}DK>w`PW zkjLF_4(CPH_LI;-EJrWFRynS{yM3H{4Eq;GF58>b-8OK6e_%%EQ1$QYZ{HVvC387bbs@@;-dPZrt#IQ__K^Z5&m4(fZ$fu6uNM! z2P1%XdJOh@b&fsnd}5pUdW}@<KIGH#z(yJ9yY*5@R`^ zGwOMQ&$(h_b6#=roX@#pVsnm$p7S|ZENspZ$#cG5GbW~=Ga1kMa0TERLpe7{P&|Y8 zoDaMMlztdI9RFYAzY-gBhW0Puf4ap1UFUP28h0t;=NY}{d@88k03G8>e)SIUXp8gp zBhP<;;xN6@E!0%!oY=b#km_8gdd1y8Rb|8Wj~3@6O&?pFj~D&e3XhNXeBI)FOu;+P zOI5sO?cF|3Rp)@4Tk;4sRhd-!m^BT)*7XKGuZyGdEwSsfL zq}^b3H8?H>xV!^=hfrLxyBXX&j~uM{O6nDsKX0M$vp64>Sz+;q!OJZEDEI-39|51_ z@*(Ou@Q}q{0Qb^AM7<6!ZG>0s-UdJ0vVR}E*5#Ht9Mk%9 zo5SNs41dM&eE0>>U)*MPehc{$Kz+K(>XMj-8)En^G5mWm{Pr0BL&JG(c@$=_AH?`q zC7A@^&xtRFe>;ZX7Q=bnMI85k!0;e&0R7zw7_sRd!xlh&y~S{9w13s`AaDTvUy3=` z%yM{!8f%?<(!MB$Pm1ARj^W=hJO%p>L4WjJ!&zsCpuhTgjQtyi2jS233^HB1l(*t% zYut~pnC}pdi!?Ri10~ZInJ<#XA3kHg4H+(7rN0@8J^#M_#?9i5F?={P_G|7l_2VRQ zzfd{Z9rJtLe0PH4EjA7G=Q#0EQRlOq_%NySFP{a+M{CXJJ>74A%11}#Gotb#RrfQY z^2u22YraM*-z|n>zWyoST6I4`>V7j+zIZAhE|t%U$`?fO!BPFyQUDzofc}gufR1p2 z`HHN3_ZA-dbEPFF@%;EGzhy38BlSMJt-t8%eJ5JSHObiXJJRx1oZ~8bRb7p*|E#Ky zR5#$Gl*n9ua;BylA4+Skt*(h&vbMgtjvu@+AL5K3W|&_zZK?CVofqFse?zFcwqanvGGww##Ve0l-$MU~?YrpSTNOe9`x0nxx>d$cMPb2;Fp4UQ1 zGyjoCze;gyw+Zv%@XD3=W|i}q$A2Wa5`2{iUn_Jze8&$zt!h&4$6fWOH2eFCX#8sO z_dN*m8MXd@`t!E`U}^XH{%QQIGM~x)v@<2=@g4Nd{|#Rsc0Xekw|BR{lNCSpjz#Ye zSoQOnt4}+?ULUcFACdl+6{iDPW=tjKJqJ3D$Js_F7M){!Mg@N0h(+goAj^!!#G-Q? z&o(--=+6AA5&|5t=o5gsb|K>=rcTT`F4ry;Ec$fl8B_5CM=asY1(xURiACq!SDv#c z7X3WhGXOYZ(K)Y>=d+1LUkV)H1!Fj3(HnpRGpJ(CIBcSi0uGteIbORDos1v2HP{La z=Jn>lEUNn2v+O$zJY-JQSR`MXO$&YRP;An`&onx*=*+i(nXnU!K85-@_<dl= zqVw7PY@^%H@$;31z#<(!vDn{5-Q+*9=#NwXinb>fo#(Pr?!=<=95&-TZBHzE08%;| zB3vW33Ui8fA8=(5KX6ZD3ypN3dYzb+7cLRuq~~Z{23#>(;~BuAT#e_@CQoC&10Xg_ zXmgs@mjV|U8=lLH{nuz?^!30MW3+u6?M=MAhhK2I*7*o|LB7TZfkQ_BEpP>IKEtJ8 zlQu;x`H&7A3gHKCGd8IM#A36P`UUubBNjagI8;DY-|MLyr}1$7rSqmT9E-MMyaUw| z{DlfNuEk$^k;V=96PtCwArk@HQGv0!0$A*~(#Gi9fGZ~82afHfV4?$^>p;?fGMx;P z$IVUpPss=V55p$?C$Su38nA>zEa990Ea4D~J_}gtC$WUXFheEyfeT^_l@jT`y<(Ea z)A1ML&0n}h*ecI(pz~}*V48;|%m5^bi&%7~GjNf%mo$?xn*!BZCl>n!z!^)lPAoe6 zw?K{7iA5g@T)~^la9P+Y&vc-3A3nsJ!*FA;6`bureNAqu#?0#kb1Z|17i*or38)nG zXL%(=sKEW*?>~IXxn;~5u6e#uUYz)}9siflDfEMwlF+~7^ttb&vGFHGf8R8_ck(_h zAOELk+{c}={@x#npH2NeCEt&A--qS@ky9)CB^^A3jCX$i&dW3A5oW$T68E(;xvedmIGBKsr`^YgH=AL7R8Duz<` z8MQKC+a($@692UG8D3`o<&S=J9RAtQeU=@E%Gh|0UW5R1fc#p%5 z>EoR*N#88&4^y`u+=pWbf{T;%O#`sgcP5^pn+_v}cOo_k?~0i4_-rN5t;9)qYh%J| zLwId4VtA~-65gJe@QUEU@mZXN_q~|#Qeea>8pA`?al?C7!ZSP0LU^1ji!-wNB>>Y< zW`s!y?>g{N*f`~v^yT6B?0V1Vhd04r9PQ{LF?Rdl!TrPuZiF4nL()OJbTPuegjWwc z;xgm+7}7TynCU}SI)1FrH<|Fv)KVS6PP3qkV_e+69~1A%Xk_M8!ZD={ojfZm={pm4 zl6Lw_`eL7zeG}b; z(JuCQ=|_7x2J**Y*OaVO4)7FgOds=|Z5iRY?o1^5i|jCrlXzKYZM!6Nu&k@%#O{lQ z6DQ+ADA&2qP8G{jQ~C)id3LIF;`q`M$NICMojQ<|;G}_lK4+^()GwUlWS`6OXBs%) zr9UxGD>!{8=G2{2cH-68n1RG=v9W(9z7*SK2LB8Gzh>~2`2V`W-@yNRgEyG}tMK1y za2x)k25-dwHw|W+X*YN?{;xLp8vJiD_*(P-E&N|+@b&oLYH$bsZ!owM|Jw|{5&t(C zydD2L4E{F$Z#MWA{NHNuckth3@OSZlo58o6|8D%>Vep;!|DnNmng1V||GV*jkHPoi zf3LwDqnMvR#`Y6~A29zv#sAL?eh~i;8T_#M--rMG20w!TpBsF@{P*DhAU6F(&J{zN zhpZg3bV#Xx{g-pb+^&W^d1rga&^$E*&y3A+pLKa>==G@|{WZ9QPx-9B>3`?xn%F0) z_zV@x?GNiQ9_;VhzA1P^rN6x+I#k{9+OA;VXS?3^t@oY_vYu8Nv_EH*KP6{0wmfWO z{CJM(?T>Tv_on28z{ipExhB7wwZD0Yi+h%4y7*ADho4wF!qtD-?BQpYp5p4iY4-5% zmbqaz>|f{Mo@H*B4Tsiw_=#n1m<_*N=iz6TozivF^jp`b-;c?FZ}&jey*X#}fnzHc zN0R)3JKM^qcDv6hMUwr2{LMMRoyRi#Dpm3@zg>_oH&wM}rYYaBeASxQlQJWE)iz(| z3}`FWfZWaMS8M%8=D+7Za$4x#qo<8KaJ0kU_M!JIq%V9}weC7RAY)jjk`U{k$iIeq zPN?m}4u4tNpic3r+n;}RPTmbi9p5pvAFeutC&I4YobvpZ)`f#`95YgV2Dre$z^GcQSaGJ-_*k@nwmPOW6SKc zm;dw7`+N74qLeetbDsKXzy^g<;9MT*(x)R&AvPdIk&5IcUme_66ff0mwi+0HX!|Y7W6~m8K?(>BR8fh z)}ukQQF}UJbxeGGyYL)MZricQP(CX;=2p?2x{LA9w>t^X+L^lR_ot7$da_-22l&(T zx1iphAp6DE+rg-}1zx?~b;!-Z*6=E{ig$Z*M%8|}p>o6QjDeLOc3j<_k};_5!<>|) zqqC=;kLPJ6T;Hzt)SS^fk7m64(TQWD-HADQJC7Ep-J*Q{Zq)BX19DP!9?i+W_vq5- z@4Yg~oUK|1b*r4f&SO6R6)MNK^B7vkQLofm!)+f%+dKAVs=EE#U-ji$`GV9%lU}>! z<^SCI9^=fw1?BshA7d+z7R0GX*PRxxcB(Ow{)DOryAo!2F%RzXA=UTz&rk541@=w- zotlH%=hYy8)micC#_1AjB*iY*gsPR^vF}RK<(j@XaR$n@_tEi4ULKlyZ2!X&Qsph{ z)%}<&`F0Od-EBEzoW3dn<-NJeE^i-Nb9;urtiOJ$6Y1G@x>w$vRjReKUd=}z^{aQ$ zM~&Wj?6kalSqjIzyzq6lI~KNbdyLZh%ps($GWGQf?^$W}K37Zn|9WBT_uEoCu5L@= z)3aXxGx1RVHLqXzyw&&2h`!|I(!mi4z8l|At&gTAbR<^|$csMZ`b8@{DW;DUDLJ`US-?HQ_8!OQv0^tx5qAWTdvnKH&lAhuljZkLJ1~)q+90bTOF&3nzNSK-XeN#6p-$@vgr>%rf)c`#bh<~)wAEyX0{D~t}c*_vGw<759FaAxLWu7<2Gj` zFG=inTSnwW|HYC)@}4btdj1)Vi{?m*FZPb4`x?nnIg;ml9Z62` zUsd^j9>Hr?kJg?vWboBHUK!Sb7*EIi#SH^?zJpbX9m(FP`_(6W2PY@`ZcI&Vee`tr zR1LVOcb^xprt(EdXJ)^l@+aus(lB#jEzNRzw}Gj?Uk{E`OM}I-S7d-aO7-gFa@ogW z_K~?ak+YA!b-l|C<>fD=9{uJ05+>gz=x$%JxPJe*cFZPIyWOL{e1CTvMyQj-GJmt6 z*3L@If-sZbR;yaKwJG0?J5}px;naE2t8Tm|=)G%jSFi)`A9&p7PxC)snNgRka#FgJ zazYOzT{C|0RL{S)X9B{ISbWbUrDA{oic;OJD}jY+9L8{d&UBbje5i1qbx`mpsA z;`L!KOptvN!d*Lhhs_Y5a_61iJ4t?6N=~gh#GG1h<V%?{r6h%Lk=!q|$d`=`qR^InuT%r7~fvY2|ax*XWT2tI+BwW7ms9FY*(;%Ht`gXTlymeP6 ze5H{bi@^{tn6 z;EetwvE39LsB#k)zW7*WPWH}YdfW`F4u7p{aTdx^tXrSC-MwOyFm>`1zGrV&-;Fc! zjGrQVB!sue@xRXX&qV95O3B!G0C9S$8iKhqbzAd#hK!ypCs%xV=p8zGl-D=#y-U`` z%lF^8*}gV*Nl$*eZ`Xm;*6<-W{r(w|f&O%yxwt*5b({-PJDsz{UbCv0v&4*R+ESj6 zF12Qe=kD*uS>o@lIn|u#YiO`eTD>Grg{;^f=h%6K(! zU!{bZFylvEzVIMDuS!0--?PSj;q%?I#>h8uth+eRpTi#5y0$Pc8oZ_K+j@R9ZnJ$} zcf8wQlAyVB*-MfCWscg_}q_nfJOV9=@R~AKs-{w_z z*0Vd?hgdz{Df^|CrMl@Je2DKGORjXc{UlC0Rh9T}sLb8-`h~(;{UelbV^RuJd~ZtY z!qbt`*Dv(a8Ljl@=y_3n9ltdkO)16wtc>K1D%zgD|N0lZZt~^&Q@!i^{l8bsqvBi2 z#S`yR_e|WUR&B|AvF}WJ{SdzOE@_N*d1*KW^T23$2HuJn-$-Jv-)pyh!x|rmSD%jz z@p|G7l{_-0?C!SW5~Qo-I<@xNgtz*JwJ)$?4@R8ieS;+SOtkv_;r&zdta}RnC;INW zKI4Npr4r1La5hvP>T=#BPOeYv@T(NOP43p8ggD{7kn!Li-@>ZI)?HPpv$y2z*_qvN~lj4=}UG8}m=gJ2-*6|KU-awTz?!d8UdhTrJSm%{x7Cq>aTrq~hoSb;3y6 z$o{@vZD~27+f#f852Sf*wS0eflnQ6Wm{+-Vn)#FDj*jtq>GYBDj<{*0#K*JWzPb0p z$fq`X^Mc87djGdac_G+ixG$I2-Vc~7d^_ElGViT*K5}2%xOQJ|PwL%nex)M6Qq{@j zGthJD^$IqXos1rjnDt}Cp@BpF2^rCMKiPD>KYaCme zJa~5d1MLWXbMMfxY6SY_3(+q>iTCOcZ`A8!Y%06395G<6j55p@pLpW#_WaHMs=~t? zDmym!_y^Z@4D^@za%T)^4X34y>&)x)%|wwc%06MNf8~I=iGjtD9)@;C|~>Q31nClAZAGvlcHvLt8Y zU13w%&%33cP&FeOyt(q`^-Ah1Rw8K22_3*)H*Y-jW)dBn5BZ}reLYDjZ=RQtoT+lw zAHebXX85rRL#2CUc`-*;u>b1Btie|&WTj=io2@p?ta)dSbq}LEnvvXg%$rGcw_zrh zci>pTVU}xaX3|HkQ%8Sv9?CcI#(3vsM^27gKTr0~{O#DVo`*X-&^4{?qsYm;%QO0B zCq7(vNoQQ!UUcsQ^d4iRu5&GxYxbdc8S?t$T8paJkL28%l$;T5OMd<7Jx}MXPf7`H zXMeQjcMZSEQMgk(s3+N9RetzR^!++inRrHb|FM-TU(kFC2ZQ*g&G zIdR)5J3U-hfp-CgZHP58gBYr`93 z{?za%&!X!l-lw@6E0}a|cJ9{T9sx)EVvMfuY+;WVb=G<5edjcNvZN`Y%Dt;_^4_61 zJHMr5^QKY$s)4DQi38QdgjMhO7V>`ajMU;k?m|tG{qo%zbSv)g@{aIRxXZHJnn7QV z`z(35cje7;=HNby$7=59J>`sH6O}g;Jhum9LuNi|{tVnDT&Z$~;u=Qgy~m0=eZw}Z zD>HM3?L5|sJHy4%9r*SrXb%sCHmvx9=7CzIJy_p6AZ0!h0ph*oU)+c@gs}FP;}MTPC-j zeSn=4=I2-+$vbL0HT|uIbm)GWA9}NV+0Sm-IqN43$hm&>0PSbDa9%NyR-W-HXZd>0 ziWvxMtXDgE%-wCW|E7KA^*OhVPB@zW=k$?b$(KzBT>r;%y5T$Y&qFO=w}07mBxh?< zQbx2gansX}9qHQ6n7X4WVVNUex4-vXsCUoRYt@;5XwTSV@u0>ZzUYU_l{NW6rFE15u^e^)#P3b() zu{T$>m38hrQWhDwC}I2l`fE?`iquX`C|)G)Q zK6ASAJ&XHk(s5U;enNDz7C}Cp0y94m$^&L-ZKB)UBk!L`ICQ@nYk|#*{gcpSIMu!6C1Sd zRvTW`#}oPMjD$s3kLYra2V>kF{yP7r@&wEVuGu$u&y45=D5&f9CGFp|e^XiJ{^{k6 zt$5u7YQ#&cw(tnUm?4CHt=MyHbXQUm&KwURT^K|1Zb$DFyqPsSzrDS3;5YTWXVsPw zFW%WUxoe!;b9J}1o?fLQA8g0fsNGSuL!Oq3d@{k8v3IiSh<@;iFYgeZq)AP<=iQ$; z$N8(Z!;Z+2&fdafO?_kF^ZvxhTlb>(iu`F}LU4x_L-ghM?)~`XzfJsPMl^gsXJ2D; zcTK@oiETQzx!9I`?UwsdOFE(p7v9mcYs%m)$6ZJKDsgP*uBK@Cp3YtBX(cKjN3 zHsym)20l9=@t*fn5=QRvV*O+K-aV05#w6VH{utjiWp_j~{Wt9Qo#s<#{k-Gu)6|6( zk!Yg2=WhcNP_nO_mT=GCPV+@>I4R+b)(u^>emCic@-sGe9=to6J|*?wu+!4=UcP$w z$2q~D<9ftc|GP;k1iq> z<-JcXERSrvU!9s8x#fO!`ksVGC5InHUO$=`>HM`yDZk{SuA6u+P`LwlEcomI#!5U* z^Kq#^T`l(WysXrps;>0sj3Y``ll^!e4ZbJx8LY&dQN*}5fibEhsmi(HHw0(rk|VlD zkGCcteLCU{K8|GURik%^iq*1I zf2(>`HLj~^sILuTF@c&@BZJH88@QTRQz&+Auh}&X4XY#NjkWWz=GT<9%lZv)VU;#D zON6y}%Y*fo1ZQo9_$!L_w+mJs3D#oilwebH-Mad^OP#$#`XGXJT(@kbvm6ZZ$axU1K!j;wBwmC~^2T7Ov-v*)EXYa%O-XSb$ceM_)$Z9_xT8fN0c zCVVoXj``ScOlutzQy#2FZVB|4HfNPMy~7Grr@CfSek_GmK_g)uiqFbcRN5Bo?9>FS z8aQyxOg}7pZBgSz6yvzvglrND!Z<2)3+k zYFgcle|+Pq4r>j5N-o=Jp*hwmtY1~LT(`iG(|`4@zzbW%_%XA3!=rqdt zEsfx%E9x5AzqHh2okBNaR;>Q&0~g~#+Lr4|tb5kn7IZKzRkdg2Ue^DPUMjF2j}t;m zbL8(xfENzaT^C$~!VXFe=s)^iIb3(i+PcOFc01lYHap-uUHxW^moCYo7HOZ&EGPF1 zTm6P$Cs8+w<4&Oa?JeCQI1yIXFRx!y)9`6&mXz9s8FWiC$l}zA;sH1x*0MN0QKhB+ zstU@-YDY2O*s%h#KA2^x))%lW)%m2A#hq_dS$t+qLtTCC>K2SEb(ZY*kd|h;tbU8b zE70b;<@GJ-Vvsc$nwS^v;%4)V7oL-f@ALvOg%f-2wWv5Oi-;EW@^E^sWi^qyaQx8v zsyh4$vyi~5IrFjR7{g-+>K<|_I%NvsutYiuU0D+sAU)1lbR4B-1=W&8b&)lzn;F~W zIq0g^)y=MHV&I?Z`VC{!{D%6-aRp(r%stl9@}{P$HFc}v$Nm54+N;a0TNv|6 zvvud|2%h9~-@enDPw|a0&-vU{613)X-W;?2OFaVQQ>JpCt z`BX~`UmL?Ojp3KaaK26GIiI@HBS1d&jTpWmhVuN%&NUWK@~Q0}as2saqUU`4kcQ=a z>N^%=c;AiT-*eWvqWCnnMD;x-IgA%I&=z;m%XPj!e79nb(zXm6?XSjvCAJ}kKZSqR z@*>0k9sl3NR&4ky_~$!~Y}wrZPx${EwhY5(Cg^YMuxFzG0`N)LB)rAIE3vUBq5m@A z?_uM+!Q}iL_3yB;=OMowcxa+tqlKJn`JM@mo5_yO z?*>W!JOMri{L9Av*Wk;+`A#y^b29Ly*d%}RfbYe|o{s+Gfj`2={+4_b@DRUJ?CHq2 zf?otK`Fk_?jo^|Wcuh<3`!$lkcYzPX^Cav!xj)yMtpOiq_)yqh3NGb&D)=sNiGLmV zPrxO8>%kKTc>d3U4+EF{D}?P>@GqJ0zXZMvT#o-+;OoF8zg`1x2hTJ1Z-f8Pvabbx z7@MT`A>d~$K0HOK{{)xt8^Axb_&)G~*iJIxXQ$#_c5peq7Vr}Afbqwl>wIdDiwS({ z_887LiaqC3KTwAd-gJaF9y0U$SKya{OZq))hIgk;!S9OUKZ@aZ$MAb&INwnAoKM~F z5g=c$uhEgSrF+h&e(Dh*pL#HcKODpN#qdXB_<wRl33ZaB6Cb;!Z;;{(Sv z0LP(QaQtrqM-?{Z7i<4-iqB!QZE9Dj9tQW;Lnu^_g4c>S=0m>#&$sxm!RJ`~Kft|p zFea)$fCpXwQuSZpXEJe)`;z(__&ke$0^V%#6m)D`Ej|SNUW;depNu|9!pi}FTqs)A zSn&HS`w8IeW5xa~aQ1n^r-EN=@pHhxZt?TLlPz8Yo^SD$;LR3q0YBT~Ujv_R@hCXg zCXx8B1#h(Yjo>#~ybJtZi{B1@s(U#Yla92^zJg}_4=p8!6~;#{|a>+5OvWrc@BRhh+SgM0Pq%W4t$`Ii4h;1^kZIrwcBZvr3W z@^W<<_$Z672cKf`cJQSZ-wOV`#lH>CwHdT4SKkBoz70^WegIx#+20H9tuJ4$9t1zb ztqJYeBp694vfxm9q{|@|Pi~j-K zE01&3JK$dbevbMOJj;#$9EDqrR(_wOP6U6_4ewkv9Q+lFj|8uD_di#S1;=ta#+|Ds zfWI#k=l^GcbImU8&Q;UE0~S9Q+^Y}gstdrq@;+D9fqVHgUp0bz`7>W#3ho{Me6=1t z#SMSHY6th?o3FNlpDD?~nc26&z4^vMwG(`k<^QkXTP=PcIOk5!M9obW$?`we-nI+%NMJ6d+onieGIA;9mJHR;A!mt^LcvdA_OLVl@*yAQac97J$!kd5u~O?xn9rEdyU~`L71| z@}ovw2L3bGKcY5(KV|XF;D5Gw2l!AoJrQ*?c#*|-gTH3k{}B9a%l{|fUjG+SKL_{f zXGA>#?&W`-dKNt24X;l92Y8mtm#f#ohgtj`aIbzWS4Y9eyZ-gchYJHm79RxukjpPt z!@!qVJP7WU@5L$~e5&PN4Bln&v%t@{_*C!)i_Zo3(tok~D)>IjKLYNZ*fqU&^ zm0Ab>h-<$}tq1>s#W#a{$Gb{(fWKw=-vaKn&sFOC;LlqAKLQ`_me(rvQ}Ekd|4UR4 z_!5gh3GU^`CFe7fu3qLNVAz53mv27|A# z{D*;i;jdL+03Yi5U#iA{kFt0n_*|D?uFe4Oa*y|NRSEup#r|Y=Yf}5{x#r@ z*8UfRpJ(y4;1ewV4RCL~zg)G0mssI#1^=35e>3=ci|+;q|B2t3lvfE&pNQ zS6KWDw0Dp1dUZOuH=n#-6@wqM?9T%C#^dYNG;puKye@}6}*T*gHLI9tY^VEHorRHu$C53;Y^DjTg z^DRTM<-gBeZB?s%zg_6%w6@2^Kg;=4n#C9%E-qNk$BPS=^EoTNdVEnJPWY39nQojQ}t%9sfl!e18mo%<$)68^B$R*9>PgL)32d0 z&(Kr@xZZil@V9Zi0o*ky@N0iwQw!iO%eM@_$gwY1e=wZu4+n6)W=68M&v)#@>Q=+g zclb2bf_nvY95VyB%khNa*ExKqI?Xg`&S3($3-d3Aa}E>0`SC9dpXcy%Rldm|jwu1$ zU%tw4&ItlIzw=p5fcYhTFaHBLU&90UuA~3yF}x~K8HHjU;`?m{w2mf-}vu# z>@QK@G5%+RkHU)D569U5C5Df)hIpoLdJJD~IQ>TAe(&}e|KG*%ldLHM_h~Ua#o7OU z^}`tdhYg?Z_}`~Ki18n6rWhB(e-xgtDYT{>41b}`Q8r6$4*%6Lyw&hzC%g^nKEs{) z2Xg%l!}an0SPiwNG}N*T*ZvQx%3k~t6)`;MguhXJD`x*~hO>T*!kNV*z3exuKlSpz zMh!23A)HR{wQ7>#I=$ag=NbMUY)0YvpDE)UbLWR?ywGr70~)0|)$}iF{~-QGC2m*0 zG@SF7QFuP+`SIGHzuf-?!?ph{YCw_pcX;A=)PBPUK^}rDSHCx$)1o1G{@_EygWx0a z{J|HB0pN6f=vEbmQ)7JfF?_4x41Xl9q#ZDvhcyz<8@y*YE;E7uNDbt`4yVJvTLlf* z`~OtUG@Q+TB(4mt>*c>sbs5g~JW@TZ4)^l!QEwQ|X~IZ+H9KV@0NiufI3LV2ocpss za6hbCSX4c2);Uwk@!{S%_=4_yKG8dOO|$+~tNGZ>tis9j^+WcR^({>eHJ9^Y__{Ek zgT-^Tma;;*fwin%T3uD$>#5sC#m>ix-A@Jci^1dgh1}S020LFB>hmmbVM*+3MAlb> zS0WfEJbn(>0sMZh1NdRx-v2g zD;&w*8R5P%6aLI>FLEnakz2Wn+!kEq)_|hVQ3DFClz1rGFP^8;O%o{A98nDv@i#~T9bE0tGVENS0k1yGU zx{Wwt%8N0d8myD(V%Fs2j9_BS3p7^4&<${5Rryj3Ts4t3bDLK$#|v34&OlhA#|^FU ztvWW#lMW25{$c4HCaSFnDS?He}rt`wlKOsyr>^SMPUt0Pn z1YKw~O?O23XM|hobzElr`qWT$74Nr;E-LIb36nRe@Dap$Gw1a8ZNkFp!otXkn&xU$ z^!ha|Rgo|%d13Wr=S}AtzLo?f?2O$-MZLoBHKbP0u4`UiS39j?^-{bx>drZ56&1~2 zP`;q5qIz!my!qjI)r-pKRnIA(jhCC`EAF!jCoQjT;VVm3waDCcb~^P2nOMy}jQ`Fg%mF$iC^`rLvDINi z(18N5GvQ87SLgr^7!GiaUBxxlX~AABD92dhbVfW!ktm8J@?vdVVp3cpkpt+xORAkw zddifNY8_>XIe1v;LjjOL%rQaHi2;zEOd1fJgj=YOrPPF1YBICb#8WE4mYUp$pm!}b ziG`pK9zY-1B(v`%QxKEH0zjt`Ku0^tL6qcA za}q$8IlLr1XDTse%4FGnvWarCIpWDC#>pnNFx1%wpo5<*X#vpb2hhR8MrSR6P6E8# zz1(ngq6){GC;_w=fZiQI?+&1Irm)Zh#->nqM+0>#7i>%tfz1BWDsaAM;wX|hiaZ+= zN09_nBqdW=ERht;{>8F?vFu+gNh_B9i{1Sv$o>;#{|U1H1k1=I0Futg!U+--B%OhU z(vShn@wyEcl4oTq6*UtWkU4lDU2EuT^07oxRwBoN7GkVQk0zel#fZnU9NQ~X? zQYr$x%{ooGlVqkwcCQ_{yq4A}MD8lNKpwC}y{b;x*AzOnRkAi%={k zx`~oJNao0abdJ+ZmrzlObpO%?7D;(=ri6-Y-=EW;Lnu_w}pLFAMvfexQYXCRSI29XZ87-e8~mC}P`?4>Gqlq=NMwAaDo&Iln<$kE zz=S2WU?OG=CL(FMkW3=rXAa1nV9?(4HGx4hxgwqGM5#Xj6FAW{li%XCjjNln;7VO> z^{SdC^R4Q_V$N#MneMzbUsW5PjF;efrKhTv^Wehb=`}4Y&RHS8xT-V>ml$dqs@JTp znqO4S*|I%Z2Aj}SQ{P-Q6Q1*n;SYxy`2016CH0NNPb>8|w7h14hA8ENknkxnj&`CfZ35I_~OT$La)J*Ib1Z&7W932Wk8C17pHx zEiFXaaX=VaVnTCrzyvmba`pVuYS-90aX?H603COA-6~v5j?^KPdMp%DeR198)iuq_ zTNuI&o}0LNhU87qc{XSM^lB#$u)C8h^*AkX&PSY+b0o=88&}uXRUx9e>zL6?!#LGh zP+i${&VupP{|^+rTwDJ?UBIyixwNLGK2nVfCs+cfDuTj|bAo9%8J=HO6jfC=;w*D! zL}ABaB-B{(+zoPNg)oWHXufDVzAuM0B zqS{&FE4+^TJ9ir5f5yJB5H|y=8nIdrmazG3>j`pVtxw+n+fS~WkdbSaxyR7wZV7r9 z9^ryT`WXB8ql-al)I=_>j;y%2dimO#=2|zfNwN%Ec%`f96;Iqty3W!kg;utdEUcnd zqA!DnmpKi%RIg!DRJ9DJ_RH4PH8fb^RdH3Iikip@tV+@d*xX-^7nb%lEuDo0lFn(w z`ct#lHms?iSJx6=`A@i>;aai)7K!BKAcClE znCmss!gxt9EOxHdI&1i$9C}yAsm*nDVLJrp7L$9C-aYi*CDqHna00^D%G~;OtJmn1 z_Nvpzw>N4{^O~^LSo@}h$8X{aH`dy=g$t{kn&q@E7|m~v^r>)Oj>p!dqT-mE#42zc zwP})T$FADB#8+9frpCFjz0`}&IS}{0L_e9@%ilRrt+4Q8n~qZn_5I(zVaIDaPC~sk zxcVj`jzM7|^0B<3etF~E)y~!XiE~$@H}$SQ7RK3WlI+9D&m`10CxFl1XMPjcnX-;6 zPT07=jvLQ)k$S8ghkMJB`WCG2Xm=3t_9?+WyxNMMbCxr(ebx@+vBP{Ebi91`iZotS zJa$PQbLw-4z~h^2~fF^(n{Fg;kD6ArE^NR$-iiH3=`CjftLh*kZ(r zG8M}wa_Zo9#^T$nB#Vj{RxPNz%;}QXVia;pbrrhZFy{GQuJle>yo%V{!YNUP%ijAd z^$oQV46sbjrv*v--Zsu%CArbnCr=8;<7Sju9_}~~%8TCGH-2{6p*y*bsF=bEWDc&y zw|Lj{ds$ALSBEuOTUJQItZuot9m>drSl+n2p)S14>LB|Zcf1_$V{{yu-e(^M+&ABy z;l{cb*Ej1iM~b}2g93hx1GHCU$xC-GM`?Gfe5Su*$ZtEqhN4QhhA@ zJGiNI^n#B)H7}fAO?^!m|3t zTArZ0mjIme?Z|4JCsiNMxj0Y6-MlL*)C(KRsnchi2lQt?p{hkL#9W38DAu(aHzs{K zhgE1AT3J(J5oSf4;dr;1opS8m`I;*9S^HRZ2rag4eYUqmyqn;oJp6HZdrX8Cz30y*-PvMQ_l0_KeJak z9^JpQM7KFfcosur^@IUZ8P3Zk`~xLT8h zIBRzn7SF3&wR#=88oh+)3OulctFJ=6YJ|zSTZv-Nu=^&3-I1JtyUS_DiQbLKx&dA| zsqd3sg?u4v62uNt>_MIL3DkA;oK}~HR_z^VoIQ)!?|XeY zmMN{R=R8TDzv1{A>uQ=^Rfq2M%k$T)ZgM8T(-z4Um*Z;q;Ys!8@(Zq2pti2U1tcz| zi>v?D=l}g7MJ}t+*E_0fBA2YKZ?1EXx}Ofl6tuZm6hG;e&b5&0+LqPm_8V&(5NI_c zLKVEM9?i!g&Q+G`=DLQunienC8m8sagL~0Q1Sdts^k*N z|H%nJNpl@XeBDKRN7{(L z`re^H|BGh;^gQu%-OSPVHNun3<5;~jeZ0A!f=@71l~?~yB?iaBdpb+kMlP;fu{RXHS#W3b^Wrc^IDp5bG~9lUF2eC4SnYdO}plB6dwa%m+sZh|ATdq^~TNLx@z9=(ofPKPrY;R zj9JP)-l_kZ8x`~}9d|3?=ww3*O9)n?HgJeP%`{W5%#VqGE2 z1k0hfv^e)$Hcsr`4KCYpO(j8kqbE+r@^7;3$)~5H4HLe(E(6ondJF}0+ z)Er|RQ)?*xj6h>8WAm-|ETm5+_4e+kp5T<;I?af!V$O7ruapK}(Jw|4%PV4BIv~Us z)8Y7%^ij0M7WM)`>-5M*IKNIxgN?v~$Zg zx*QAtoizVhhuJ61Mz_<<^kn@-+uLd5`>feUCziBLrTt&EJ+bIBXm504(dW_rU2RV+ z`XbsJomljXX#bwJCl-Av?Tt<>`bygWP1_TT-bj0+6N|o%_U~(ZV$rXlz0rw9=X=3f zA831G(KpiG=)|I5OZ%hRo>=s)v^P4j=sRftp|&R${Z`r=omlkUv_GcpiAC?Gz0rw9 zznk_SX?tSP@1woZiA8^i_8)6|V$mO=z0rw9KTP{iv^}xtPtxA##GBz$7gFQUB(pIG!|z|z+di{1<@ z@e+%^4p`zP7X1p^oA8N6|2plBPAvLHV2PJl^sT^I5q-SGqHhDvHafBBJ7{mhCl>uy z+8do%^xeP`FR|zkP)|*CA|@975nyQ-#G*e<`!sD&EINnhz(B1Ni_R`AFi7jfqO)pd z)#>9U7M($78=YA66KKCw+Y^f(0G8t=7M*K=XD!qA#G;R*z0rw9FQWZYZBHzE39y7u zEIQW^m;59aook0nz7dN)7dWd{hfgf}0^n?;6N`Qx?U!nMV$m-Imh=#dz6@B>LoE6_ z>H~E+#G+qi>BOSnZ0W?J?*x|qkXUrCeV#EGKXAmNbKa7Eiz7SppY&Tb=JY7^9gW%l zhq^R=g!sD}C!wCC-==X1aK-mDJ_ER5r^a)McWK;2yjx?gdsOg!jqfJjqwzuD(Cr%k zmYAI=9J}CxJ2cKB{(;7$fJ6VP@fhlNYCM(rhZ=7NPQOdz9{^YUNMnv8QU{17PdJW9 z9v;t_!a1$<`NR^=8PwSb;D|*(A6Ui$V$nANXPl_*iADbz?akuj#G?P6`VehTEc*M@ z*~s9CMIVa%l;b59{Z!zr<&L?tX0qrUN3xA>k12VyU!m=Z#hz#V*#<~ zlW1>rV$q#3%Y@Ts%rd$?W^p`{Hf4`Z=TXnl`9Lh;bDc>ULy1La|1W(YvFMwDv+DKn z5{u5Y(Xx$BEV?sBm~{3TBaCj35$yjZ{lpT^kEsvU=_eL_AF$L%h_{5R2~g32gLmdDznLaiFvQYv^8$-^O2Puf~5S=422q1>sbf&w-o_T<~M9 z7ZLwN<9WmnXuJeC^iz#DQD+5*=syz%teoi@uEZCVXPiSJK|-#G!dwa zuD9%o#h%jwX*|Blbnwbi_UW{(e3ju=RC`tzu4zl zoQF%FMl9hh0+v3FSakMjp+mZ!k0w5>@!9xG|2K`dQh!|Ir>Q@oaWamp;z^CufD3-1 zagdk;BOLqxf?sO9g!n0q+24kKrSZMg88F;)#LsB_0&Skv_%-Uk*4Q}*VW$f>2gg$J z8;$>2edag>Cw(KamEEIQ9aC0=6DPoU094M!~cXzHfV zCl`@Rr)|;(chzP`aojQIowL$PAoc;D1AGz=dy^hw(KplH=)|IL1(tLYi{1q+eIv2x><`n~AmDDr7W#Jw zDt1+&-)j6G@$WPap{zr^FaUQO@qcLiW8lgcGV)-kYr9sEXOs9Ix8R?vFIV-z-d}17JUJACJK&N z^jhG+=~^ciy^VUl)`>;uI1=E8U*U*F-whlHX`NW~ebh}mA{L!Pl+68zMSl`l=6=MY zKSlf1_<LIb{iKr)m z0-X=Uq7S7$NbAI+pGw`dFJjSC5N7BN{J>>l3$gQtyA50DKOLwZ!(Rat1;;8|@Fxdi zZBB$~?z0d}n4_roS7%sB;p{r&jFn&1x;<7-XE^3Vcf=C@`P2)wJ+bJ`)H(5iBNqJ{ z;6Sm~iACQ>eS+4BMSq$)KQatQEc)BPQpbozKME{$j9B!Kfu)WSi_Y@OYJvb~mmTLw z*+wT8d!Cy}9g96rkve9V^>8bEVhM-Wd?b8g(Va2Z+_Ua8=9cJuu*cj=>??JQSi<4C zgVZtmJi@7CZ|URB!e8jWG+u$f3T7nS5p1D%9OzsZE%>v>oEsGUMdKv=$^4vH;$`?U zMi7gBDzMZ~V$sJ@H}#WPbf+Gc>f^QR;S$<&FoauzP3$iN4oucMvFJOgpP_YP(I292 z`Y2-2|E@l&1p&Z4g-yb7`Y5CS!+n$q=XEQ5b^+N&Czg2o>!Vn9QXh!Lei*Qn7qRGh zz%sTHi#`-_g%}B39=6cC4s^cp6?#wO$M9G1H;sQ!{JzE?6MvvF`@IS_P`J-qmx9JqV}t%$m*OT?m|N&QQ@4iJm()EQ2o;OshcEqLH8trLs=&D77PP#G*5Qq^=T+{+y)~i=KqMk~&N*dXT!Q!^EOtA>dOr0sU1x|zUqHQF>%^khQlFxAV$rXlZqA{IMQ@{?tnGf3HG07e9wZt)PG`0r_(17g8*mu$rphKcrpq{EcWasvaZ)-0x@-_ z%^kpM17jpiAC=QmU>GpI@^NOTf1G{P5X8Dfg=|C z`+&2JPAvLEz*4@%q8|p9`b;ePlfY7+iA8^k_9lE{(VwNg(TPR>J+Q<}Ec#!mPuKZC zEIO+~pi1k+q6es(dPpof$8qUuKPMKQbx+zwY(12A5nB(lF2zo8&tj8so(Il0Is z+>e-!K_ zKZzw?C;$1t9h{y2XM#(95{rEqu;eGP=#{`(m*WSHSoG<@*+wT8eJ-%%C$Z=kQ8)QX zEc(}}oB1TM=7_baKxey2hKJ+vFIlQXHCNo z9I@y@;B2E4iyi`&JSP@?5_QuyiAA45eZEd7vFPVfH)A)k=u3dJs_+B11e@r!z}ZG8 z7JUV+`2qO*)b z9OU69U@JIH<1*k7C*yGQuvMI{@fzTQe2uwp7BdgdE^F4$Y@-uPTv@ZW0Wk)RfEa0r!_<MehR6HafBB zJAoxV#G>y3mh=#d{tB?fODy_Zz**<9ve-D_h($jGINRvNqMr?%H4i^< z#G9L%R_qz2gikEG(`HThecJ4N7{c{wvqtaJW=%MK+N{wV z5thWe4p{08vFJ&_Azqw-OCc`RcmnYxjafGeCTqOJ!rb?taXo?MCG#S??3^^8r_0(- z^EI?L_r-|iSawqXsOP!Y3B}HDD=IV$uH$oV5f$aKxg&2b{eG zKXAmN9|e|piADbySmGrX-I+iCm#z=?{F$dWa=gT1&wfCTmsoU8wIyErei^6K60dz- zj>EhhFR_Hf>MP|-Ec)5Navg(M^f|zC9fMeOr=MiU2{#H`=t~-(O?;-tHxQqt@dLmG z3>fYR@s~Azo48D4UXmy%*O=#q6;m{3TvF$WB@Icyp$cs?oVZeBM-OYvezKB*!3Bt? zX&kihXy5{4GZa|jBJLFzJ7&0(v4yHMZUD|==LAPA_D#UqMkf}14RF>X{J;^5ei?AK z(TPRB3OH*ae&C2j-w2#-bYjsr155bCqF+mU6F#x%+kmB>5R2Xgob?s_z;$60eJ60X z(TPRh11#|pi~a-Jn|O&uzYkdAB^KQ&yBRuf2SE?b)Holwa+bztQlG6c``ZvJCfqD+ zmFH;8tPjoA_(I@{b2VNGTrf}L^~CcvzLnU-%QSqRzIr(9<$Q!#j)mW95(VqjBvL+V&73wA*h(&)NSo$Jj(b*qLUu5@<^I#KN zpv!Ry@j{K40#`25c$tOS9z$Qz`gO$TX}pd2s~UF$7Z`mX@%dU;_^Y@;<6-y{n`GDo z7VEMjmNcILoOO}biA85$lx=ik(MQp~I?M8EWAy%bwV_4=vaBPPwemnBhqONi6oP z|I)7Qw&2wHOW+A7b)ML%^G26CPo2k=)l8(Zgg*{E+vvoimjFw?5sO|1Ea@Q@y%AWh z=@E;58Fh2df>`wHsGEDr#G>Cu-CP4C{{Py$7T_wXGkj4*QPg;)iV3Zeq9VQb7Giv3 z8@)k6BT|jXbf_UONDxR&f{IU6#Hgqd1>cA-Y85S2YVm>1(D)b&mX5Y{rnL2ek2Gb>dKmXnTp6tTa;EXao!)Cwx@3-Ii&tv!OvS;^K`%2ntcf#KUB3_5~9$@W< z#L6FlYE9M&pIGg|J+hO@zYffUd^RUr+CRRJUl-4t` z+UJqa3PU1R`+V}9omlOi40$kZDcHZ8n&l6lhyW5vT zk@A^kx=lD8Sf$zpUqm|%NK1+52;K|7bG5F0Pk8L#+JWfJ>a6SnWl? z`!)!lSnWLCiyOsmkA0peOPrlp`8+n0(}Yi~_TU(tE_Qni^88ucBz9uup9oyy?8Iv4 zd91iu_{3^Ig?wixR{KQY=!y z0_#{$toHqYb*v{=dxm^BrW4c7HetRx))T9J0I-fb#HvGFj0x%7SM9{~t;E^YPuhoK zNw!GYiB;zi;Nn)%A=Z3H0+%>DvD%LXRvlv1sRS-QPjrZtKMuIW*@@LopVWV1wGSfS z`A@8N)?u<;{I~VVI!|3F?ZtXXwh2e;1SXj$?9Q3CjRGHB8GHHQ>;?NU*Z44}a32Dn zop09X<@Ec{qDjnpVB-C9a<1qTtDVPh5lKyV7HwBu)hv)72d+}JCDQyff?csrNARxmH$Q`ZTeMtr?s4hd-vGDtip zXB{ra@8m^Nx5QevJRXx5i=9~QtSjXctDSwR@&?goe@opcnEf{G>?44)H;J9cQMOBP z6Ztm_o&j9BNbqcOZV}A(%HAq?0r6tNL0dSTF4)r?Fp)N6(S5f7ryZYTO7apZ7qR*u z)WfB{>w%g{XD3!Z`)%qr$*Y|BcEMwSi|!E2{!@9U;Dx~Hy9D1!>^OG=XPtc|aLU;^ z78l(u{BGd%J%ZN)XB~cpn1d(M1}y1&1#bjS@d5$qZQ}a`e*m1lU+@5|ls_0a^?=xe z`f<-dZT;*{od<qiR>`exDkn@<>FCuepl>-zj8g)Z<63av{wr*B6f2X1{0ql zcECixtL54w(7DRk7a04MV&9GY`GN!fHO4+uaFFjT!M*gaHFm4tX>_g=9Oz$f?C$y` z(C>)RS!noH=LTbU*BF5gU$AqjpY`WP!?!v&8T$o-1Dy+Fbh-@R=>&ChqRTYXK6e&A zTb;-t@}R7n6ycNZ9f?c>q6#E3b%^?r!57_YGqh&H&klbnql$j1JPkhM8|hKm=ZQXN zf<@+wN{q+R4EKR(5E7nIBaYzH{@WpHAisSbghJEFs61Q7-zyzUjX zar80bKMRwKMHn9#u%OJ#MjOpAIA9-Dt*5!DdfQPm7gVl~nq{NH(uZN>`Y1a3h)^_$ zTGm&+qeH!1TrI>XL7-)P5WS-op*Pw-W0$k7ZUSBP(NU{vLRR%r)mCQ^#A!R~g%N=I zP?u$4^Vs-5eRb0u?73#{tL9Omt8xe-0B4^%Qp9OI`Xm>`*C^;DcjRe7sDKk@H=NN} z+i>EXX=5jvh+PFq9F5?;JW0CnT|rRMP$US75PZ|yZjU@$merhGb^3`XRMpf>z|nSQ zeM@WO#E!Ot3yqL>t+-NXq%YfJsL9nsP=x#lN{ocYP@U}vt38*aLt|m1k2}2R;yBbd zV*7u_RI(`W55GN9SGRj8C) z=MDlIM@7Jj?$9QbWptp*sJ5~@F|L*$i!y4TULBu1YS2Zgid-3jCXNWB6&$5O7|OgI zBYSeh?(sn;BOHziXypgmj@UDzbE1175M1s)CpgI$7I-4=Y+2ymjH?vkVoc%UdT~U= z2^+^E&c|)-7UNvRZYFBQXUNR%738J&nfdh}#5^7Fq1CPotSuF!B|;H;)B)oCT;6~nnTrXMzE8D z_SzxRS3cqhnUf@HTJD-M;&#CXH8y*?qJI88O^~`6|F_L3ICnhW!84uD8*4bz9zGuG zRd*402=;y?s(%!)OMWxO2ix(T-GCV$VkK;`?JU&v7<24u_Umc0#u@2O~(Ocp1`M>h`*~vIP&IeE) zKQ9=^yVdYc+6r%(;Z4{IZv}XK2G923d7Kib`Eu$>oZf?m$EhoEJWkWn`r|Z@INoZ*x>?z{>Jj&FnXLK6Q}p4(c{#cI3CZ*T3$@|jpcn}^5vA8IK2e6sUD~5 z#PJ3h9;Qae@`hlWwlAmP#Oak9Jx=XWUJ1@8a6OnGjupP0$G>6Hp9jH2-p+25&*L_x zL$T1GZSh8f6XfeMpdQCyO`2~C2Krjz4D&G1jKXh@3)J8?*5~iBSiPy>b3Udf)%z_B zR&OQrIQNozoPVZzd^N-BvCqxMc1^0+1d`Qz8G2nHQSS&Ws<+nD+X#Uw6~kKf)_8i8 z7t6bv)H}-P@zYU(e@4Qa;Gfg`uF*T+)0>3JvhKCZJiYTgy(!DlPj?ajPB40}czUbQDIeBKGyc8c z>2*DddCN{OYxE98A#8c4?2UKYXmClTi@~$yUA7YbVI%8rEEaC#@zLVxEhtJPIQLzX z>do-dz>n$dIP|- z7We=|J2H=#EM+gaY} zShT#4d3uYWN1i6td)U((`s>iYW{_3yP>eseJzj-gkBVWfdc(l8<*kCA_P=wD-esQN zq5~6&(unq$>*itXg+_rVlt3)}dcODkitJovI{+1jReZ6)Zc((qEekbofQLo+TEmb|| zNdIBDHpX^M>farzrv_YvjRJ{!bFip?uX%c-pf_B_u-4sQ_4Gy=y$g)qt{Bv9f2oF^ zdtE0`RlS|Sv*n!%J-r^9YxFKqJ-6eh-%KP%1WNKp_1aX=8CK!KTg!W~(Od254M$-c zBJ`g0^fp0nifi9Xjo#lqy-w&=N9g^<)2sMH*#9m!dI#+3>d%#9BlPrKNLelK*&gq0 z@S^T3&H%4J_N#C^u13BXf`fi=CDz;q*Ak08z0J^@0=p*7x69Mp0KIOI)?=BEMfG|- zy{dz8oMXEt)%&@p*Y(G6TwMUN>ix&ln+d(BarI+QZxi&iA9NbMGE`R3Pn{zRV*E>k zM<2BQ2LCDa?>eK`r0cC_g&R<8@51iI56vZ z1s2sCjKa}Z_u1sc6zJg;kxQz#H+aN)ejf6EsP{PRsyD&Yn+d&4PEGRS&rXkbCwMrO zHd&$$QHsxJq^afyXq(3{mcI$@T zxLheDU;Z4cJhzQJTMoq&!L#i_UQ~OW3Z89`3ypuPk%zX&Ri54k=pE{O;7aTHS&#P# zcv1E8l$Y<_Cf{dGzW?y_`X3Qpj=y?(-9~SX(L1;#zg`AI?+_NiB`wDkk2eOqsB)YQ zo~^%4Cf{yoYW>~f>5Ypi$BmxeZXbll$6BNJjHfpldNAdZmg7B-*AY{Wx4e8)Cf^rK zzDW#bxRl8Kzx+Jtv5cCCx$FrZ*A-ZpCPI(($MeQZSh$V9zX2Zm?9N!2=0lIinP|`$g@?qkyoWZuvQ+|?vM<&4muJ(V2pbe kzx4S&kE?-Lv& GetNatives(); List& GetNativeAppLists(); - void RegisterNative(const AppItem &nativeAppList, NativeRegisterCallback* native); void RegisterSlice(const uint16_t id, SliceProxy* slice); void RegisterMenu(const uint16_t id, const char *icon, const char *iconHexagon, const char *label); + void RegisterMenu(const AppItem &item); bool IsSliceIdExist(AppViewId id); private: NativeRegisterManager() {}; - ~NativeRegisterManager(); + ~NativeRegisterManager() {}; NativeRegisterManager(const NativeRegisterManager&) = delete; NativeRegisterManager &operator=(const NativeRegisterManager&) = delete; - Graphic::Vector natives_; Graphic::Vector slices_; List nativeAppLists_; }; -class NativeRegister { -public: - NativeRegister(const AppItem &nativeAppList, NativeRegisterCallback* native) - { - NativeRegisterManager::GetInstance().RegisterNative(nativeAppList, native); - } -}; - class SliceRegister { public: SliceRegister(const uint16_t id, SliceProxy* sliceProxy) @@ -82,14 +67,26 @@ public: NativeRegisterManager::GetInstance().RegisterSlice(id, sliceProxy); NativeRegisterManager::GetInstance().RegisterMenu(id, icon, iconHexagon, label); } + SliceRegister(const AppItem &item, SliceProxy* sliceProxy) + { + NativeRegisterManager::GetInstance().RegisterSlice(item.id, sliceProxy); + NativeRegisterManager::GetInstance().RegisterMenu(item); + } }; } // namespace OHOS -#define REGIST_NATIVE(nativeAppList, func) \ - const static OHOS::NativeRegister (STATIC_VAR)(nativeAppList, new func()) #define REGIST_SLICE(id, V, P) \ const static OHOS::SliceRegister (STATIC_VAR)(static_cast(id), new AbilitySliceProxy()) #define REGIST_MENU(id, V, P, icon, iconHexagon, label) \ const static OHOS::SliceRegister (STATIC_VAR)(static_cast(id), new AbilitySliceProxy(), \ icon, iconHexagon, label) +/* + * 目前支持两种模式的注册,如果需要扩展,请自行扩展AppItem的构造方法 + * 支持多语言注册以及多图标打包功能的注册示例:REGIST_MENU_EXT((AppItem{VIEW_OFFLINEVOICE, VOICE_RES_ID, + * VOICE_HEXAGON_ID, RES_PATH, HEXAGON_PATH, VOICE_LANGUAGE_ID, nullptr}), MainVocassistView, VocassistPresenter); + * 不支持多语言,一个图标使用一个文件的注册示例:REGIST_MENU_EXT((AppItem{VIEW_OFFLINEVOICE, PNG_APPLIST_VOCASSIST_IMAGE, + * PNG_APPLIST_DEFAULT_IMG, "语音助手", nullptr}), MainVocassistView, VocassistPresenter); + */ +#define REGIST_MENU_EXT(item, V, P) \ + const static OHOS::SliceRegister (STATIC_VAR)(item, new AbilitySliceProxy()) #endif // NATIVE_MANAGER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/UICardPageFactory.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/UICardPageFactory.h new file mode 100644 index 000000000..761e137c7 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/UICardPageFactory.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: UICardPageFactory + * Author: + * Create: 2025-06 + */ + +#ifndef UI_CARD_PAGE_FACTORY_H +#define UI_CARD_PAGE_FACTORY_H + +#include +#include "components/ui_card_page.h" +#include "UiConfig.h" + +namespace OHOS { +class UICardPageProxyInterface; +class UICardPageFactory { +public: + static UICardPageFactory& GetInstance() + { + static UICardPageFactory instance; + return instance; + } + void RegisterWatchDial(const uint16_t mode, const uint16_t id, UICardPageProxyInterface* uiCardPage); + UICardPage* CreateWatchDial(uint16_t mode, uint16_t id); + +private: + UICardPageFactory() {}; + ~UICardPageFactory() {}; + UICardPageFactory(const UICardPageFactory&) = delete; + UICardPageFactory &operator=(const UICardPageFactory&) = delete; + std::unordered_map watchDials_[static_cast(DIAL_DISPLAY_MODE_MAX)]; +}; + +class WatchDialRegister { +public: + WatchDialRegister(const uint16_t mode, const uint16_t id, UICardPageProxyInterface* uiCardPage) + { + UICardPageFactory::GetInstance().RegisterWatchDial(mode, id, uiCardPage); + } +}; + +class UICardPageProxyInterface { +public: + virtual UICardPage* CreateUICardPage() = 0; + UICardPageProxyInterface() = default; + virtual ~UICardPageProxyInterface() = default; + UICardPageProxyInterface(const UICardPageProxyInterface&) = delete; + UICardPageProxyInterface& operator=(const UICardPageProxyInterface&) = delete; + UICardPageProxyInterface(UICardPageProxyInterface&&) = delete; + UICardPageProxyInterface& operator=(UICardPageProxyInterface&&) = delete; +}; + +template +class WatchDialProxy : public UICardPageProxyInterface { +public: + UICardPage* CreateUICardPage() override + { + U* u = new U(); + UICardPage* page = dynamic_cast(u); + if (page == nullptr) { + delete u; + } + return page; + } +}; +} // namespace OHOS + +#define REGIST_WATCH_DIAL(mode, id, U) \ + const static OHOS::WatchDialRegister (STATIC_VAR)(static_cast(mode), static_cast(id), \ + new WatchDialProxy()) + +#endif // UI_CARD_PAGE_FACTORY_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/UiConfig.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/UiConfig.h index ffecde66d..b04a143ac 100644 --- a/code/sdk/application/wearable/nativeapp/nativelauncher/include/UiConfig.h +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/UiConfig.h @@ -31,6 +31,12 @@ namespace OHOS { DIAL_MAX, } DialId; + typedef enum { + DIAL_DISPLAY_MODE_MAIN = 0, + DIAL_DISPLAY_MODE_AOD, + DIAL_DISPLAY_MODE_MAX, + } DialDispayMode; + #ifndef UNUSED #define UNUSED(x) ((void)(x)) #endif @@ -379,6 +385,25 @@ namespace OHOS { static constexpr const char *PNG_PREVIEW_CARD_VIDEO = APP_RES_PATH"/noaudio_05.bin"; static constexpr const char *PNG_SET_DIAL_CLOCK = APP_RES_PATH"/DIAL_CLOCK.bin"; + + static constexpr const char *PNG_APPLIST_STOPWATCH_LOGO = APP_RES_PATH"/STOPWATCH_LOGO.bin"; + static constexpr const char *PNG_APPLIST_STOPWATCH_IMAGE = APP_RES_PATH"/STOPWATCH.bin"; + static constexpr const char *WEATHER_IMAGE = APP_RES_PATH"/WEATHER.bin"; + static constexpr const char *WEATHER_MAIN_ICON = APP_RES_PATH"/WEATHER_LOGO.bin"; + static constexpr const char *TIMER_IMAGE = APP_RES_PATH"/TIMER.bin"; + static constexpr const char *TIMER_MAIN_ICON = APP_RES_PATH"/TIMER_ICON.bin"; + static constexpr const char *DATE_IMAGE = APP_RES_PATH"/DATE.bin"; + static constexpr const char *DATE_MAIN_ICON = APP_RES_PATH"/DATE_LOGO.bin"; + static constexpr const char *FLASHLIGHT_IMAGE = APP_RES_PATH"/FLASHLIGHT.bin"; + static constexpr const char *FLASHLIGHT_MAIN_ICON = APP_RES_PATH"/FLASHLIGHT_LOGO.bin"; + static constexpr const char *SLEEP_IMAGE = APP_RES_PATH"/SLEEP.bin"; + static constexpr const char *SLEEP_ICON = APP_RES_PATH"/SLEEP_ICON.bin"; + static constexpr const char *BREATH_IMAGE = APP_RES_PATH"/BREATH.bin"; + static constexpr const char *BREATH_MAIN_ICON = APP_RES_PATH"/BREATH_ICON.bin"; + static constexpr const char *FINDPHONE_IMAGE = APP_RES_PATH"/FINDPHONE.bin"; + static constexpr const char *FINDPHONE_MAIN_ICON = APP_RES_PATH"/FINDPHONE_LOGO.bin"; + static constexpr const char *CAMERA_IMAGE = APP_RES_PATH"/CAMERA.bin"; + static constexpr const char *CAMERA_MAIN_ICON = APP_RES_PATH"/CAMERA_ICON.bin"; } #endif // UI_CONFIG_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_breath.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_breath.h new file mode 100644 index 000000000..ca668341c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_breath.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UIBreathResource + * Create: 2025-06-05 + */ +#ifndef UI_RESOURCE_BREATH_IMAGE_H +#define UI_RESOURCE_BREATH_IMAGE_H +#include +namespace OHOS { + static const int IMAGE_CONVERTER_TOOL_BREATH001 = 0x100001; + static const int IMAGE_CONVERTER_TOOL_BREATH002 = 0x100002; + static const int IMAGE_CONVERTER_TOOL_BREATH003 = 0x100003; + static const int IMAGE_CONVERTER_TOOL_BREATH004 = 0x100004; + static const int IMAGE_CONVERTER_TOOL_BREATH005 = 0x100005; + static const int IMAGE_CONVERTER_TOOL_BREATH006 = 0x100006; + static const int IMAGE_CONVERTER_TOOL_BREATH007 = 0x100007; + static const int IMAGE_CONVERTER_TOOL_BREATH008 = 0x100008; + static const int IMAGE_CONVERTER_TOOL_BREATH009 = 0x100009; + static const int IMAGE_CONVERTER_TOOL_BREATH010 = 0x10000a; + static const int IMAGE_CONVERTER_TOOL_BREATH011 = 0x10000b; + static const int IMAGE_CONVERTER_TOOL_BREATH012 = 0x10000c; + static const int IMAGE_CONVERTER_TOOL_BREATH013 = 0x10000d; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE001 = 0x10000e; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE002 = 0x10000f; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE003 = 0x100010; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE004 = 0x100011; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE005 = 0x100012; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE006 = 0x100013; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE007 = 0x100014; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE008 = 0x100015; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE009 = 0x100016; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE010 = 0x100017; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE011 = 0x100018; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE012 = 0x100019; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE013 = 0x10001a; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE014 = 0x10001b; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE015 = 0x10001c; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE016 = 0x10001d; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE017 = 0x10001e; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE018 = 0x10001f; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE019 = 0x100020; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE020 = 0x100021; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE021 = 0x100022; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE022 = 0x100023; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE023 = 0x100024; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE024 = 0x100025; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE025 = 0x100026; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE026 = 0x100027; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE027 = 0x100028; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE028 = 0x100029; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE029 = 0x10002a; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE030 = 0x10002b; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE031 = 0x10002c; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE032 = 0x10002d; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE033 = 0x10002e; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE034 = 0x10002f; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE035 = 0x100030; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE036 = 0x100031; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE037 = 0x100032; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE038 = 0x100033; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE039 = 0x100034; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE040 = 0x100035; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE041 = 0x100036; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE042 = 0x100037; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE043 = 0x100038; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE044 = 0x100039; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE045 = 0x10003a; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE046 = 0x10003b; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE047 = 0x10003c; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE048 = 0x10003d; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE049 = 0x10003e; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE050 = 0x10003f; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE051 = 0x100040; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE052 = 0x100041; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE053 = 0x100042; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE054 = 0x100043; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE055 = 0x100044; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE056 = 0x100045; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE057 = 0x100046; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE058 = 0x100047; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE059 = 0x100048; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE060 = 0x100049; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE061 = 0x10004a; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE062 = 0x10004b; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE063 = 0x10004c; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE064 = 0x10004d; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE065 = 0x10004e; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE066 = 0x10004f; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE067 = 0x100050; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE068 = 0x100051; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE069 = 0x100052; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE070 = 0x100053; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE071 = 0x100054; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE072 = 0x100055; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE073 = 0x100056; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE074 = 0x100057; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE075 = 0x100058; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE076 = 0x100059; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE077 = 0x10005a; + static const int IMAGE_CONVERTER_TOOL_INOREX_HALE078 = 0x10005b; +} // OHOS +#endif // UI_RESOURCE_BREATH_IMAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_camera.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_camera.h new file mode 100644 index 000000000..022ddfca0 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_camera.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UICameraResource + * Create: 2025-06-05 + */ +#ifndef UI_RESOURCE_CAMERA_H +#define UI_RESOURCE_CAMERA_H +#include +namespace OHOS { + static const int IMAGE_CONVERTER_TOOL_CAMERA_1 = 0x100001; + static const int IMAGE_CONVERTER_TOOL_CAMERA_2 = 0x100002; + static const int IMAGE_CONVERTER_TOOL_CAMERA_3 = 0x100003; + static const int IMAGE_CONVERTER_TOOL_CAMERA_4 = 0x100004; + static const int IMAGE_CONVERTER_TOOL_CAMERA_5 = 0x100005; + +} // OHOS +#endif // UI_RESOURCE_CAMERA_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_date.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_date.h new file mode 100644 index 000000000..0bccb8b0e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_date.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UIWeatherResource + * Create: 2025-06-10 + */ +#ifndef UI_RESOURCE_DATE_H +#define UI_RESOURCE_DATE_H +#include +namespace OHOS { + static const int DIR_MASK = 0xfff00000; + static const int PNG_MASK = 0x000fffff; + static const int IMAGE_CONVERTER_TOOL_DATE1 = 0x100001; + static const int IMAGE_CONVERTER_TOOL_DATE2 = 0x100002; + static const int IMAGE_CONVERTER_TOOL_DATE3 = 0x100003; + static const int IMAGE_CONVERTER_TOOL_DATE4 = 0x100004; + static const int IMAGE_CONVERTER_TOOL_DATE5 = 0x100005; + static const int IMAGE_CONVERTER_TOOL_DATE6 = 0x100006; + static const int IMAGE_CONVERTER_TOOL_DATE7 = 0x100007; + static const int IMAGE_CONVERTER_TOOL_DATE8 = 0x100008; +} // OHOS +#endif // UI_RESOURCE_DATE_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_findPhone.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_findPhone.h new file mode 100644 index 000000000..9a51cdf10 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_findPhone.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UIFindPhoneResource + * Create: 2025-2-13 + */ +#ifndef UI_RESOURCE_FINDPHONE_H +#define UI_RESOURCE_FINDPHONE_H +#include +namespace OHOS { + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_1 = 0x100001; + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_2 = 0x100002; + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_3 = 0x100003; + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_4 = 0x100004; + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5 = 0x100005; + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_6 = 0x100006; + static const int IMAGE_CONVERTER_TOOL_CONNECT_PHONE_7 = 0x100007; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE001 = 0x100008; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE002 = 0x100009; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE003 = 0x10000a; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE004 = 0x10000b; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE005 = 0x10000c; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE006 = 0x10000d; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE007 = 0x10000e; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE008 = 0x10000f; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE009 = 0x100010; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE010 = 0x100011; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE011 = 0x100012; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE012 = 0x100013; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE013 = 0x100014; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE014 = 0x100015; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE015 = 0x100016; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE016 = 0x100017; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE017 = 0x100018; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE018 = 0x100019; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE019 = 0x10001a; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE020 = 0x10001b; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE021 = 0x10001c; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE022 = 0x10001d; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE023 = 0x10001e; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE024 = 0x10001f; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE025 = 0x100020; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE026 = 0x100021; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE027 = 0x100022; + static const int IMAGE_CONVERTER_TOOL_FINDPHONE028 = 0x100023; +} // OHOS +#endif // UI_RESOURCE_FINDPHONE_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_sleep.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_sleep.h new file mode 100644 index 000000000..c5d369d71 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_sleep.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UISleepResource + * Create: 2025-06-05 + */ +#ifndef UI_RESOURCE_SLEEP_H +#define UI_RESOURCE_SLEEP_H +#include +namespace OHOS { + static const int IMAGE_CONVERTER_TOOL_BACKGROUND = 0x100001; + static const int IMAGE_CONVERTER_TOOL_BLACK_BG = 0x100002; + static const int IMAGE_CONVERTER_TOOL_BLUE_CIR = 0x100003; + static const int IMAGE_CONVERTER_TOOL_GREEN_CIR = 0x100004; + static const int IMAGE_CONVERTER_TOOL_NORECORD_SLEEP = 0x100005; + static const int IMAGE_CONVERTER_TOOL_ORANGE_CIR = 0x100006; + static const int IMAGE_CONVERTER_TOOL_RECORD_BG = 0x100007; + static const int IMAGE_CONVERTER_TOOL_RECORD_SLEEP = 0x100008; + static const int IMAGE_CONVERTER_TOOL_RED_CIR = 0x100009; + static const int IMAGE_CONVERTER_TOOL_SELECTEDTIME = 0x10000a; + static const int IMAGE_CONVERTER_TOOL_SELECTTIME = 0x10000b; + static const int IMAGE_CONVERTER_TOOL_SETTIMEBTN = 0x10000c; + static const int IMAGE_CONVERTER_TOOL_SETTING = 0x10000d; + static const int IMAGE_CONVERTER_TOOL_START_GRAY = 0x10000e; + static const int IMAGE_CONVERTER_TOOL_STAR_GRAY = 0x10000f; + static const int IMAGE_CONVERTER_TOOL_STAR_YELLOW = 0x100010; + static const int IMAGE_CONVERTER_TOOL_TIPS = 0x100011; +} // OHOS +#endif // UI_RESOURCE_SLEEP_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_string.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_string.h new file mode 100644 index 000000000..d7ca185f6 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_string.h @@ -0,0 +1,23 @@ +/* +* Copyright (c) xxxxxxxx Technologies Co., Ltd. 2021-2021. All rights reserved. +* Description: language +* Author: Graphic develop team +* Create: 2021-07-06 +*/ + +#ifndef UI_RESOURCE_STRING_H +#define UI_RESOURCE_STRING_H +#include +namespace OHOS { +enum UIResourceTextId : uint16_t { + STR_LANGUAGE = 0, + STR_MAX_ID = 1, +}; // UIResourceTextId + +enum FontLanguageId : uint8_t { + LANGUAGE_ID_ZH, + LANGUAGE_ID_EN, + LANGUAGE_ID_MAX +}; // UITextLanguageTextId +} +#endif /* UI_RESOURCE_STRING_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_timer.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_timer.h new file mode 100644 index 000000000..b9a462900 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_timer.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UITimerResource + * Create: 2025-06-05 + */ +#ifndef UI_RESOURCE_TIMER_H +#define UI_RESOURCE_TIMER_H +#include +namespace OHOS { + static const int IMAGE_CONVERTER_TOOL_BG_CIR = 0x100001; + static const int IMAGE_CONVERTER_TOOL_TIMER_1 = 0x100002; + static const int IMAGE_CONVERTER_TOOL_TIMER_15 = 0x100003; + static const int IMAGE_CONVERTER_TOOL_TIMER_3 = 0x100004; + static const int IMAGE_CONVERTER_TOOL_TIMER_30 = 0x100005; + static const int IMAGE_CONVERTER_TOOL_TIMER_BEGIN_GRAY = 0x100006; + static const int IMAGE_CONVERTER_TOOL_TIMER_BEGIN_ORANGE = 0x100007; + static const int IMAGE_CONVERTER_TOOL_TIMER_BG = 0x100008; + static const int IMAGE_CONVERTER_TOOL_TIMER_EXIT = 0x100009; + static const int IMAGE_CONVERTER_TOOL_TIMER_PAUSE = 0x10000a; + static const int IMAGE_CONVERTER_TOOL_TIMER_PAUSE_ORANGE = 0x10000b; + static const int IMAGE_CONVERTER_TOOL_TIMER_PBG = 0x10000c; + static const int IMAGE_CONVERTER_TOOL_TIMER_PLAY = 0x10000d; + static const int IMAGE_CONVERTER_TOOL_TIMER_POINTER = 0x10000e; + static const int IMAGE_CONVERTER_TOOL_TIMER_RESTART = 0x10000f; + static const int IMAGE_CONVERTER_TOOL_TIMER_USER = 0x100010; +} // OHOS +#endif // UI_RESOURCE_TIMER_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_weather.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_weather.h new file mode 100644 index 000000000..874ba3f93 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_resource_weather.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: UIWeatherResource + * Create: 2025-06-05 + */ +#ifndef UI_RESOURCE_WEATHER_IMAGE_H +#define UI_RESOURCE_WEATHER_IMAGE_H +#include +namespace OHOS { +static const int IMAGE_CONVERTER_TOOL_WEATHER00 = 0x100001; +static const int IMAGE_CONVERTER_TOOL_WEATHER01 = 0x100002; +static const int IMAGE_CONVERTER_TOOL_WEATHER02 = 0x100003; +static const int IMAGE_CONVERTER_TOOL_WEATHER03 = 0x100004; +static const int IMAGE_CONVERTER_TOOL_WEATHER04 = 0x100005; +static const int IMAGE_CONVERTER_TOOL_WEATHER05 = 0x100006; +static const int IMAGE_CONVERTER_TOOL_WEATHER06 = 0x100007; +static const int IMAGE_CONVERTER_TOOL_WEATHER07 = 0x100008; +static const int IMAGE_CONVERTER_TOOL_WEATHER08 = 0x100009; +static const int IMAGE_CONVERTER_TOOL_WEATHER09 = 0x10000a; +static const int IMAGE_CONVERTER_TOOL_WEATHER10 = 0x10000b; +static const int IMAGE_CONVERTER_TOOL_WEATHER11 = 0x10000c; +static const int IMAGE_CONVERTER_TOOL_WEATHER12 = 0x10000d; +static const int IMAGE_CONVERTER_TOOL_WEATHER13 = 0x10000e; +static const int IMAGE_CONVERTER_TOOL_WEATHER14 = 0x10000f; +static const int IMAGE_CONVERTER_TOOL_WEATHER15 = 0x100010; +static const int IMAGE_CONVERTER_TOOL_WEATHER16 = 0x100011; +static const int IMAGE_CONVERTER_TOOL_WEATHER17 = 0x100012; +static const int IMAGE_CONVERTER_TOOL_WEATHER18 = 0x100013; +static const int IMAGE_CONVERTER_TOOL_WEATHER19 = 0x100014; +static const int IMAGE_CONVERTER_TOOL_WEATHER20 = 0x100015; +static const int IMAGE_CONVERTER_TOOL_WEATHER21 = 0x100016; +static const int IMAGE_CONVERTER_TOOL_WEATHER22 = 0x100017; +static const int IMAGE_CONVERTER_TOOL_WEATHER23 = 0x100018; +static const int IMAGE_CONVERTER_TOOL_WEATHER24 = 0x100019; +static const int IMAGE_CONVERTER_TOOL_WEATHER25 = 0x10001a; +static const int IMAGE_CONVERTER_TOOL_WEATHER26 = 0x10001b; +static const int IMAGE_CONVERTER_TOOL_WEATHER27 = 0x10001c; +static const int IMAGE_CONVERTER_TOOL_WEATHER28 = 0x10001d; +static const int IMAGE_CONVERTER_TOOL_WEATHER29 = 0x10001e; +static const int IMAGE_CONVERTER_TOOL_WEATHER30 = 0x10001f; +static const int IMAGE_CONVERTER_TOOL_WEATHER31 = 0x100020; +static const int IMAGE_CONVERTER_TOOL_WEATHER32 = 0x100021; +static const int IMAGE_CONVERTER_TOOL_WEATHER33 = 0x100022; +static const int IMAGE_CONVERTER_TOOL_WEATHER34 = 0x100023; +static const int IMAGE_CONVERTER_TOOL_WEATHER35 = 0x100024; +static const int IMAGE_CONVERTER_TOOL_WEATHER36 = 0x100025; +static const int IMAGE_CONVERTER_TOOL_WEATHER37 = 0x100026; +static const int IMAGE_CONVERTER_TOOL_WEATHER38 = 0x100027; +static const int IMAGE_CONVERTER_TOOL_WEATHER39 = 0x100028; +static const int IMAGE_CONVERTER_TOOL_WEATHER40 = 0x100029; +static const int IMAGE_CONVERTER_TOOL_WEATHER41 = 0x10002a; +static const int IMAGE_CONVERTER_TOOL_WEATHER42 = 0x10002b; +static const int IMAGE_CONVERTER_TOOL_WEATHER43 = 0x10002c; +static const int IMAGE_CONVERTER_TOOL_WEATHER44 = 0x10002d; +static const int IMAGE_CONVERTER_TOOL_WEATHER45 = 0x10002e; +static const int IMAGE_CONVERTER_TOOL_WEATHER46 = 0x10002f; +static const int IMAGE_CONVERTER_TOOL_WEATHER47 = 0x100030; +static const int IMAGE_CONVERTER_TOOL_WEATHER48 = 0x100031; +static const int IMAGE_CONVERTER_TOOL_WEATHER49 = 0x100032; +static const int IMAGE_CONVERTER_TOOL_WEATHER50 = 0x100033; +static const int IMAGE_CONVERTER_TOOL_WEATHER51 = 0x100034; +static const int IMAGE_CONVERTER_TOOL_WEATHER52 = 0x100035; +static const int IMAGE_CONVERTER_TOOL_WEATHER53 = 0x100036; +static const int IMAGE_CONVERTER_TOOL_WEATHER54 = 0x100037; +static const int IMAGE_CONVERTER_TOOL_WEATHER55 = 0x100038; +static const int IMAGE_CONVERTER_TOOL_WEATHER56 = 0x100039; +static const int IMAGE_CONVERTER_TOOL_WEATHER57 = 0x10003a; +static const int IMAGE_CONVERTER_TOOL_WEATHER58 = 0x10003b; +static const int IMAGE_CONVERTER_TOOL_WEATHER59 = 0x10003c; +static const int IMAGE_CONVERTER_TOOL_WEATHER60 = 0x10003d; +static const int IMAGE_CONVERTER_TOOL_WEATHER61 = 0x10003e; +static const int IMAGE_CONVERTER_TOOL_WEATHER62 = 0x10003f; +static const int IMAGE_CONVERTER_TOOL_WEATHER63 = 0x100040; +static const int IMAGE_CONVERTER_TOOL_WEATHER64 = 0x100041; +static const int IMAGE_CONVERTER_TOOL_WEATHER65 = 0x100042; +static const int IMAGE_CONVERTER_TOOL_WEATHER66 = 0x100043; +static const int IMAGE_CONVERTER_TOOL_WEATHER67 = 0x100044; +static const int IMAGE_CONVERTER_TOOL_WEATHER68 = 0x100045; +static const int IMAGE_CONVERTER_TOOL_WEATHER69 = 0x100046; +static const int IMAGE_CONVERTER_TOOL_WEATHER70 = 0x100047; +static const int IMAGE_CONVERTER_TOOL_WEATHER71 = 0x100048; +static const int IMAGE_CONVERTER_TOOL_WEATHER72 = 0x100049; +static const int IMAGE_CONVERTER_TOOL_WEATHER73 = 0x10004a; +static const int IMAGE_CONVERTER_TOOL_WEATHER74 = 0x10004b; +static const int IMAGE_CONVERTER_TOOL_WEATHER75 = 0x10004c; +static const int IMAGE_CONVERTER_TOOL_WEATHER76 = 0x10004d; +static const int IMAGE_CONVERTER_TOOL_WEATHER77 = 0x10004e; +} // OHOS +#endif // UI_RESOURCE_IMAGE_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_stopwatch_resource.h b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_stopwatch_resource.h new file mode 100644 index 000000000..56019f1cd --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/include/ui_stopwatch_resource.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved. + * Description: UIStopWatchResource + * Create: 2025-06-05 + */ + +#ifndef UI_STOPWATCH_RESOURCE_H +#define UI_STOPWATCH_RESOURCE_H + +#include + +namespace OHOS { +static const int IMAGE_STOPWATCH_STOPWATCH01 = 0x100001; +static const int IMAGE_STOPWATCH_STOPWATCH02 = 0x100002; +static const int IMAGE_STOPWATCH_STOPWATCH04 = 0x100003; +static const int IMAGE_STOPWATCH_STOPWATCH06 = 0x100004; +static const int IMAGE_STOPWATCH_STOPWATCH08 = 0x100005; +static const int IMAGE_STOPWATCH_STOPWATCH10 = 0x100006; +static const int IMAGE_STOPWATCH_STOPWATCH12 = 0x100007; +static const int IMAGE_STOPWATCH_STOPWATCH14 = 0x100008; +static const int IMAGE_STOPWATCH_STOPWATCH16 = 0x100009; +static const int IMAGE_STOPWATCH_STOPWATCH19 = 0x10000a; +static const int IMAGE_STOPWATCH_STOPWATCH20 = 0x10000b; +} // OHOS +#endif // UI_STOPWATCH_RESOURCE_H diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeLauncher.cpp b/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeLauncher.cpp index 4f3804675..be0ab5890 100644 --- a/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeLauncher.cpp +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeLauncher.cpp @@ -18,20 +18,23 @@ #include "SliceProxy.h" #include "AbilitySliceProxy.h" #include "wearable_log.h" -#include "CallerLogModel.h" -#include "ActivityModel.h" -#include "HeartModel.h" -#include "PlayersModel.h" -#include "HealthModel.h" -#include "VocassistModel.h" -#include "ScreenModels.h" -#include "BluetoothHeadsetEvent.h" +#include "callerlog/CallerLogModel.h" +#include "activity/ActivityModel.h" +#include "heartrate/HeartModel.h" +#include "player/PlayersModel.h" +#include "main/HealthModel.h" +#include "sports/SportsModel.h" +#include "offlinevoice/VocassistModel.h" +#include "screensetting/ScreenModels.h" +#include "bluetooth/BluetoothHeadsetEvent.h" #include "graphic_hardware_config.h" #include "graphic_service.h" #include "common/graphic_startup.h" #ifdef JS_ENABLE #include "product_adapter.h" #endif +#include "RecentManager.h" +#include "PageTransitionMgr.h" namespace OHOS { @@ -48,13 +51,15 @@ void NativeLauncher::InitNativeLauncher() { #ifdef JS_ENABLE ACELite::ProductAdapter::SetScreenSize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + ACELite::ProductAdapter::SetDefaultFontStyle( + DEFAULT_VECTOR_FONT_FILENAME, ACELite::ProductAdapter::GetDefaultFontSize()); #endif GraphicStartUp::InitFontEngine(MEM_POOL_UI_FONT, MEM_POOL_UI_FONT_SIZE, OHOS::VECTOR_FONT_DIR, DEFAULT_VECTOR_FONT_FILENAME); WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeLauncher::InitNativeLauncher"); // 初始化所有预加载slice InitBtHeadsetEvent(); // 蓝牙ct和tg适配初始化 - InitAllNativeSlices(); + NativeRegisterManager::GetInstance().InitAllNativesSlices(); CallerLogModel::GetInstance()->InitPhoneService(); PlayersModel::GetInstance()->AudioInit(); ActivityModel::GetInstance()->Init(); @@ -62,22 +67,18 @@ void NativeLauncher::InitNativeLauncher() VocassistModel::GetInstance()->Init(); HeartModel::GetInstance()->Init(); BluetoothModel::GetInstance()->Init(); + SportsModel::GetInstance()->Init(); // 初始化默认首页 ScreenModels::GetInstance()->PreLoadAppimages(); NativeAbility::GetInstance().SetDefaultSliceId(VIEW_MAIN_SAMPLE); -} -void NativeLauncher::InitAllNativeSlices(void) -{ - Graphic::Vector& natives = NativeRegisterManager::GetInstance().GetNatives(); - for(uint16_t index =0; index < natives.Size(); index++) { - if (static_cast(natives[index].type) >= VIEW_MAX_INTER_APP) { - continue; - } - natives[index].native->InitSlice(); - } - NativeRegisterManager::GetInstance().InitAllNativesSlices(); - return; + RecentManager::GetInstance()->SetDirPath("system/recent/"); + RecentManager::GetInstance()->AddToBlackList(VIEW_AOD); + RecentManager::GetInstance()->AddToBlackList(VIEW_RECENT_APP); + RecentManager::GetInstance()->AddToBlackList(VIEW_APPLIST); + RecentManager::GetInstance()->AddToBlackList(VIEW_MAIN_SAMPLE); + RecentManager::GetInstance()->SetMaxSize(5); // 5: max number of recent apps. + PageTransitionMgr::GetInstance().SetRecentMinPeriod(1000); // 1000: min period } } diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeRegisterManager.cpp b/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeRegisterManager.cpp index 6ea82ddfb..bfd2119e0 100644 --- a/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeRegisterManager.cpp +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/src/NativeRegisterManager.cpp @@ -8,15 +8,6 @@ #include "NativeRegisterManager.h" namespace OHOS { -NativeRegisterManager::~NativeRegisterManager() -{ - for(uint16_t i =0; i < natives_.Size(); i++) { - if (natives_[i].native != nullptr) { - delete natives_[i].native; - natives_[i].native = nullptr; - } - } -} void NativeRegisterManager::InitAllNativesSlices() { @@ -26,34 +17,11 @@ void NativeRegisterManager::InitAllNativesSlices() } } -Graphic::Vector& NativeRegisterManager::GetNatives() -{ - return natives_; -} - List& NativeRegisterManager::GetNativeAppLists() { return nativeAppLists_; } -void NativeRegisterManager::RegisterNative(const AppItem &nativeAppList, NativeRegisterCallback* native) -{ - if (native == nullptr) { - GRAPHIC_LOGE("native can't be nullptr"); - return; - } - for(uint16_t i = 0; i < natives_.Size(); i++) { - if (natives_[i].type == (NativeRegisterType)nativeAppList.id) { - GRAPHIC_LOGE("RegisterNative failed because type %d already registered", nativeAppList.id); - return; - } - } - GRAPHIC_LOGI("register native %d", nativeAppList.id); - NativeMap map = {(NativeRegisterType)nativeAppList.id, native}; - natives_.PushBack(map); - nativeAppLists_.PushBack(nativeAppList); -} - void NativeRegisterManager::RegisterSlice(const uint16_t id, SliceProxy* sliceProxy) { if (sliceProxy == nullptr) { @@ -72,7 +40,7 @@ void NativeRegisterManager::RegisterSlice(const uint16_t id, SliceProxy* slicePr void NativeRegisterManager::RegisterMenu(const uint16_t id, const char *icon, const char *iconHexagon, const char *label) { - AppItem item = {id, icon, icon, iconHexagon, label, nullptr}; + AppItem item = {id, icon, iconHexagon, label, nullptr}; ListNode* appNode = nativeAppLists_.Head(); while (appNode != nativeAppLists_.End()) { if (id == appNode->data_.id) { @@ -88,6 +56,23 @@ void NativeRegisterManager::RegisterMenu(const uint16_t id, const char *icon, co nativeAppLists_.PushBack(item); } +void NativeRegisterManager::RegisterMenu(const AppItem &item) +{ + ListNode* appNode = nativeAppLists_.Head(); + while (appNode != nativeAppLists_.End()) { + if (item.id == appNode->data_.id) { + GRAPHIC_LOGE("Register menu failed because id %d already registered.", item.id); + return; + } + if (item.id < appNode->data_.id) { + nativeAppLists_.Insert(appNode, item); + return; + } + appNode = appNode->next_; + } + nativeAppLists_.PushBack(item); +} + bool NativeRegisterManager::IsSliceIdExist(AppViewId id) { for (uint16_t index = 0; index < slices_.Size(); index++) { diff --git a/code/sdk/application/wearable/nativeapp/nativelauncher/src/UICardPageFactory.cpp b/code/sdk/application/wearable/nativeapp/nativelauncher/src/UICardPageFactory.cpp new file mode 100644 index 000000000..649aa2f3c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativelauncher/src/UICardPageFactory.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: UICardPageFactory + * Author: + * Create: 2025-06 + */ + +#include "UICardPageFactory.h" +#include "wearable_log.h" + +namespace OHOS { + +void UICardPageFactory::RegisterWatchDial(const uint16_t mode, const uint16_t id, UICardPageProxyInterface* uiCardPage) +{ + if (mode >= DIAL_DISPLAY_MODE_MAX || uiCardPage == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Can't register watch dial using invalid mode or proxy %d-%p", + mode, uiCardPage); + return; + } + if (watchDials_[mode].find(id) != watchDials_[mode].end()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Watch dial mode %d id:%d has already been registered", mode, id); + return; + } else { + watchDials_[mode].insert({id, uiCardPage}); + } +} + +UICardPage* UICardPageFactory::CreateWatchDial(uint16_t mode, uint16_t id) +{ + if (mode >= DIAL_DISPLAY_MODE_MAX ) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Can't create watch dial using invalid mode %d", mode); + return nullptr; + } + + auto it = watchDials_[mode].find(id); + if (it != watchDials_[mode].end()) { + return it->second->CreateUICardPage(); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Watch dial mode %d id:%d was not registered", mode, id); + return nullptr; + } +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityModel.cpp index a47bb9a77..a68a6c7e5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityModel.cpp @@ -5,7 +5,7 @@ * Create: 2022-03-02 */ -#include "ActivityModel.h" +#include "activity/ActivityModel.h" #include #include "iostream" #include @@ -17,9 +17,9 @@ #include "graphic_timer.h" #include "securec.h" #include "broadcast_service.h" -#include "MainClockView.h" -#include "IndoorWalkPresenter.h" -#include "ActivityWeekView.h" +#include "clock/MainClockView.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "activity/ActivityWeekView.h" #include "graphic_service.h" #ifdef __cplusplus @@ -76,32 +76,50 @@ static void RefreshStepControls(const uint32_t &value, const uint16 &msgId) { MainClockView *mainClockView = OHOS::MainClockView::GetInstance(); if (mainClockView != nullptr) { - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&MainClockView::RefreshStep, mainClockView, value)); + GraphicService::GetInstance()->PostGraphicEvent([value]() { + if (OHOS::MainClockView::GetInstance() != nullptr) { + OHOS::MainClockView::GetInstance()->RefreshStep(value); + } + }); } IndoorWalkPresenter *indoorWalkPresenter = OHOS::IndoorWalkPresenter::GetInstance(); if (indoorWalkPresenter != nullptr) { - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&IndoorWalkPresenter::ModifiesSteps, indoorWalkPresenter, value)); + GraphicService::GetInstance()->PostGraphicEvent([value]() { + if (OHOS::IndoorWalkPresenter::GetInstance() != nullptr) { + OHOS::IndoorWalkPresenter::GetInstance()->ModifiesSteps(value); + } + }); } ActivityWeekView *activityWeekView = OHOS::ActivityWeekView::GetInstance(); if (activityWeekView == nullptr) { return; } - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&ActivityWeekView::RefreshSteps, activityWeekView, value)); + GraphicService::GetInstance()->PostGraphicEvent([value]() { + if (OHOS::ActivityWeekView::GetInstance() != nullptr) { + OHOS::ActivityWeekView::GetInstance()->RefreshSteps(value); + } + }); if (msgId == TOPIC_EVENT_STEPDATA_UPDATE) { - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&ActivityWeekView::RefreshTodayView, activityWeekView, value)); + GraphicService::GetInstance()->PostGraphicEvent([value]() { + if (OHOS::ActivityWeekView::GetInstance() != nullptr) { + OHOS::ActivityWeekView::GetInstance()->RefreshTodayView(value); + } + }); } else if (msgId == TOPIC_EVENT_NEXTDAY_UPDATE) { - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&ActivityWeekView::InitAvgStep, activityWeekView)); + GraphicService::GetInstance()->PostGraphicEvent([]() { + if (OHOS::ActivityWeekView::GetInstance() != nullptr) { + OHOS::ActivityWeekView::GetInstance()->InitAvgStep(); + } + }); if (OHOS::ActivityModel::GetInstance()->GetWeekToday() == MONDAY_STEP_COUNTER) { - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&ActivityWeekView::InitWeekView, activityWeekView)); + GraphicService::GetInstance()->PostGraphicEvent([]() { + if (OHOS::ActivityWeekView::GetInstance() != nullptr) { + OHOS::ActivityWeekView::GetInstance()->InitWeekView(); + } + }); } } } @@ -123,8 +141,11 @@ static void Notify(void *args, const Topic topic, Request* request) counter += *(uint32_t *)request->data; OHOS::ActivityModel::GetInstance()->ReviseStepCounter(counter); - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&ActivityModel::SetStepData, ActivityModel::GetInstance(), counter)); + GraphicService::GetInstance()->PostGraphicEvent([counter]() { + if (ActivityModel::GetInstance() != nullptr) { + ActivityModel::GetInstance()->SetStepData(counter); + } + }); RefreshStepControls(counter, TOPIC_EVENT_STEPDATA_UPDATE); } @@ -216,7 +237,7 @@ void SaveEveryMinCallback(void* data) GraphicService::GetInstance()->PostGraphicEvent(std::bind(SaveEveryMinCallbackProc, data)); } -void ActivityModel::SetStepData(uint32_t &value) +void ActivityModel::SetStepData(const uint32_t &value) { g_stepData1.weekSteps[weekToday] = value; // 第一次上报数据后打开定时器 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityPresenter.cpp index c381e72e9..4603a46c0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityPresenter.cpp @@ -9,13 +9,13 @@ #include "gfx_utils/graphic_types.h" #include "components/ui_checkbox.h" #include "UiConfig.h" -#include "ActivityPresenter.h" +#include "activity/ActivityPresenter.h" #include "NativeRegisterManager.h" namespace OHOS { REGIST_SLICE(VIEW_MAIN_ACTIVITY, MainActivityView, ActivityPresenter); - + static ActivityPresenter *g_pActivityPresenter = nullptr; ActivityPresenter::ActivityPresenter() { @@ -36,7 +36,7 @@ ActivityPresenter *ActivityPresenter::GetInstance() bool ActivityPresenter::OnDrag(UIView& view, const DragEvent& event) { - WEARABLE_LOGD("WEARABLE_LOG_MODULE_APP", "ActivityPresenter::OnDrag"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ActivityPresenter::OnDrag"); if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) { if (strcmp(view.GetViewId(), ACTIVITY_WEEK_VIEW) == 0) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ActivityPresenter::OnDrag on ACTIVITY_WEEK_VIEW"); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityWeekView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityWeekView.cpp index 3e880d409..dfafe79ba 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityWeekView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/ActivityWeekView.cpp @@ -5,8 +5,8 @@ * Create: 2021-10-18 */ -#include "ActivityWeekView.h" -#include "ActivityPresenter.h" +#include "activity/ActivityWeekView.h" +#include "activity/ActivityPresenter.h" #include "common/image_cache_manager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/MainActivityView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/MainActivityView.cpp index d9f307527..a119b20ec 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/src/MainActivityView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/activity/src/MainActivityView.cpp @@ -6,7 +6,7 @@ */ #include "components/ui_label.h" -#include "MainActivityView.h" +#include "activity/MainActivityView.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardAdapter.cpp index d92f38ddb..b62235fec 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardAdapter.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-18 */ -#include "AddCardAdapter.h" +#include "add_card/AddCardAdapter.h" namespace OHOS { AddCardAdapter::AddCardAdapter() {} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardItem.cpp b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardItem.cpp index 67e287ec8..c6453a442 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardItem.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardItem.cpp @@ -1,5 +1,5 @@ -#include "AddCardItem.h" -#include "AddCardPresenter.h" +#include "add_card/AddCardItem.h" +#include "add_card/AddCardPresenter.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardModel.cpp index fa052decb..52a621627 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardModel.cpp @@ -5,7 +5,7 @@ * Create: 2021-11-23 */ -#include "AddCardModel.h" +#include "add_card/AddCardModel.h" #include "kv_store.h" #include "securec.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardPresenter.cpp index b72e0dcfc..59474f5d9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardPresenter.cpp @@ -5,9 +5,9 @@ * Create: 2021-11-23 */ -#include "AddCardView.h" -#include "AddCardModel.h" -#include "AddCardPresenter.h" +#include "add_card/AddCardView.h" +#include "add_card/AddCardModel.h" +#include "add_card/AddCardPresenter.h" #include "hal_tick.h" #include "NativeRegisterManager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardView.cpp index abb1a6376..4828ac3fe 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/add_card/src/AddCardView.cpp @@ -6,8 +6,8 @@ */ #include -#include "AddCardView.h" -#include "AddCardPresenter.h" +#include "add_card/AddCardView.h" +#include "add_card/AddCardPresenter.h" namespace OHOS { AddCardView::AddCardView() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmClockModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmClockModel.cpp index 4edb2149a..e2863a5a4 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmClockModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmClockModel.cpp @@ -12,12 +12,12 @@ #include "samgr_lite.h" #include "graphic_mutex.h" #include "UiConfig.h" -#include "AlarmClockModel.h" -#include "AlarmPopUpPresenter.h" +#include "alarm/AlarmClockModel.h" +#include "alarm/AlarmPopUpPresenter.h" #include "graphic_service.h" -#include "PlayersModel.h" -#include "PhoneService.h" -#include "ui_service.h" +#include "player/PlayersModel.h" +#include "phoneservice/PhoneService.h" +#include "uiservice/ui_service.h" #ifdef __cplusplus extern "C" { @@ -456,8 +456,7 @@ void AlarmClockModel::SetDelayAlarm(uint8_t alarm) } currentAlarm[clockListener]->delayNum++; clockQueueMsg->eventType = EVENT_ALARM_RING_DELAY; - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmClockModel::ButtonStatusRing clockQueueMsg->eventType is %u", - clockQueueMsg->eventType); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmClockModel::SetDelayAlarm %u %u", clockQueueMsg->eventType, alarm); (clockQueueMsg->data).value = alarm; AlmmgrAlarmClockEventProcess(clockQueueMsg); return; @@ -471,8 +470,7 @@ void AlarmClockModel::SetCancelAlarm(uint8_t alarm) return; } clockQueueMsg->eventType = EVENT_ALARM_RING_CANCEL; - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmClockModel::ButtonStatusRing clockQueueMsg->eventType is %u", - clockQueueMsg->eventType); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmClockModel::SetCancelAlarm %u %u", clockQueueMsg->eventType, alarm); (clockQueueMsg->data).value = alarm; AlmmgrAlarmClockEventProcess(clockQueueMsg); return; @@ -805,8 +803,9 @@ int AlarmClockModel::AlarmPlayerStart(void) void AlarmPlayerCallbackImpl::OnPlaybackComplete() { - GraphicService::GetInstance()->PostGraphicEvent( - std::bind(&OHOS::AlarmClockModel::DeactAudioInter, OHOS::AlarmClockModel::GetInstance())); + /* msg center已处理,此处注释 */ + // GraphicService::GetInstance()->PostGraphicEvent( + // std::bind(&OHOS::AlarmClockModel::DeactAudioInter, OHOS::AlarmClockModel::GetInstance())); } uint16_t AlarmClockModel::JudgePreSlice(void) diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmCloseRingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmCloseRingView.cpp index e69e8b6ef..c10fa4875 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmCloseRingView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmCloseRingView.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-11 */ -#include "AlarmCloseRingView.h" +#include "alarm/AlarmCloseRingView.h" #include "common/screen.h" #include "components/ui_label.h" #include "components/ui_label_button.h" @@ -13,8 +13,8 @@ #include "ohos_timer.h" #include "graphic_timer.h" -#include "AlarmPopUpPresenter.h" -#include "PhoneService.h" +#include "alarm/AlarmPopUpPresenter.h" +#include "phoneservice/PhoneService.h" namespace OHOS { #define CLOSE "关闭" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmConfigView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmConfigView.cpp index 171caef71..97141e68b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmConfigView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmConfigView.cpp @@ -5,10 +5,10 @@ * Create: 2021-09-11 */ -#include "AlarmConfigView.h" +#include "alarm/AlarmConfigView.h" #include "UiConfig.h" #include -#include "AlarmPresenter.h" +#include "alarm/AlarmPresenter.h" #include #include "color.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmJudgeView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmJudgeView.cpp index 9e6c2ea72..3ec474d30 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmJudgeView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmJudgeView.cpp @@ -5,10 +5,10 @@ * Create: 2021-09-11 */ -#include "AlarmJudgeView.h" +#include "alarm/AlarmJudgeView.h" #include "UiConfig.h" #include -#include "AlarmPresenter.h" +#include "alarm/AlarmPresenter.h" namespace OHOS { #define DELETE_INETERFACES "是否删除此闹钟?" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmMaxClock.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmMaxClock.cpp index ed0e5aef6..5bc2c3949 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmMaxClock.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmMaxClock.cpp @@ -5,14 +5,14 @@ * Create: 2021-09-11 */ -#include "AlarmMaxClock.h" +#include "alarm/AlarmMaxClock.h" #include "UiConfig.h" #include #include "ohos_timer.h" #include "graphic_timer.h" -#include "AlarmPresenter.h" -#include "MainAlarmView.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/MainAlarmView.h" namespace OHOS { #define MAX_INETERFACES "当前闹钟个数已达上限" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmNewTimeView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmNewTimeView.cpp index 93a205b55..d13509d96 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmNewTimeView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmNewTimeView.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-11 */ -#include "AlarmNewTimeView.h" +#include "alarm/AlarmNewTimeView.h" #include "common/screen.h" #include "components/ui_label.h" #include "components/ui_label_button.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpPresenter.cpp index 2ae51d223..972cc0e3e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpPresenter.cpp @@ -6,11 +6,11 @@ */ -#include "AlarmPopUpPresenter.h" -#include "MainAlarmView.h" +#include "alarm/AlarmPopUpPresenter.h" +#include "alarm/MainAlarmView.h" #include "ChangeSliceListener.h" -#include "PhoneService.h" -#include "PlayersModel.h" +#include "phoneservice/PhoneService.h" +#include "player/PlayersModel.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpView.cpp index 29ad7f6fb..3d54a5ce9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPopUpView.cpp @@ -5,8 +5,8 @@ * Create: 2021-09-11 */ -#include "AlarmPopUpView.h" -#include "AlarmPopUpPresenter.h" +#include "alarm/AlarmPopUpView.h" +#include "alarm/AlarmPopUpPresenter.h" #include "common/screen.h" #include "components/ui_label.h" #include "components/ui_label_button.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPresenter.cpp index 29b88dd08..c0e1985b1 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmPresenter.cpp @@ -6,8 +6,8 @@ */ -#include "AlarmPresenter.h" -#include "MainAlarmView.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/MainAlarmView.h" #include "NativeRegisterManager.h" #include "ChangeSliceListener.h" #include "string" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmRingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmRingView.cpp index bb449321c..26c94cdb4 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmRingView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmRingView.cpp @@ -5,15 +5,15 @@ * Create: 2021-09-11 */ -#include "AlarmRingView.h" +#include "alarm/AlarmRingView.h" #include "common/screen.h" #include "components/ui_label.h" #include "components/ui_label_button.h" #include -#include "AlarmPopUpPresenter.h" +#include "alarm/AlarmPopUpPresenter.h" #include "ohos_timer.h" #include "graphic_timer.h" -#include "PhoneService.h" +#include "phoneservice/PhoneService.h" namespace OHOS { #define RING_AGAIN "响铃将在十分钟后再次响起" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetTimeView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetTimeView.cpp index 6d04e328f..bf5f07d11 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetTimeView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetTimeView.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-11 */ -#include "AlarmSetTimeView.h" +#include "alarm/AlarmSetTimeView.h" #include "common/screen.h" #include "components/ui_label.h" #include "components/ui_label_button.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetWeekView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetWeekView.cpp index 397430b78..673317760 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetWeekView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/AlarmSetWeekView.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-11 */ -#include "AlarmSetWeekView.h" +#include "alarm/AlarmSetWeekView.h" #include "common/screen.h" #include "components/ui_digital_clock.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/MainAlarmView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/MainAlarmView.cpp index 430334b14..1f56be330 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/MainAlarmView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarm/src/MainAlarmView.cpp @@ -5,10 +5,10 @@ * Create: 2021-09-11 */ -#include "MainAlarmView.h" +#include "alarm/MainAlarmView.h" #include "UiConfig.h" #include "ui_label_button.h" -#include "PhoneService.h" +#include "phoneservice/PhoneService.h" namespace OHOS { static MainAlarmView *g_MainAlarmView = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/src/AlarmClockManage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/src/AlarmClockManage.cpp index 5ce9f8636..a87b03af3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/src/AlarmClockManage.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/src/AlarmClockManage.cpp @@ -19,9 +19,9 @@ #include "broadcast_service.h" #include "samgr_lite.h" -#include "RtcService.h" -#include "AlarmClockTimerConfig.h" -#include "AlarmClockManage.h" +#include "rtcservice/RtcService.h" +#include "alarmclocktimerconfig/AlarmClockTimerConfig.h" +#include "alarmclockmanage/AlarmClockManage.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/src/AlarmClockTimerConfig.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/src/AlarmClockTimerConfig.cpp index 135ebd78d..c5c02282e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/src/AlarmClockTimerConfig.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/src/AlarmClockTimerConfig.cpp @@ -16,7 +16,7 @@ #include "thread_adapter.h" #include "graphic_service.h" -#include "AlarmClockTimerConfig.h" +#include "alarmclocktimerconfig/AlarmClockTimerConfig.h" #ifdef __cplusplus extern "C" { @@ -102,8 +102,9 @@ void AlarmScan(void *arg) if ((g_alarmCtrA.callback != nullptr) && (g_alarmCtrA.info.hour == curTime.tm_hour) && (g_alarmCtrA.info.minute == curTime.tm_min)) { - g_alarmCtrA.callback(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmA Called %d %d", curTime.tm_hour, curTime.tm_min); g_alarmCtrA.state = ALARM_STATUS_CREATED; + g_alarmCtrA.callback(); } } @@ -112,8 +113,9 @@ void AlarmScan(void *arg) (g_alarmCtrB.info.week == curTime.tm_wday) && (g_alarmCtrB.info.hour == curTime.tm_hour) && (g_alarmCtrB.info.minute == curTime.tm_min)) { - g_alarmCtrB.callback(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmB Called %d %d", curTime.tm_hour, curTime.tm_min); g_alarmCtrB.state = ALARM_STATUS_CREATED; + g_alarmCtrB.callback(); } } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBarCode.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBarCode.cpp index 5e8723d58..8ecfc16e3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBarCode.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBarCode.cpp @@ -8,8 +8,8 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipayBarCode.h" -#include "AlipayModel.h" +#include "alipay/AlipayBarCode.h" +#include "alipay/AlipayModel.h" namespace OHOS { #define ALIPAY_BARCODE_SPACE 32 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBind.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBind.cpp index 780949585..ec5e44753 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBind.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBind.cpp @@ -6,8 +6,8 @@ */ #include "UiConfig.h" #include -#include "AlipayBind.h" -#include "AlipayModel.h" +#include "alipay/AlipayBind.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const char *BIND_TITLE = (char *)"使用支付宝扫码绑定"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindAni.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindAni.cpp index 4574cb9f5..3a1b70ff1 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindAni.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindAni.cpp @@ -9,7 +9,7 @@ #include "layout/grid_layout.h" #include "font/ui_font.h" #include -#include "AlipayBindAni.h" +#include "alipay/AlipayBindAni.h" #include "common/image_cache_manager.h" #include "graphic_service.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindRes.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindRes.cpp index 0a331982b..04d775882 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindRes.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayBindRes.cpp @@ -10,8 +10,8 @@ #include "font/ui_font.h" #include #include "cmsis_os.h" -#include "AlipayBindRes.h" -#include "AlipayModel.h" +#include "alipay/AlipayBindRes.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const int16 EXIT_LABEL_X_FIRST = 151; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayExitBind.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayExitBind.cpp index edf88e323..3d86a9393 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayExitBind.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayExitBind.cpp @@ -9,7 +9,7 @@ #include "layout/grid_layout.h" #include "font/ui_font.h" #include -#include "AlipayExitBind.h" +#include "alipay/AlipayExitBind.h" namespace OHOS { static const int16 EXIT_LABEL_X_FIRST = 132; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayHelp.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayHelp.cpp index a772a5c10..6e1ff1652 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayHelp.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayHelp.cpp @@ -8,8 +8,8 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipayHelp.h" -#include "AlipayModel.h" +#include "alipay/AlipayHelp.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const char *HELP_TITLE = (char*)"使用支付宝扫码求助"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListAdapter.cpp index 75b2d2da8..3ac28ada0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListAdapter.cpp @@ -5,8 +5,8 @@ * Create: */ -#include "AlipayListAdapter.h" -#include "AlipayListItemView.h" +#include "alipay/AlipayList/AlipayListAdapter.h" +#include "alipay/AlipayList/AlipayListItemView.h" namespace OHOS { AlipayListAdapter::AlipayListAdapter() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListItemView.cpp index 4cd238d8a..b91ee5cd1 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListItemView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListItemView.cpp @@ -6,7 +6,7 @@ */ #include "wearable_log.h" -#include "AlipayListItemView.h" +#include "alipay/AlipayList/AlipayListItemView.h" namespace OHOS { static constexpr int16 ALIPAY_LIST_ICON_X = 20; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListView.cpp index e96e47030..292c48bba 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayList/AlipayListView.cpp @@ -6,8 +6,8 @@ */ #include -#include "AlipayListView.h" -#include "AlipayListItem.h" +#include "alipay/AlipayList/AlipayListView.h" +#include "alipay/AlipayList/AlipayListItem.h" #include "cmsis_os2.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayMainView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayMainView.cpp index 76c9385ff..d45093f13 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayMainView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayMainView.cpp @@ -5,7 +5,7 @@ * Create: */ -#include "AlipayMainView.h" +#include "alipay/AlipayMainView.h" #include "UiConfig.h" #include "alipay_feature.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayModel.cpp index 0414fd48b..cc906cbee 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayModel.cpp @@ -7,8 +7,8 @@ #include "UiConfig.h" #include "alipay_feature.h" -#include "AlipayModel.h" -#include "AlipayMainView.h" +#include "alipay/AlipayModel.h" +#include "alipay/AlipayMainView.h" #include "graphic_service.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPayCode.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPayCode.cpp index 79e738f0f..0fea31b45 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPayCode.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPayCode.cpp @@ -8,8 +8,8 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipayPayCode.h" -#include "AlipayModel.h" +#include "alipay/AlipayPayCode.h" +#include "alipay/AlipayModel.h" namespace OHOS { static AlipayPayCode *g_alipayPayCode = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPresenter.cpp index a58470e2d..4909bd08d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayPresenter.cpp @@ -5,8 +5,8 @@ * Create: */ -#include "AlipayPresenter.h" -#include "AlipayMainView.h" +#include "alipay/AlipayPresenter.h" +#include "alipay/AlipayMainView.h" #include "ChangeSliceListener.h" #include "graphic_service.h" #include "string" @@ -14,10 +14,10 @@ #include "sstream" #include "errcode.h" #include "pm_definition.h" -#include "AlipayListView.h" -#include "AlipayListItemView.h" -#include "AlipayTransListItemView.h" -#include "AlipayTransListView.h" +#include "alipay/AlipayList/AlipayListView.h" +#include "alipay/AlipayList/AlipayListItemView.h" +#include "alipay/AlipayTrans/AlipayTransListItemView.h" +#include "alipay/AlipayTrans/AlipayTransListView.h" #include "NativeRegisterManager.h" namespace OHOS { @@ -61,7 +61,6 @@ void AlipayPresenter::OnStart() void AlipayPresenter::OnResume(void) { - Presenter::OnResume(); svr_alipay_create_task(); } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipaySetting.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipaySetting.cpp index c889eff58..8c977405b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipaySetting.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipaySetting.cpp @@ -8,8 +8,8 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipaySetting.h" -#include "AlipayModel.h" +#include "alipay/AlipaySetting.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const char *SETTING_TITLE = (char *)"设置"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayGetTransList.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayGetTransList.cpp index 0bdadd009..b17032a7c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayGetTransList.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayGetTransList.cpp @@ -10,7 +10,7 @@ #include "font/ui_font.h" #include #include "cmsis_os.h" -#include "AlipayGetTransList.h" +#include "alipay/AlipayTrans/AlipayGetTransList.h" namespace OHOS { static const int16 EXIT_LABEL_X_FIRST = 60; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransAni.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransAni.cpp index 37adb66e5..1ef552af3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransAni.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransAni.cpp @@ -10,7 +10,7 @@ #include "font/ui_font.h" #include #include "cmsis_os.h" -#include "AlipayTransAni.h" +#include "alipay/AlipayTrans/AlipayTransAni.h" #include "common/image_cache_manager.h" #include "graphic_service.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransCode.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransCode.cpp index 2f0459546..072b53b57 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransCode.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransCode.cpp @@ -8,8 +8,8 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipayTransCode.h" -#include "AlipayModel.h" +#include "alipay/AlipayTrans/AlipayTransCode.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const char *TRANSCODE_BUTTON = (char *)"切换交通卡"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransEnable.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransEnable.cpp index 8b42995ba..917843773 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransEnable.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransEnable.cpp @@ -8,8 +8,8 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipayTransEnable.h" -#include "AlipayModel.h" +#include "alipay/AlipayTrans/AlipayTransEnable.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const char *TRANSCODE_TITLE = (char *)"乘车码未开通"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListAdapter.cpp index 703c4b275..54ddc916f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListAdapter.cpp @@ -5,8 +5,8 @@ * Create: */ -#include "AlipayTransListAdapter.h" -#include "AlipayTransListItemView.h" +#include "alipay/AlipayTrans/AlipayTransListAdapter.h" +#include "alipay/AlipayTrans/AlipayTransListItemView.h" namespace OHOS { AlipayTransListAdapter::AlipayTransListAdapter() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListItemView.cpp index aa4b0f0c7..ad049da17 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListItemView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListItemView.cpp @@ -6,7 +6,7 @@ */ #include "wearable_log.h" -#include "AlipayTransListItemView.h" +#include "alipay/AlipayTrans/AlipayTransListItemView.h" namespace OHOS { static constexpr int16_t ALIPAY_TRANS_LIST_ITEM_BUTTON_HEIGHT = 95; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListView.cpp index b77752179..d811a1ee9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransListView.cpp @@ -6,9 +6,9 @@ */ #include -#include "AlipayTransListView.h" -#include "AlipayTransListItem.h" -#include "AlipayModel.h" +#include "alipay/AlipayTrans/AlipayTransListView.h" +#include "alipay/AlipayTrans/AlipayTransListItem.h" +#include "alipay/AlipayModel.h" #include "cmsis_os2.h" #include "common_def.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransRes.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransRes.cpp index c7b5558b2..573415e63 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransRes.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransRes.cpp @@ -10,8 +10,8 @@ #include "font/ui_font.h" #include #include "cmsis_os.h" -#include "AlipayTransRes.h" -#include "AlipayModel.h" +#include "alipay/AlipayTrans/AlipayTransRes.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const int16 EXIT_LABEL_X_FIRST = 38; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransTips.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransTips.cpp index 11706660a..a59f99f14 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransTips.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayTrans/AlipayTransTips.cpp @@ -10,8 +10,8 @@ #include "font/ui_font.h" #include #include "cmsis_os.h" -#include "AlipayTransTips.h" -#include "AlipayModel.h" +#include "alipay/AlipayTrans/AlipayTransTips.h" +#include "alipay/AlipayModel.h" namespace OHOS { static const int16 TIPS_LABEL_X_FIRST = 38; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbind.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbind.cpp index 2c081cae3..a716545b0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbind.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbind.cpp @@ -10,7 +10,7 @@ #include "font/ui_font.h" #include #include "cmsis_os.h" -#include "AlipayUnbind.h" +#include "alipay/AlipayUnbind.h" namespace OHOS { static const int16 EXIT_LABEL_X_FIRST = 132; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbindFinish.cpp b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbindFinish.cpp index 817d90bf3..bd259f23e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbindFinish.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/alipay/src/AlipayUnbindFinish.cpp @@ -8,7 +8,7 @@ #include "UiConfig.h" #include #include "cmsis_os.h" -#include "AlipayUnbindFinish.h" +#include "alipay/AlipayUnbindFinish.h" namespace OHOS { static AlipayUnbindFinish *g_alipayUnbindFinish = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodModel.cpp index e06b38c0e..a32c98430 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodModel.cpp @@ -5,7 +5,9 @@ * Create: 2024-10-30 */ -#include "AodModel.h" +#include "aod_view/AodModel.h" +#include +#include "securec.h" #include "kv_store.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodPresenter.cpp index c08a7472b..9d47082d9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodPresenter.cpp @@ -5,7 +5,7 @@ * Create: 2024-10-30 */ -#include "AodPresenter.h" +#include "aod_view/AodPresenter.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodView.cpp index 90405196d..6bb9f8cec 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/aod_view/src/AodView.cpp @@ -5,14 +5,15 @@ * Create: 2024-10-30 */ -#include "AodView.h" -#include "AodPresenter.h" -#include "AodModel.h" +#include "aod_view/AodView.h" +#include "aod_view/AodPresenter.h" +#include "aod_view/AodModel.h" #include "common/graphic_utils.h" -#include "DialBinParser.h" -#include "DialViewGroup.h" -#include "AmbientClockView.h" -#include "DialModelTime.h" +#include "UICardPageFactory.h" +#include "main/DialBinParser.h" +#include "main/dial/DialViewGroup.h" +#include "clock/AmbientClockView.h" +#include "main/dial/DialModelTime.h" namespace OHOS { AodView::~AodView() @@ -67,13 +68,7 @@ void AodView::OnStop() UIViewGroup *AodView::InitAodDial(DialSetting &setting) { - switch (setting.dialId) { - case DIAL_CLOCK: - return new AmbientClockView; - default: - return nullptr; - } - return nullptr; + return UICardPageFactory::GetInstance().CreateWatchDial(DIAL_DISPLAY_MODE_AOD, setting.dialId); } UIViewGroup *AodView::InitAodOffDial(DialSetting &setting) @@ -84,7 +79,7 @@ UIViewGroup *AodView::InitAodOffDial(DialSetting &setting) if (fp == nullptr) { return nullptr; } - bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(fp, &preview); + bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(setting.dialFullName, fp, &preview); fclose(fp); if (!ret) { return nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistModel.h b/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistModel.h deleted file mode 100644 index fdf1a34f2..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistModel.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: ApplistModel.h - * Author: - * Create: 2021-09-18 - */ - -#ifndef APPLIST_MODEL_H -#define APPLIST_MODEL_H - -#include "bundle_info.h" -#include "AppViewIDs.h" -#include "ohos_types.h" - -#define APP_MAX_NUM 50 - -namespace OHOS { -typedef struct { - uint16_t id; - const char *iconLarge; - const char *iconSmall; - const char *iconHexagon; - const char *label; - const char *uid; -} AppItem; - -enum AppListStyle { - APPLIST_STYLE, - HEXAGONS_STYLE, - FOOTBALL_STYLE, - WATERFALL_STYLE -}; - -class ApplistPresenter; -class ApplistModel { -public: - static ApplistModel &GetInstance(void); - - void Init(); - const AppItem *GetApplistItems() const; - uint8 GetAppListNum() const; - void ResolvingJSAppItems(void); - void SetStartIndex(uint16_t index); - uint16_t GetStartIndex(void); - void SetHeadItemY(int index); - int GetHeadItemY(void); - void ApplistUpdate(void); - void SetPresenter(ApplistPresenter *p); - AppListStyle GetCurrentStyle(void); - void SetInitFlag(bool flag); - -private: - ApplistModel(); - ApplistModel(const ApplistModel &); - ApplistModel &operator=(const ApplistModel &); - virtual ~ApplistModel(); - ApplistPresenter *presenter{nullptr}; - - AppItem applist[APP_MAX_NUM] = { VIEW_INVALID, nullptr, nullptr, nullptr, nullptr, nullptr }; - BundleInfo *bundleInfos = nullptr; - int32 bundleLen = 0; - uint8 appLen = 0; - - uint16_t startIndex = 0; - int headItemY = 0; - bool initFlag{false}; -}; -} - -#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/AppItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/AppItemView.cpp index e4193a9a5..f5dca80fd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/AppItemView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/AppItemView.cpp @@ -5,7 +5,8 @@ * Create: 2021-09-18 */ -#include "AppItemView.h" +#include "applist/AppItemView.h" +#include "common/image_cache_manager.h" #include "wearable_log.h" namespace OHOS { @@ -33,6 +34,9 @@ namespace OHOS { { Remove(&icon_); Remove(&label_); + if (itemInfo_.iconSmall == nullptr && itemInfo_.resPath != nullptr) { + ImageCacheManager::GetInstance().UnloadOneInMultiRes(itemInfo_.resId, itemInfo_.resPath); + } } void AppItemView::SetUpChild() @@ -56,8 +60,25 @@ namespace OHOS { void AppItemView::SetItemInfo(const AppItem &itemInfo) { itemInfo_ = itemInfo; - icon_.SetSrc(itemInfo.iconSmall); - label_.SetText(itemInfo.label); + if (itemInfo.label == nullptr) { + if (itemInfo.labelId != STR_MAX_ID) { + label_.SetTextId(itemInfo.labelId); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AppItemView::SetItemInfo label is null and labelId equal STR_MAX_ID!"); + } + } else { + label_.SetText(itemInfo.label); + } + if (itemInfo.iconSmall == nullptr && itemInfo_.resPath != nullptr) { + ImageInfo* image = ImageCacheManager::GetInstance().LoadOneInMultiRes(itemInfo.resId, itemInfo.resPath); + if (image != nullptr) { + icon_.SetSrc(image); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AppItemView::SetItemInfo image get failed!"); + } + } else { + icon_.SetSrc(itemInfo.iconSmall); + } } AppViewId AppItemView::GetViewId() @@ -88,6 +109,9 @@ namespace OHOS { HexagonsItemView::~HexagonsItemView() { + if (itemInfo_.iconSmall == nullptr && itemInfo_.resPath != nullptr) { + ImageCacheManager::GetInstance().UnloadOneInMultiRes(itemInfo_.resId, itemInfo_.resPath); + } } void HexagonsItemView::SetItemInfo(const AppItem &itemInfo) @@ -105,6 +129,13 @@ namespace OHOS { return itemInfo_.uid; } + FootballItemView::~FootballItemView() + { + if (itemInfo_.iconHexagon == nullptr && itemInfo_.hexagonPath != nullptr) { + ImageCacheManager::GetInstance().UnloadOneInMultiRes(itemInfo_.hexagonId, itemInfo_.hexagonPath); + } + } + void FootballItemView::SetItemInfo(const AppItem &itemInfo) { itemInfo_ = itemInfo; @@ -119,6 +150,13 @@ namespace OHOS { { return itemInfo_.uid; } + + WaterfallItemView::~WaterfallItemView() + { + if (itemInfo_.iconSmall == nullptr && itemInfo_.resPath != nullptr) { + ImageCacheManager::GetInstance().UnloadOneInMultiRes(itemInfo_.resId, itemInfo_.resPath); + } + } void WaterfallItemView::SetItemInfo(const AppItem &itemInfo) { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistAdapter.cpp index 8e26721c8..2808ba27a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistAdapter.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-18 */ -#include "ApplistAdapter.h" +#include "applist/ApplistAdapter.h" namespace OHOS { ApplistAdapter::ApplistAdapter() {} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistModel.cpp index c5a7339bf..b3eabbb23 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistModel.cpp @@ -12,11 +12,11 @@ #include "utils.h" #include "bundlems_slite_client.h" #include "wearable_log.h" - #include "UiConfig.h" -#include "ApplistModel.h" -#include "ApplistPresenter.h" -#include "SetDesktopView.h" +#include "applist/ApplistModel.h" +#include "applist/ApplistPresenter.h" +#include "font/font_global_manager.h" +#include "settings/SetDesktopModel.h" #include "NativeRegisterManager.h" namespace OHOS { @@ -96,7 +96,6 @@ namespace OHOS { applist[appLen] = { VIEW_EXTERN_APP, bundleInfos[len].smallIconPath, - bundleInfos[len].smallIconPath, bundleInfos[len].bigIconPath, bundleInfos[len].label, bundleInfos[len].bundleName @@ -163,15 +162,6 @@ namespace OHOS { AppListStyle ApplistModel::GetCurrentStyle(void) { - uint8_t currenStyle = SetDesktopView::GetInstance()->GetCurrentSelectedStyle(); - if (currenStyle == 1) { // 1: hexagons desktop style - return HEXAGONS_STYLE; - } else if (currenStyle == 2) { // 2: football desktop style - return FOOTBALL_STYLE; - } else if (currenStyle == 3) { // 3: waterfall desktop style - return WATERFALL_STYLE; - } else { - return APPLIST_STYLE; - } + return static_cast(SetDesktopModel::GetInstance().GetDesktopStyle()); } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistPresenter.cpp index 3442b147c..382786a39 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistPresenter.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-18 */ -#include "ApplistPresenter.h" +#include "applist/ApplistPresenter.h" #include "ability_manager.h" #include "securec.h" #include "components/ui_hexagons_list.h" @@ -44,7 +44,6 @@ REGIST_SLICE(VIEW_APPLIST, ApplistView, ApplistPresenter); void ApplistPresenter::OnResume() { - Presenter::OnResume(); if (GetCurrentStyle() == AppListStyle::FOOTBALL_STYLE) { view_->StartFootBallAnimator(); } else if (GetCurrentStyle() == AppListStyle::WATERFALL_STYLE) { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistView.cpp index 11876d275..fbb18801e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/applist/src/ApplistView.cpp @@ -6,10 +6,11 @@ */ #include "components/ui_view_group.h" -#include "ApplistView.h" -#include "ApplistPresenter.h" -#include "AppItemView.h" +#include "applist/ApplistView.h" +#include "applist/ApplistPresenter.h" +#include "applist/AppItemView.h" #include "common/image_cache_manager.h" +#include "common/screen.h" #include "hal_tick.h" namespace OHOS { @@ -264,13 +265,27 @@ void ApplistView::ListStyleOnStop() presenter_->SetStartIndex(listHeadIndex); } +void ApplistView::LoadAppIconImage(UIImageView *view, const uint32_t id, const char *path) +{ + ImageInfo* image = ImageCacheManager::GetInstance().LoadOneInMultiRes(id, path); + if (image == nullptr) { + GRAPHIC_LOGE("Load App Icon path %s Image %x fail\n", path, id); + return; + } + view->SetSrc(image); +} + void ApplistView::AddAppItemToList(const AppItem &item) { AppListStyle style = presenter_->GetCurrentStyle(); if (style == AppListStyle::FOOTBALL_STYLE) { FootballItemView *itemView = new FootballItemView(); itemView->SetItemInfo(item); - itemView->SetSrc(item.iconHexagon); + if (item.iconHexagon == nullptr && item.hexagonPath != nullptr) { + LoadAppIconImage(itemView, item.hexagonId, item.hexagonPath); + } else { + itemView->SetSrc(item.iconHexagon); + } itemView->SetTouchable(true); itemView->SetOnClickListener(presenter_); footballList_->Add(itemView); @@ -278,7 +293,11 @@ void ApplistView::AddAppItemToList(const AppItem &item) } else if (style == AppListStyle::HEXAGONS_STYLE) { HexagonsItemView *itemView = new HexagonsItemView(); itemView->SetItemInfo(item); - itemView->SetSrc(item.iconSmall); + if (item.iconSmall == nullptr && item.resPath != nullptr) { + LoadAppIconImage(itemView, item.resId, item.resPath); + } else { + itemView->SetSrc(item.iconSmall); + } itemView->SetTouchable(true); itemView->SetOnClickListener(presenter_); hexagonsList_->Add(itemView); @@ -286,7 +305,11 @@ void ApplistView::AddAppItemToList(const AppItem &item) } else if (style == AppListStyle::WATERFALL_STYLE) { WaterfallItemView *itemView = new WaterfallItemView(); itemView->SetItemInfo(item); - itemView->SetSrc(item.iconSmall); + if (item.iconSmall == nullptr && item.resPath != nullptr) { + LoadAppIconImage(itemView, item.resId, item.resPath); + } else { + itemView->SetSrc(item.iconSmall); + } itemView->SetTouchable(true); itemView->SetOnClickListener(presenter_); waterfallList_->Add(itemView); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodModel.cpp new file mode 100644 index 000000000..692d2d93d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodModel.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: SettingModel.cpp + * Author: + * Create: 2025-03-23 + */ + +#include +#include "blood/BloodModel.h" +#include "blood/BloodView.h" +#include "ohos_timer.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr uint64_t CENTI_SECOND_UNIT = 100; +static constexpr uint64_t MS_ONE_SECONDS = 1000; +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t NUM_TIME_MIN = 60; +static constexpr uint16_t NUM_TIME_HOUR = 3600; +static constexpr int32_t NUM_TIME_DAY = 86400; + +static constexpr int16_t MIN_TO_HOUR = 60; +static constexpr int16_t HOURLY_SYSTEM = 24; +BloodModel::BloodModel() +{ + InitCurrentTimeTimer(); +} + +BloodModel::~BloodModel() +{ + DisableCurrentTimeTimer(); +} + +BloodModel &BloodModel::GetInstance() +{ + static BloodModel instance; + return instance; +} +void BloodModel::SetbuttonStatus(bool status) +{ + buttonStatus = status; +} + +bool BloodModel::GetbuttonStatus() +{ + return buttonStatus; +} + +/* 定时器回调函数 */ +static void CurrentTimeTimerCallback(void *data) +{ + (void)data; + BloodView *view = BloodView::GetInstance(); + if (view != nullptr && view->IsCurrentTimeLabelValid()) { + std::string currTime = BloodModel::GetInstance().GetCurrentTimeString(); + view->UpdateCurrentTimeLabel(currTime.c_str()); + } +} + +std::string BloodModel::GetCurrentTimeString() +{ + std::string strHours; + std::string strMinute; + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t second = tv.tv_sec; + uint64_t uSecond = tv.tv_usec; + uint64_t minute = second / MIN_TO_HOUR; + uint64_t hour = minute / MIN_TO_HOUR; + uint8_t realHour = static_cast(hour % HOURLY_SYSTEM); + uint8_t realMinute = static_cast(minute % MIN_TO_HOUR); + + if (realHour >= 0 && realHour < NUM_TEN) { + strHours = "0" + std::to_string(realHour); + } else { + strHours = std::to_string(realHour); + } + if (realMinute >= 0 && realMinute < NUM_TEN) { + strMinute = "0" + std::to_string(realMinute); + } else { + strMinute = std::to_string(realMinute); + } + return strHours + ":" + strMinute; +} + +void BloodModel::InitCurrentTimeTimer() +{ + if (pCurrentTimeTimer_ != nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchModel::InitCurrentTimeTimer GraphicTimer already exists!!"); + return; + } + uint32_t tick = GetOSTick(MS_ONE_SECONDS); + pCurrentTimeTimer_ = new GraphicTimer(tick, CurrentTimeTimerCallback, nullptr, true); + if (pCurrentTimeTimer_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchModel::InitCurrentTimeTimer new GraphicTimer failed!!"); + return; + } +} + +void BloodModel::DisableCurrentTimeTimer() +{ + if (pCurrentTimeTimer_ != nullptr) { + pCurrentTimeTimer_->Stop(); + delete pCurrentTimeTimer_; + pCurrentTimeTimer_ = nullptr; + } +} + +void BloodModel::StartCurrentTimeTimer() +{ + if (pCurrentTimeTimer_ != nullptr) { + bool retTimer = pCurrentTimeTimer_->Start(); + if (!retTimer) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StartStopwatchTimer GraphicTimer Start failed!!"); + if (pCurrentTimeTimer_ != nullptr) { + delete pCurrentTimeTimer_; + pCurrentTimeTimer_ = nullptr; + } + return; + } + } +} + +void BloodModel::PauseCurrentTimeTimer() +{ + if (pCurrentTimeTimer_ != nullptr) { + pCurrentTimeTimer_->Stop(); + } +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodPresenter.cpp new file mode 100644 index 000000000..5e98671cc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodPresenter.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingPresenter.cpp + * Author: + * Create: 2025-03-23 + */ + +#include "blood/BloodPresenter.h" +#include "blood/BloodView.h" +#include "blood/BloodModel.h" +#include "uiservice/ui_service.h" +#include "NativeRegisterManager.h" +namespace OHOS { + +REGIST_MENU(VIEW_BLOOD, BloodView, BloodPresenter, PNG_APPLIST_TEMP_IMAGE, PNG_APPLIST_TEMP_IMAGE, "血氧"); + +static BloodPresenter *g_pBloodPresenter = nullptr; + +BloodPresenter::BloodPresenter() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPresenter::BloodPresenter"); + findPhoneModel = &BloodModel::GetInstance(); + g_pBloodPresenter = this; +} + +BloodPresenter::~BloodPresenter() +{ + g_pBloodPresenter = nullptr; +} + +void BloodPresenter::OnResume(void) +{ + Presenter::OnResume(); + SendMsgToUIService(UI_ADD_SLEEP_VETO, 0, nullptr, 0); + BloodModel::GetInstance().StartCurrentTimeTimer(); +} + +void BloodPresenter::OnPause(void) +{ + Presenter::OnPause(); + SendMsgToUIService(UI_RM_SLEEP_VETO, 0, nullptr, 0); + BloodModel::GetInstance().PauseCurrentTimeTimer(); + return; +} + +BloodPresenter *BloodPresenter::GetInstance() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPresenter GetInstance"); + return g_pBloodPresenter; +} + +bool BloodPresenter::ClickFuncId(const char *buttonName) +{ + if (buttonName == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempPresenter::ClickFuncId buttonName nullptr error!"); + return false; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TempPresenter::ClickFuncId buttonName = %s", buttonName); + if (strcmp(buttonName, "button1") == 0) { + } else if (strcmp(buttonName, "button2") == 0) { + } + return false; +} + +bool BloodPresenter::OnClick(UIView &view, const ClickEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TempPresenter::OnClick "); + UNUSED(event); + BloodView::GetInstance()->DropView(view, 1); + return true; +} + +bool BloodPresenter::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WeatherOnDragListener::OnDrag"); + UNUSED(view); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPresenter::OnDrag %s", view.GetViewId()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPresenter::OnDrag %s", event.GetDragDirection()); + if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPresenter::OnDrag ChangeSlice(VIEW_APPLIST)"); + BloodView::GetInstance()->DropView(view, 0); + } else if (event.GetDragDirection() == DragEvent::DIRECTION_RIGHT_TO_LEFT) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPresenter::OnDrag DIRECTION_RIGHT_TO_LEFT"); + BloodView::GetInstance()->DropView(view, 1); + } + return false; +} + +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodView.cpp new file mode 100644 index 000000000..05a7801dc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/blood/src/BloodView.cpp @@ -0,0 +1,603 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingView.cpp + * Author: + * Create: 2025-03-23 + */ + +#include + +#include "blood/BloodView.h" +#include "blood/BloodPresenter.h" +#include "ui_test_group.h" + +namespace OHOS { +static BloodView *g_pBloodView = nullptr; +static const char *BLOOD_LABEL_TWO = (char *)"本功能用于18岁以上健康人群测量运动过程,及之后腕部皮肤温度和体温的变化," + "请加入研究,以便及时观察运动前后身体的变化。"; +static const char *BLOOD_LABEL_THREE = (char *)"测量需佩戴10分钟以上,且容易受到环境因素影响。目前达不到水银体温计的精" + "度,测量结果仅供参考,不作为医疗诊断依据。"; +static constexpr uint16_t BLOOD_FIRST_LABEL_FONT = 35; +static constexpr uint16_t BLOOD_LABEL_FIRST_X = 45; +static constexpr uint16_t BLOOD_LABEL_FIRST_Y = 120; +static constexpr uint16_t BLOOD_LABEL_SECOND_Y = 350; +static constexpr uint16_t BLOOD_LABEL_THIRD_Y = 650; +static constexpr uint16_t BLOOD_LABEL_FIRST_WIDTH = 350; +static constexpr uint16_t BLOOD_LABEL_FIRST_HEIGHT = 400; +static constexpr uint16_t BLOOD_IMAGE_POSITION_X = 92; +static constexpr uint16_t BLOOD_IMAGE_POSITION_y = 127; +static constexpr uint16_t BLOOD_IMAGE_WIDTH = 276; +static constexpr uint16_t BLOOD_IMAGE_HEIGHT = 125; +static const char *BLOOD_LABEL_ONE = + (char *)"本功能通过内置温度传感器测量腕部皮肤温度,主要研究腕部皮肤温度和体温的关系。"; +static constexpr uint16_t WATCH_TIME_LABEL_CURTIME_XPOS = 188; +static constexpr uint16_t WATCH_TIME_LABEL_CURTIME_YPOS = 12; +static constexpr uint16_t WATCH_TIME_LABEL_CURTIME_WIDTH = 361; +static constexpr uint16_t WATCH_TIME_LABEL_CURTIME_HEIGHT = 80; +static constexpr uint16_t WATCH_TIME_LABEL_CURTIME_FONT_SIZE = 40; +static constexpr uint16_t BLOOD_LAYOUT_POSITION_X = 370; +static constexpr uint16_t BLOOD_LAYOUT_WIDTH = 320; +static constexpr uint16_t BLOOD_BUTTON_POSITION_X = 188; +static constexpr uint16_t BLOOD_BUTTON_POSITION_Y = 320; +static constexpr uint16_t BLOOD_BUTTON_WIDTH = 180; +static constexpr uint16_t BLOOD_BUTTON_HEIGHT = 80; +static constexpr uint16_t BLOOD_BUTTON_TWO_POSITION_Y = 330; +static constexpr uint16_t BLOOD_BUTTON_TWO_WIDTH = 120; +static constexpr uint16_t BLOOD_LABEL_FRONT = 25; +static constexpr uint16_t BLOOD_LABEL1_POSITION_X = 150; +static constexpr uint16_t BLOOD_LABEL1_POSITION_Y = 161; +static constexpr uint16_t BLOOD_LABEL1_WIDTH = 200; +static constexpr uint16_t BLOOD_LABEL1_HEIGHT = 60; +static constexpr uint16_t BLOOD_LABEL_FRONT1 = 60; +static constexpr uint16_t BLOOD_LABEL2_POSITION_X = 150; +static constexpr uint16_t BLOOD_LABEL2_POSITION_Y = 132; +static constexpr uint16_t BLOOD_LABEL2_WIDTH = 200; +static constexpr uint16_t BLOOD_LABEL2_HEIGHT = 60; +static constexpr uint16_t BLOOD_IMAGEANIMATOR_POSITION_X = 84; +static constexpr uint16_t BLOOD_IMAGEANIMATOR_POSITION_Y = 108; +static constexpr uint16_t BLOOD_IMAGEANIMATOR_WIDTH = 100; +static constexpr uint16_t BLOOD_IMAGEANIMATOR_HEIGHT = 100; + +static ImageAnimatorInfo g_imageAnimatorInfo[4] = { + {PNG_SETTTING_BUTTON_IMAGE, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, + {PNG_NEW_DEVICE, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, + {PNG_BT_LIST, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, + {PNG_GANTAN, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, +}; + +BloodView::BloodView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodView::BloodView"); + g_pBloodView = this; + findPhoneModel = &BloodModel::GetInstance(); +} + +BloodView::~BloodView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodView::~BloodView"); + g_pBloodView = nullptr; + if (currentTime_ != nullptr) { + delete currentTime_; + currentTime_ = nullptr; + } + if (button != nullptr) { + delete button; + button = nullptr; + } + if (buttonMore != nullptr) { + delete buttonMore; + buttonMore = nullptr; + } + if (label1_ != nullptr) { + delete label1_; + label1_ = nullptr; + } + if (label2_ != nullptr) { + delete label2_; + label2_ = nullptr; + } + if (layout_ != nullptr) { + delete layout_; + layout_ = nullptr; + } + if (currentTime_ != nullptr) { + delete currentTime_; + currentTime_ = nullptr; + } + if (group != nullptr) { + delete group; + group = nullptr; + } + if (groupTest != nullptr) { + delete groupTest; + groupTest = nullptr; + } + if (scrollGroup != nullptr) { + delete scrollGroup; + scrollGroup = nullptr; + } + for (int16_t numGroup = SET_ZERO; numGroup <= MAX_BLOOD_PAGE; numGroup++) { + if (container[numGroup] != nullptr) { + container[numGroup] = nullptr; + } + } +} + +BloodView *BloodView::GetInstance() +{ + return g_pBloodView; +} + +void BloodView::OnStart() +{ + SetupCurrentTime(); + InitStart(); +} + +void BloodView::OnStop() +{ + if (dragListener_ != nullptr) { + delete dragListener_; + dragListener_ = nullptr; + } + return; +} + +void BloodView::SetupCurrentTime() +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::SetupCurrentTime new Label"); + currentTime_ = new UILabel(); + if (currentTime_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::SetupCurrentTime new Label currentTime_ fail"); + return; + } + currentTime_->SetPosition(WATCH_TIME_LABEL_CURTIME_XPOS, WATCH_TIME_LABEL_CURTIME_YPOS); + currentTime_->Resize(WATCH_TIME_LABEL_CURTIME_WIDTH, WATCH_TIME_LABEL_CURTIME_HEIGHT); + std::string curtime = BloodModel::GetInstance().GetCurrentTimeString(); + currentTime_->SetText(curtime.c_str()); + currentTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WATCH_TIME_LABEL_CURTIME_FONT_SIZE); + currentTime_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + currentTime_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + currentTime_->SetRollSpeed(0); + currentTime_->SetVisible(true); +} + +void BloodView::SetUpImageAnimator() +{ + imageAnimator_ = new UIImageAnimatorView(); + if (imageAnimator_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::UIImageAnimatorView new Label currentTime_ fail"); + return; + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::SetUpImageAnimator "); + imageAnimator_ = new UIImageAnimatorView(); + imageAnimator_->SetPosition(BLOOD_IMAGE_POSITION_X, BLOOD_IMAGE_POSITION_y, BLOOD_IMAGE_WIDTH, + BLOOD_IMAGE_HEIGHT); // 50 : offset 50 : offset 200 : offset 200: offset + int imageNumber = 4; + int ImageUpdate = 300; + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, imageNumber, + ImageUpdate); // 4: the number of images, 100: updating time + imageAnimator_->Stop(); + imageAnimator_->LayoutCenterOfParent(); + imageAnimator_->SetDraggable(true); + UIView::OnDragListener *listener = static_cast(BloodPresenter::GetInstance()); + imageAnimator_->SetOnDragListener(listener); + container[BLOOD_START]->Add(imageAnimator_); + if (layout_ == nullptr) { + layout_ = new GridLayout(); + uint16_t height = Screen::GetInstance().GetHeight(); + + int heightOffset = 50; + layout_->SetPosition(BLOOD_LAYOUT_POSITION_X, 0, BLOOD_LAYOUT_WIDTH, + height - heightOffset); // 370: x , 320: width, 50: offset + container[BLOOD_START]->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_VER); + layout_->SetRows(SET_NINE); // 9 : rows + layout_->SetCols(SET_TWO); // 2 : columns + } + InitImageInfo(); +} + +void BloodView::InitStart() +{ + if (group == nullptr) { + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + UIView::OnDragListener *dragListener = static_cast(BloodPresenter::GetInstance()); + if (dragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "start dragListener = nullptr"); + } + group->SetOnDragListener(dragListener); + group->SetViewId("startPage"); + group->SetDraggable(true); + group->SetTouchable(true); + + if (button == nullptr) { + button = new UILabelButton(); + } + button->SetPosition(BLOOD_BUTTON_POSITION_X, + BLOOD_BUTTON_TWO_POSITION_Y); // widget's left position and top position + button->Resize(BLOOD_BUTTON_TWO_WIDTH, BLOOD_BUTTON_HEIGHT); // widget's width and height + button->SetViewId("button1"); // Set style + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)(BloodPresenter::GetInstance()); + button->SetOnClickListener(clickListener); + button->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + button->SetVisible(true); + button->SetText("开始"); + + group->Add(currentTime_); + group->Add(button); + container[BLOOD_START] = group; + + AddViewToRootContainer(container[BLOOD_START]); + GetRootContainer()->Invalidate(); +} + +void BloodView::InitTest() +{ + if (groupTest == nullptr) { + groupTest = new UIViewGroup(); + } + groupTest->SetPosition(0, 0); + groupTest->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + + UIView::OnDragListener *dragListener = static_cast(BloodPresenter::GetInstance()); + if (dragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init test dragListener = nullptr"); + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init test dragListener successful"); + + groupTest->SetOnDragListener(dragListener); + groupTest->SetViewId("testPage"); + groupTest->SetDraggable(true); + groupTest->SetTouchable(true); + + if (label1_ == nullptr) { + label1_ = new UILabel(); + } + + label1_->SetPosition(BLOOD_LABEL1_POSITION_X, BLOOD_LABEL1_POSITION_Y); // widget's left position and top position + label1_->Resize(BLOOD_LABEL1_WIDTH, BLOOD_LABEL1_HEIGHT); // widget's width and height + label1_->SetViewId("label1"); // Set style + label1_->SetStyle(STYLE_TEXT_FONT, BLOOD_LABEL_FRONT1); + + // Set additional property + label1_->SetText("99%"); + label1_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + label1_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + label1_->SetRollSpeed(0); + label1_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BLOOD_LABEL_FRONT1); + + // Add to rootView + label1_->SetVisible(true); + + // Add Label to App + if (label2_ == nullptr) { + label2_ = new UILabel(); + } + + label2_->SetPosition(BLOOD_LABEL2_POSITION_X, BLOOD_LABEL2_POSITION_Y); // widget's left position and top position + label2_->Resize(BLOOD_LABEL2_WIDTH, BLOOD_LABEL2_HEIGHT); // widget's width and height + label2_->SetViewId("label1"); // Set style + label2_->SetStyle(STYLE_TEXT_FONT, BLOOD_LABEL_FRONT); + + // Set additional property + label2_->SetText("血氧"); + label2_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + label2_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + label2_->SetRollSpeed(0); + label2_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BLOOD_LABEL_FRONT); + label2_->SetVisible(true); + + // Add to rootView + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init test label successful"); + + if (buttonMore == nullptr) { + buttonMore = new UILabelButton(); + } + + buttonMore->SetPosition(BLOOD_BUTTON_POSITION_X, + BLOOD_BUTTON_POSITION_Y); // widget's left position and top position + buttonMore->Resize(BLOOD_BUTTON_WIDTH, BLOOD_BUTTON_HEIGHT); // widget's width and height + buttonMore->SetViewId("button2"); // Set style + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)(BloodPresenter::GetInstance()); + buttonMore->SetOnClickListener(clickListener); + buttonMore->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + buttonMore->SetVisible(true); + buttonMore->SetText("了解更多"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init test button successful"); + + groupTest->Add(label1_); + groupTest->Add(label2_); + groupTest->Add(currentTime_); + groupTest->Add(buttonMore); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init test add button successful"); +} + +void BloodView::InitMore() +{ + if (scrollGroup == nullptr) { + scrollGroup = new UIScrollView(); + } + scrollGroup->Add(currentTime_); + + scrollGroup->SetViewId("moreGroup"); + scrollGroup->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + scrollGroup->SetThrowDrag(true); + scrollGroup->SetScrollBlankSize(50); // 50:font size + UIView::OnDragListener *listener = static_cast(BloodPresenter::GetInstance()); + scrollGroup->SetOnDragListener(listener); + scrollGroup->SetDraggable(true); + scrollGroup->SetTouchable(true); + if (!InitSimilarLabel(SET_ZERO, BLOOD_LABEL_FIRST_Y, BLOOD_LABEL_ONE)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[SET_ZERO] error"); + } + if (!InitSimilarLabel(SET_ONE, BLOOD_LABEL_SECOND_Y, BLOOD_LABEL_TWO)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[SET_ONE] error"); + } + if (!InitSimilarLabel(SET_TWO, BLOOD_LABEL_THIRD_Y, BLOOD_LABEL_THREE)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[SET_ONE] error"); + } +} + +bool BloodView::InitSimilarLabel(int16 num, int16 labelY, const char *labelText) +{ + tempLabel[num] = new UILabel(); + if (tempLabel[num] == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[%d] error", num); + return false; + } + tempLabel[num]->SetPosition(BLOOD_LABEL_FIRST_X, labelY, BLOOD_LABEL_FIRST_WIDTH, BLOOD_LABEL_FIRST_HEIGHT); + tempLabel[num]->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + tempLabel[num]->SetText(labelText); + tempLabel[num]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BLOOD_FIRST_LABEL_FONT); + scrollGroup->Add(tempLabel[num]); + + return true; +} + +bool BloodView::TempInitLabel(void) +{ + scrollGroup->Add(currentTime_); + UIView::OnDragListener *dragListener = static_cast(BloodPresenter::GetInstance()); + if (dragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init more dragListener = nullptr"); + } + if (!InitSimilarLabel(SET_ZERO, BLOOD_LABEL_FIRST_Y, BLOOD_LABEL_ONE)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[SET_ZERO] error"); + return false; + } + if (!InitSimilarLabel(SET_ONE, BLOOD_LABEL_SECOND_Y, BLOOD_LABEL_TWO)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[SET_ONE] error"); + return false; + } + if (!InitSimilarLabel(SET_TWO, BLOOD_LABEL_THIRD_Y, BLOOD_LABEL_THREE)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TempJoinStudy::TempInitLabel new tempLabel[SET_ONE] error"); + return false; + } + return true; +} + +void BloodView::InitImageInfo() +{ + const uint16_t pixelByteSize = 4; // 4: bytes per pixel + const uint16_t width = 100; // 100: image's width + const uint16_t height = 100; // 100: image's height + uint32_t dataSize = width * height * pixelByteSize; + uint8_t *srcData1 = static_cast(UIMalloc(dataSize)); + if (srcData1 == nullptr) { + return; + } + + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData1[i] = SET_INT_MAX; // 255: pixel value + srcData1[i + 1] = 0; // 1: set green channel + srcData1[i + 2] = 0; // 2: set red channel + srcData1[i + 3] = OPA_OPAQUE; // 3: set alpha channel + } + imageInfo1_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo1_ == nullptr) { + UIFree(srcData1); + return; + } + + imageInfo1_->header.width = width; + imageInfo1_->header.height = height; + imageInfo1_->header.colorMode = ColorMode::ARGB8888; + imageInfo1_->dataSize = dataSize; + imageInfo1_->data = srcData1; + + uint8_t *srcData2 = static_cast(UIMalloc(dataSize)); + if (srcData2 == nullptr) { + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData2[i] = 0; // set blue channel + srcData2[i + 1] = SET_INT_MAX; // 1: set green channel 255: pixel value + srcData2[i + 2] = 0; // 2: set red channel + srcData2[i + 3] = OPA_OPAQUE; // 3: set alpha channel + } + + imageInfo2_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo2_ == nullptr) { + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + imageInfo2_->header.width = width; + imageInfo2_->header.height = height; + imageInfo2_->header.colorMode = ARGB8888; + imageInfo2_->dataSize = dataSize; + imageInfo2_->data = srcData2; + + uint8_t *srcData3 = static_cast(UIMalloc(dataSize)); + if (srcData3 == nullptr) { + UIFree(imageInfo2_); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData3[i] = 0; // set blue channel + srcData3[i + 1] = 0; // 1: set green channel + srcData3[i + 2] = SET_INT_MAX; // 2: set red channel 255: pixel value + srcData3[i + 3] = OPA_OPAQUE; // 3: set alpha channel + } + + imageInfo3_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo3_ == nullptr) { + UIFree(srcData3); + UIFree(imageInfo2_); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + imageInfo3_->header.width = width; + imageInfo3_->header.height = height; + imageInfo3_->header.colorMode = ARGB8888; + imageInfo3_->dataSize = dataSize; + imageInfo3_->data = srcData3; + + imageAnimatorImageInfo_[0].imageInfo = imageInfo1_; + imageAnimatorImageInfo_[0].pos = {BLOOD_IMAGEANIMATOR_POSITION_X, BLOOD_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo_[0].width = BLOOD_IMAGEANIMATOR_WIDTH; // 100: width value + imageAnimatorImageInfo_[0].height = BLOOD_IMAGEANIMATOR_HEIGHT; // 100: height value + imageAnimatorImageInfo_[0].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo_[1].imageInfo = imageInfo2_; + imageAnimatorImageInfo_[1].pos = {BLOOD_IMAGEANIMATOR_POSITION_X, BLOOD_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo_[1].width = BLOOD_IMAGEANIMATOR_WIDTH; // 100: width value + imageAnimatorImageInfo_[1].height = BLOOD_IMAGEANIMATOR_HEIGHT; // 100: height value + imageAnimatorImageInfo_[1].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo_[2].imageInfo = imageInfo3_; // 2: image index + imageAnimatorImageInfo_[2].pos = {BLOOD_IMAGEANIMATOR_POSITION_X, BLOOD_IMAGEANIMATOR_POSITION_Y}; // 2: image index + imageAnimatorImageInfo_[2].width = BLOOD_IMAGEANIMATOR_WIDTH; // 2: image index, 100: width value + imageAnimatorImageInfo_[2].height = BLOOD_IMAGEANIMATOR_HEIGHT; // 2: image index, 100: height value + imageAnimatorImageInfo_[2].imageType = IMG_SRC_IMAGE_INFO; // 2: image index +} + +void BloodView::UpdateCurrentTimeLabel(const char *currentTime) +{ + currentTime_->SetText(currentTime); + currentTime_->Invalidate(); +} + +bool BloodView::IsCurrentTimeLabelValid() +{ + return currentTime_ != nullptr ? true : false; +} + +void BloodView::DropView(UIView &view, int type) +{ + if (type == 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_ondrop]-0"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_ondrop] view name :%s", + view.GetViewId()); + if (&view == container[BLOOD_START]) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[CHANGE_INTERFACE_CONFIG]-0"); + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } else if (&view == container[BLOOD_TEST]) { + ChangeView(BLOOD_TEST, BLOOD_START); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[BLOOD_START]-0"); + } else if (&view == container[BLOOD_MORE]) { + ChangeView(BLOOD_MORE, BLOOD_TEST); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_SCROLL]-0"); + } + } else if (type == 1) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_ondrop] view name :%s", + view.GetViewId()); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_ondrop]-1"); + if (&view == button || view.GetViewId() == "button1") { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_SWIPE]-1"); + ChangeView(BLOOD_START, BLOOD_TEST); + } else if (&view == buttonMore || view.GetViewId() == "button1") { + ChangeView(BLOOD_TEST, BLOOD_MORE); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::DropView::container[WEATHER_SCROLL]-1"); + } else if (&view == container[BLOOD_MORE]) { + } + } +} + +bool BloodView::ChangeBloodStart(int16_t thisView) +{ + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodView::WeatherGroupView"); + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool BloodView::ChangeBloodTest(int16_t thisView) +{ + if (container[thisView] == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::ChangeBloodTest"); + InitTest(); + container[thisView] = groupTest; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool BloodView::ChangeBloodMore(int16_t thisView) +{ + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodView::WeatherScrollView"); + InitMore(); + container[thisView] = scrollGroup; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +struct BloodViewMapper { + uint16_t viewId; + bool (BloodView::*func)(int16 thisView); +}; + +static const BloodViewMapper ViewMapper[] = { + {BLOOD_START, &BloodView::ChangeBloodStart}, + {BLOOD_TEST, &BloodView::ChangeBloodTest}, + {BLOOD_MORE, &BloodView::ChangeBloodMore}, +}; + +bool BloodView::ClickFunc(int16 interf) +{ + int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[0]); + for (int i = 0; i < funcSize; i++) { + if (interf == ViewMapper[i].viewId) { + bool jug = (this->*(ViewMapper[i].func))(interf); + if (!jug) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView:: ChangeInterFace[%d] false", interf); + return false; + } + return true; + } + } + return false; +} + +void BloodView::ChangeView(int16 hideView, int16 showView) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodView::ChangeView hideView = %d, showView = %d", hideView, showView); + if (hideView > MAX_BLOOD_PAGE) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::ChangeView Overstep ones bounds"); + return; + } + if (!ClickFunc(showView)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodView::ChangeView ClickFunc ercror"); + return; + } + container[hideView]->SetVisible(false); + container[showView]->SetVisible(true); + Draw(); + return; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodBandoffView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodBandoffView.cpp index 656cf1bf1..894ffd66c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodBandoffView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodBandoffView.cpp @@ -6,8 +6,8 @@ */ #include "UiConfig.h" #include "wearable_log.h" -#include "BloodBandoffView.h" -#include "BloodOxygenModel.h" +#include "bloodoxygen/BloodBandoffView.h" +#include "bloodoxygen/BloodOxygenModel.h" namespace OHOS { // 动态显示图片设置 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenModel.cpp index c6f083a43..edad7933b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenModel.cpp @@ -5,7 +5,7 @@ * Create: 2021-08-01 */ -#include "BloodOxygenModel.h" +#include "bloodoxygen/BloodOxygenModel.h" namespace OHOS { BloodOxygenModel::BloodOxygenModel() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenPresenter.cpp index c7bcfe376..84d8e0897 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenPresenter.cpp @@ -5,14 +5,14 @@ * Create: 2021-08-01 */ -#include "BloodOxygenPresenter.h" +#include "bloodoxygen/BloodOxygenPresenter.h" #include "common/task_manager.h" -#include "BloodOxygenView.h" -#include "BloodOxygenModel.h" +#include "bloodoxygen/BloodOxygenView.h" +#include "bloodoxygen/BloodOxygenModel.h" #include "components/ui_label.h" -#include "BloodBandoffView.h" +#include "bloodoxygen/BloodBandoffView.h" #include "ChangeSliceListener.h" -#include "ui_service.h" +#include "uiservice/ui_service.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenView.cpp index d6ee39ad4..5b2ade831 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/src/BloodOxygenView.cpp @@ -5,8 +5,8 @@ * Create: 2021-08-01 */ -#include "BloodOxygenView.h" -#include "BloodOxygenModel.h" +#include "bloodoxygen/BloodOxygenView.h" +#include "bloodoxygen/BloodOxygenModel.h" namespace OHOS { // 按钮设置 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothCaseListAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothCaseListAdapter.cpp index 763f631ce..06dc76ba1 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothCaseListAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothCaseListAdapter.cpp @@ -5,13 +5,13 @@ * Create: 2021-07-26 */ #include -#include "BluetoothCaseListAdapter.h" -#include "BluetoothEarPhoneView.h" +#include "bluetooth/BluetoothCaseListAdapter.h" +#include "bluetooth/BluetoothEarPhoneView.h" #include "gfx_utils/list.h" -#include "PlayersPresenter.h" +#include "player/PlayersPresenter.h" #include "wearable_log.h" #include "UiConfig.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothModel.h" namespace OHOS { BluetoothCaseListAdapter::~BluetoothCaseListAdapter() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceCaseListAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceCaseListAdapter.cpp index f2950ec01..ed234cca2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceCaseListAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceCaseListAdapter.cpp @@ -5,13 +5,13 @@ * Create: 2021-07-26 */ #include -#include "BluetoothDeviceCaseListAdapter.h" -#include "BluetoothOptionsView.h" +#include "bluetooth/BluetoothDeviceCaseListAdapter.h" +#include "bluetooth/BluetoothOptionsView.h" #include "gfx_utils/list.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "BluetoothPresenter.h" +#include "bluetooth/BluetoothPresenter.h" namespace OHOS { BluetoothDeviceCaseListAdapter::~BluetoothDeviceCaseListAdapter() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceListView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceListView.cpp index 94ef720d7..abcad4678 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceListView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothDeviceListView.cpp @@ -4,12 +4,12 @@ * Author: * Create: 2021-10-13 */ -#include "BluetoothDeviceListView.h" +#include "bluetooth/BluetoothDeviceListView.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" -#include "BluetoothModel.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" +#include "bluetooth/BluetoothModel.h" namespace OHOS { static BluetoothDeviceListView *g_pBluetoothDeviceListView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarListView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarListView.cpp index daf4cf89d..190747bde 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarListView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarListView.cpp @@ -4,13 +4,13 @@ * Author: * Create: 2021-10-13 */ -#include "BluetoothModel.h" -#include "BluetoothEarListView.h" +#include "bluetooth/BluetoothModel.h" +#include "bluetooth/BluetoothEarListView.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" -#include "SettingModel.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" +#include "settings/SettingModel.h" namespace OHOS { static BluetoothEarListView *g_pBluetoothEarListView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarPhoneView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarPhoneView.cpp index 7253ed754..5c85b6d00 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarPhoneView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothEarPhoneView.cpp @@ -5,13 +5,13 @@ * Create: 2021-10-13 */ #include -#include "BluetoothEarPhoneView.h" +#include "bluetooth/BluetoothEarPhoneView.h" #include "wearable_log.h" #include "UiConfig.h" -#include "BluetoothPresenter.h" -#include "PlayersPresenter.h" -#include "BluetoothItemView.h" -#include "SettingModel.h" +#include "bluetooth/BluetoothPresenter.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothItemView.h" +#include "settings/SettingModel.h" #include "common/image_cache_manager.h" #include "graphic_service.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp index 6ac112db8..a036e7628 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp @@ -5,10 +5,10 @@ * Create: 2022-3-22 */ -#include "BluetoothHeadsetEvent.h" +#include "bluetooth/BluetoothHeadsetEvent.h" #include "bts_avrcp_target.h" #include "bts_avrcp_controller.h" -#include "PlayersModel.h" +#include "player/PlayersModel.h" #include "graphic_service.h" using namespace OHOS; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothItemView.cpp index 676c0183e..a05ca8591 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothItemView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothItemView.cpp @@ -5,7 +5,7 @@ * Create: 2021-10-13 */ -#include "BluetoothItemView.h" +#include "bluetooth/BluetoothItemView.h" #include "wearable_log.h" #include "UiConfig.h" #include "common/image_cache_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothModel.cpp index abea09a37..cf54e84df 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothModel.cpp @@ -5,14 +5,14 @@ * Create: 2021-10-13 */ #include -#include "BluetoothModel.h" -#include "BluetoothWrapper.h" -#include "BluetoothPresenter.h" -#include "ConnectPhonePresenter.h" -#include "BluetoothView.h" -#include "BluetoothItemView.h" -#include "PlayersModel.h" -#include "PhoneAudio.h" +#include "bluetooth/BluetoothModel.h" +#include "bluetooth/BluetoothWrapper.h" +#include "bluetooth/BluetoothPresenter.h" +#include "connectnewphone/ConnectPhonePresenter.h" +#include "player/BluetoothView.h" +#include "bluetooth/BluetoothItemView.h" +#include "player/PlayersModel.h" +#include "phoneservice/PhoneAudio.h" #include "graphic_service.h" #include "msg_center.h" #include "bts_def.h" @@ -35,8 +35,11 @@ #include "msg_center_protocol.h" #include "dfx_channel.h" #include "tcxo.h" -#include "ui_service.h" +#include "uiservice/ui_service.h" #include "network/network_listener.h" +#if defined(SUPPORT_LWIP) && defined(SUPPORT_BREDR) +#include "lwip_driver_adapter.h" +#endif namespace OHOS { #define BT_SPP_TASK_STACK_SIZE 2048 @@ -849,6 +852,36 @@ void BluetoothModel::BtGapAclStateChangedHandle(gap_acl_state_t state, unsigned } } +void ChangeBleConnectToMax() +{ + if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) { + gap_conn_param_update_t conn_param = { 0 }; + conn_param.conn_handle = BLUETOOTH_CONN_HANDLE; + conn_param.interval_min = BLUETOOTH_INTERVAL_TOMAX_MIN; + conn_param.interval_max = BLUETOOTH_INTERVAL_TOMAX_MAX; + conn_param.slave_latency = BLUETOOTH_LATENCY; + conn_param.timeout_multiplier = BLUETOOTH_TIMEOUT_MUTIPLIER; + errcode_t ret = gap_ble_connect_param_update(&conn_param); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback change to max interval ret:%d : latency-min:%u latency-max:%u\n", + ret, conn_param.interval_min, conn_param.interval_max); + } +} + +void ChangeBleConnectToDefault() +{ + if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) { + gap_conn_param_update_t conn_param = { 0 }; + conn_param.conn_handle = BLUETOOTH_CONN_HANDLE; + conn_param.interval_min = BLUETOOTH_INTERVAL_TODEFAULT_MIN; + conn_param.interval_max = BLUETOOTH_INTERVAL_TODEFAULT_MAX; + conn_param.slave_latency = BLUETOOTH_LATENCY; + conn_param.timeout_multiplier = BLUETOOTH_TIMEOUT_MUTIPLIER; + errcode_t ret = gap_ble_connect_param_update(&conn_param); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback change to default interval ret:%d : latency-min:%u latency-max:%u\n", + ret, conn_param.interval_min, conn_param.interval_max); + } +} + // 回调:ACL连接状态上报 void GapAclStateChangedCallback(const bd_addr_t *bdAddr, gap_acl_state_t state, unsigned int reason) { @@ -872,6 +905,9 @@ void GapAclStateChangedCallback(const bd_addr_t *bdAddr, gap_acl_state_t state, SendMsgToUIService(BT_CONNECTED_TO_UI, 0, nullptr, 0); // send to ace network // SetAclConnected(true); +#if defined(SUPPORT_LWIP) && defined(SUPPORT_BREDR) + bt_pan_open(); +#endif net_connect_status_change(NETWORK_TYPE_BLUETOOTH, CONNECTION_STATUS_CONNECTED); } return; @@ -1299,6 +1335,11 @@ static a2dp_snk_callbacks_t g_a2dp_snk_callbacks = { BtA2dpSnkConfigChangedCb }; +static void BleConnectCallback(uint16_t conn_id, errcode_t status, const gap_ble_conn_param_update_t *param) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback conn_id:%u, interval-1:%u latency:%u timeout:%u\n",conn_id, param->interval, param->latency, param->timeout); +} + void BtInitCallBacks() { g_btGapCallBacks.discovery_result_callback = BtGapDiscoveryResultCallback; @@ -1327,6 +1368,7 @@ void BtInitCallBacksEx() g_gapBleCallbacks.start_adv_cb = BleAdvStartCallback; g_gapBleCallbacks.stop_adv_cb = BleAdvStopCallback; g_gapBleCallbacks.terminate_adv_cb = BleAdvTerminateCallback; + g_gapBleCallbacks.conn_param_update_cb = BleConnectCallback; wrapper_gap_ble_register_callbacks(&g_gapBleCallbacks); g_btGattsCallbacks.add_service_cb = BtGattsServiceAddCallback; @@ -1411,10 +1453,6 @@ void BtSppServerCreate(const char *spp_uuid, const char *name, uint8_t name_len) param.socket_type = SPP_SOCKET_RFCOMM; param.is_encrypt = true; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "uuid: %s uuid_len: %u\n", spp_uuid, param.uuid.uuid_len); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "socket_type: %x is_encrypt: %d name: %s nameLen: %u\n", param.socket_type, - param.is_encrypt, name, name_len); - int ret = spp_server_create(¶m, name, name_len); WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_create ret: %x\n", ret); } @@ -1422,12 +1460,9 @@ void BtSppServerCreate(const char *spp_uuid, const char *name, uint8_t name_len) static int BtSppServerAcceptTaskBody(void *data) { int server_id = (int)(intptr_t)data; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "server_id: %x\n", server_id); - int ret = spp_server_accept(server_id); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_accept ret: %x\n", ret); - + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_accept ret: %x, server_id: %d\r\n", ret, server_id); return OSAL_SUCCESS; } @@ -1445,8 +1480,6 @@ void BtSppServerAccept(uint8_t server_id) if (ret != OSAL_SUCCESS) { WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "set pri error: %08x\n", ret); } - - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "create task success.\n"); } void BtInitSpp(void) diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothOptionsView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothOptionsView.cpp index a2c367198..ae254eaa6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothOptionsView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothOptionsView.cpp @@ -4,12 +4,12 @@ * Author: * Create: 2021-10-13 */ -#include "BluetoothOptionsView.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothOptionsView.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" namespace OHOS { static BluetoothOptionsView *g_pBluetoothOptionsView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothPresenter.cpp index bcb1aa3bb..e3e472450 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothPresenter.cpp @@ -7,9 +7,9 @@ #include "wearable_log.h" #include "UiConfig.h" -#include "BluetoothPresenter.h" -#include "BluetoothReconnectView.h" -#include "MainBluetoothView.h" +#include "bluetooth/BluetoothPresenter.h" +#include "bluetooth/BluetoothReconnectView.h" +#include "bluetooth/MainBluetoothView.h" #include "NativeRegisterManager.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothReconnectView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothReconnectView.cpp index ad2334248..c1bea7573 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothReconnectView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothReconnectView.cpp @@ -4,12 +4,12 @@ * Create: 2021-10-13 */ -#include "BluetoothReconnectView.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothReconnectView.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" #include "common/image_cache_manager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothWrapper.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothWrapper.cpp index 22e85a984..0e074c908 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothWrapper.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/BluetoothWrapper.cpp @@ -6,7 +6,7 @@ */ #include -#include "BluetoothWrapper.h" +#include "bluetooth/BluetoothWrapper.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/MainBluetoothView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/MainBluetoothView.cpp index 5e1ca8918..a7a242543 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/MainBluetoothView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/MainBluetoothView.cpp @@ -4,8 +4,8 @@ * Author: * Create: 2021-10-13 */ -#include "MainBluetoothView.h" -#include "BluetoothModel.h" +#include "bluetooth/MainBluetoothView.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsConnFailMessageView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsConnFailMessageView.cpp index 552f968aa..21fb3c440 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsConnFailMessageView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsConnFailMessageView.cpp @@ -4,12 +4,12 @@ * Author: * Create: 2021-10-13 */ -#include "TipsConnFailMessageView.h" -#include "BluetoothModel.h" +#include "bluetooth/TipsConnFailMessageView.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" namespace OHOS { static TipsConnFailMessageView *g_pConnFailMessageView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsFailMessageView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsFailMessageView.cpp index 4d732b85d..ad592dc90 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsFailMessageView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsFailMessageView.cpp @@ -4,12 +4,12 @@ * Author: * Create: 2021-10-13 */ -#include "TipsFailMessageView.h" -#include "BluetoothModel.h" +#include "bluetooth/TipsFailMessageView.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" namespace OHOS { static TipsFailMessageView *g_pFailMessageView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsSuccMessageView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsSuccMessageView.cpp index 9bab50fa8..99b0a7f73 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsSuccMessageView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/src/TipsSuccMessageView.cpp @@ -4,12 +4,12 @@ * Author: * Create: 2021-10-13 */ -#include "TipsSuccMessageView.h" -#include "BluetoothModel.h" +#include "bluetooth/TipsSuccMessageView.h" +#include "bluetooth/BluetoothModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "PlayersPresenter.h" -#include "BluetoothPresenter.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothPresenter.h" namespace OHOS { static TipsSuccMessageView *g_pSuccMessageView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathDurPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathDurPage.cpp new file mode 100644 index 000000000..fd888e58a --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathDurPage.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathDurPage + * Create: 2025-5-13 + */ +#include "components/root_view.h" +#include "gfx_utils/graphic_math.h" +#include "UiConfig.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "alarm/MainAlarmView.h" +#include "TransitionType.h" +#include "SlicePageFactory.h" +#include "ui_resource_breath.h" +#include "main/LoadImg.h" +#include "breath/BreathView.h" +#include "breath/BreathDurPage.h" + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_MAIN_BREATHEASE, BrearhView::BREATH_DUR_VIEW, BreathDurPage, false); + +#define WND_BTHDUR_BTN_OK_ID "BTH_DUR_OK" +#define WND_BTHDUR_TITLE_X 100 +#define WND_BTHDUR_TITLE_Y 38 +#define WND_BTHDUR_TITLE_W 253 +#define WND_BTHDUR_TITLE_H 53 +#define WND_BTHDUR_TITLE_FONT_SIZE 38 +#define WND_BTHDUR_PICKER_X 64 +#define WND_BTHDUR_PICKER_Y 109 +#define WND_BTHDUR_PICKER_W 321 +#define WND_BTHDUR_PICKER_H 218 +#define WND_BTHDUR_PICKER_B_FONT_SIZE 44 +#define WND_BTHDUR_PICKER_H_FONT_SIZE 44 +#define WND_BTHDUR_PICKER_ITEM_H 80 +#define WND_BTHDUR_OK_X 61 +#define WND_BTHDUR_OK_Y 362 +#define WND_BTHDUR_OK_W 331 +#define WND_BTHDUR_OK_H 98 +#define BREATH_GROUP_SIZE 466 + +BreathDurPage::BreathDurPage() {} + +BreathDurPage::~BreathDurPage() +{ + group->RemoveAll(); + if (lableTitle != nullptr) { + delete lableTitle; + lableTitle = nullptr; + } + if (pickerTime != nullptr) { + delete pickerTime; + pickerTime = nullptr; + } + if (buttonOk != nullptr) { + delete buttonOk; + buttonOk = nullptr; + } + if (group != nullptr) { + delete group; + group = nullptr; + } + if (center != nullptr) { + delete center; + center = nullptr; + } +} + +void BreathDurPage::OnStart(void *data) +{ + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnStart new Group ERROR"); + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + + if (lableTitle == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnStart new lableTitle ERROR"); + lableTitle = new UILabel(); + } + lableTitle->SetPosition(WND_BTHDUR_TITLE_X, WND_BTHDUR_TITLE_Y); + lableTitle->Resize(WND_BTHDUR_TITLE_W, WND_BTHDUR_TITLE_H); + lableTitle->SetText("时间设置"); + lableTitle->SetTextColor(Color::White()); + lableTitle->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHDUR_TITLE_FONT_SIZE); + lableTitle->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(lableTitle); + + if (pickerTime == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnStart new pickerTime ERROR"); + pickerTime = new UIPicker(); + } + pickerTime->SetPosition(WND_BTHDUR_PICKER_X, WND_BTHDUR_PICKER_Y); + pickerTime->Resize(WND_BTHDUR_PICKER_W, WND_BTHDUR_PICKER_H); + pickerTime->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + pickerTime->SetBackgroundFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHDUR_PICKER_B_FONT_SIZE); + pickerTime->SetHighlightFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHDUR_PICKER_H_FONT_SIZE); + pickerTime->SetItemHeight(WND_BTHDUR_PICKER_ITEM_H); + pickerTime->SetTextColor(Color::GetColorFromRGBA(0xfa, 0xf3, 0xf3, 0xff), + Color::GetColorFromRGBA(0xfa, 0xf3, 0xf3, 0xff)); + uint8_t selectTime = BreathModel::GetInstance().GetSelectTime(); + pickerTime->SetSelected(selectTime); + pickerTime->SetOnDragListener(this); + pickerTime->SetLoopState(false); + group->Add(pickerTime); + + if (center == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnStart new center ERROR"); + center = new UIImageView(); + } + center->SetPosition(WND_BTHDUR_PICKER_X, WND_BTHDUR_PICKER_Y); + center->Resize(WND_BTHDUR_PICKER_W, WND_BTHDUR_PICKER_H); + LOADIMG::LoadImageViewImg(center, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH013); + group->Add(center); + + if (buttonOk == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnStart new buttonOk ERROR"); + buttonOk = new UIButton(); + } + buttonOk->SetPosition(WND_BTHDUR_OK_X, WND_BTHDUR_OK_Y); + buttonOk->Resize(WND_BTHDUR_OK_W, WND_BTHDUR_OK_H); + buttonOk->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + buttonOk->SetViewId(WND_BTHDUR_BTN_OK_ID); + LOADIMG::LoadBtnImage(buttonOk, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH005, IMAGE_CONVERTER_TOOL_BREATH005); + buttonOk->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + buttonOk->SetOnClickListener(this); + group->Add(buttonOk); + + AddViewToPageContainer(group); +} + +void BreathDurPage::OnStop() {} + +void BreathDurPage::OnResume() +{ + pickerTime->SetValues(BreathModel::GetInstance().GetDurListData(), BreathModel::GetInstance().GetDurListSize()); + GetSlicePageContainer()->SetIntercept(true); + GetSlicePageContainer()->SetOnDragListener(nullptr); +} + +void BreathDurPage::OnPause() {} + +bool BreathDurPage::OnClick(UIView &view, const ClickEvent &event) +{ + if (strcmp(view.GetViewId(), WND_BTHDUR_BTN_OK_ID) == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathDurPage OnClick...ChangeTo DUR"); + BreathModel::GetInstance().SetTimeDuration(pickerTime->GetSelected()); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathDurPage OnClick...ChangeTo unknow"); + return false; + } + return true; +} + +bool BreathDurPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathDurPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathExerPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathExerPage.cpp new file mode 100644 index 000000000..92c689bb3 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathExerPage.cpp @@ -0,0 +1,323 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathExerPage + * Create: 2025-5-13 + */ +#include +#include +#include "gfx_utils/graphic_math.h" +#include "common/image_cache_manager.h" +#include "components/ui_image_animator.h" +#include "components/root_view.h" +#include "UiConfig.h" +#include "ohos_timer.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "PageTransitionMgr.h" +#include "ui_resource_breath.h" +#include "main/LoadImg.h" +#include "breath/BreathView.h" +#include "breath/BreathExerPage.h" + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_MAIN_BREATHEASE, BrearhView::BREATH_EXER_VIEW, BreathExerPage, false); + +#define BREATH_GROUP_SIZE 454 +#define BREATH_ZERO 0 +#define BREATH_ONE 1 +#define BREATH_TWO 2 +#define BREATH_THREE 3 +static constexpr uint16_t BREATH_PHONE_IMAGE_POSITION_X = 0; +static constexpr uint16_t BREATH_PHONE_IMAGE_POSITION_y = 0; +static constexpr uint16_t BREATH_PHONE_IMAGE_WIDTH = 400; +static constexpr uint16_t BREATH_PHONE_IMAGE_HEIGHT = 400; +static constexpr uint16_t BREATH_PHONE_IMAGEANIMATOR_POSITION_X = 170; +static constexpr uint16_t BREATH_PHONE_IMAGEANIMATOR_POSITION_Y = 170; +static constexpr uint16_t BREATH_PHONE_IMAGEANIMATOR_WIDTH = 100; +static constexpr uint16_t BREATH_PHONE_IMAGEANIMATOR_HEIGHT = 100; +static constexpr uint16_t IMAGE_SIZE = 454; +static constexpr uint16_t IMAGEANIMATOERVIEW_SIZE = 80; +static constexpr uint16_t FIND_PHONE_IMAGE_X = 1; +static constexpr uint16_t FIND_PHONE_IMAGE_y = 1; +static constexpr uint16_t FIND_PHONE_PIXELBYTE_SIZE = 4; +static constexpr uint16_t FIND_PHONE_PIXELBYTEH = 100; +static constexpr uint16_t END_TIME = 20; + +const int g_imageAnimatorInfo[IMAGEANIMATOERVIEW_SIZE] = { + IMAGE_CONVERTER_TOOL_INOREX_HALE001, IMAGE_CONVERTER_TOOL_INOREX_HALE002, IMAGE_CONVERTER_TOOL_INOREX_HALE003, + IMAGE_CONVERTER_TOOL_INOREX_HALE004, IMAGE_CONVERTER_TOOL_INOREX_HALE005, IMAGE_CONVERTER_TOOL_INOREX_HALE006, + IMAGE_CONVERTER_TOOL_INOREX_HALE007, IMAGE_CONVERTER_TOOL_INOREX_HALE008, IMAGE_CONVERTER_TOOL_INOREX_HALE009, + IMAGE_CONVERTER_TOOL_INOREX_HALE010, IMAGE_CONVERTER_TOOL_INOREX_HALE011, IMAGE_CONVERTER_TOOL_INOREX_HALE012, + IMAGE_CONVERTER_TOOL_INOREX_HALE013, IMAGE_CONVERTER_TOOL_INOREX_HALE014, IMAGE_CONVERTER_TOOL_INOREX_HALE015, + IMAGE_CONVERTER_TOOL_INOREX_HALE016, IMAGE_CONVERTER_TOOL_INOREX_HALE017, IMAGE_CONVERTER_TOOL_INOREX_HALE018, + IMAGE_CONVERTER_TOOL_INOREX_HALE019, IMAGE_CONVERTER_TOOL_INOREX_HALE020, IMAGE_CONVERTER_TOOL_INOREX_HALE021, + IMAGE_CONVERTER_TOOL_INOREX_HALE022, IMAGE_CONVERTER_TOOL_INOREX_HALE023, IMAGE_CONVERTER_TOOL_INOREX_HALE024, + IMAGE_CONVERTER_TOOL_INOREX_HALE025, IMAGE_CONVERTER_TOOL_INOREX_HALE026, IMAGE_CONVERTER_TOOL_INOREX_HALE027, + IMAGE_CONVERTER_TOOL_INOREX_HALE028, IMAGE_CONVERTER_TOOL_INOREX_HALE029, IMAGE_CONVERTER_TOOL_INOREX_HALE030, + IMAGE_CONVERTER_TOOL_INOREX_HALE031, IMAGE_CONVERTER_TOOL_INOREX_HALE032, IMAGE_CONVERTER_TOOL_INOREX_HALE033, + IMAGE_CONVERTER_TOOL_INOREX_HALE034, IMAGE_CONVERTER_TOOL_INOREX_HALE035, IMAGE_CONVERTER_TOOL_INOREX_HALE036, + IMAGE_CONVERTER_TOOL_INOREX_HALE037, IMAGE_CONVERTER_TOOL_INOREX_HALE038, IMAGE_CONVERTER_TOOL_INOREX_HALE039, + IMAGE_CONVERTER_TOOL_INOREX_HALE040, IMAGE_CONVERTER_TOOL_INOREX_HALE041, IMAGE_CONVERTER_TOOL_INOREX_HALE042, + IMAGE_CONVERTER_TOOL_INOREX_HALE043, IMAGE_CONVERTER_TOOL_INOREX_HALE044, IMAGE_CONVERTER_TOOL_INOREX_HALE045, + IMAGE_CONVERTER_TOOL_INOREX_HALE046, IMAGE_CONVERTER_TOOL_INOREX_HALE047, IMAGE_CONVERTER_TOOL_INOREX_HALE048, + IMAGE_CONVERTER_TOOL_INOREX_HALE049, IMAGE_CONVERTER_TOOL_INOREX_HALE050, IMAGE_CONVERTER_TOOL_INOREX_HALE051, + IMAGE_CONVERTER_TOOL_INOREX_HALE052, IMAGE_CONVERTER_TOOL_INOREX_HALE053, IMAGE_CONVERTER_TOOL_INOREX_HALE054, + IMAGE_CONVERTER_TOOL_INOREX_HALE055, IMAGE_CONVERTER_TOOL_INOREX_HALE056, IMAGE_CONVERTER_TOOL_INOREX_HALE057, + IMAGE_CONVERTER_TOOL_INOREX_HALE058, IMAGE_CONVERTER_TOOL_INOREX_HALE059, IMAGE_CONVERTER_TOOL_INOREX_HALE060, + IMAGE_CONVERTER_TOOL_INOREX_HALE061, IMAGE_CONVERTER_TOOL_INOREX_HALE062, IMAGE_CONVERTER_TOOL_INOREX_HALE063, + IMAGE_CONVERTER_TOOL_INOREX_HALE064, IMAGE_CONVERTER_TOOL_INOREX_HALE065, IMAGE_CONVERTER_TOOL_INOREX_HALE066, + IMAGE_CONVERTER_TOOL_INOREX_HALE067, IMAGE_CONVERTER_TOOL_INOREX_HALE068, IMAGE_CONVERTER_TOOL_INOREX_HALE068, + IMAGE_CONVERTER_TOOL_INOREX_HALE069, IMAGE_CONVERTER_TOOL_INOREX_HALE070, IMAGE_CONVERTER_TOOL_INOREX_HALE071, + IMAGE_CONVERTER_TOOL_INOREX_HALE072, IMAGE_CONVERTER_TOOL_INOREX_HALE073, IMAGE_CONVERTER_TOOL_INOREX_HALE074, + IMAGE_CONVERTER_TOOL_INOREX_HALE075, IMAGE_CONVERTER_TOOL_INOREX_HALE076, IMAGE_CONVERTER_TOOL_INOREX_HALE077, + IMAGE_CONVERTER_TOOL_INOREX_HALE078, IMAGE_CONVERTER_TOOL_INOREX_HALE078, +}; + +BreathExerPage::BreathExerPage() {} + +BreathExerPage::~BreathExerPage() +{ + group->RemoveAll(); + if (group != nullptr) { + delete group; + group = nullptr; + } + if (imageAnimator_ != nullptr) { + delete imageAnimator_; + imageAnimator_ = nullptr; + } + if (animatorCallBack != nullptr) { + delete animatorCallBack; + animatorCallBack = nullptr; + } + ImageCacheManager::GetInstance().UnloadAllInMultiRes(BREATH_IMAGE); +} + +void BreathExerPage::OnStart(void *data) +{ + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::OnStart new group ERROR"); + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetTouchable(true); + group->SetDraggable(true); + group->SetOnDragListener(this); + + palyNumber = BreathModel::GetInstance().GetTheNumberOfPlays(); + SetUpImageAnimator(); + + imageAnimator_->Start(); + imageAnimator_->SetVisible(true); + animatorCallBack = new BreathExerPageCallback(this); + if (animatorCallBack == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::OnStart new animatorCallBack ERROR"); + return; + } + animation = new Animator(animatorCallBack, nullptr, 0, true); + if (animation == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::OnStart new animation ERROR"); + return; + } + animation->Start(); + + AddViewToPageContainer(group); +} +void BreathExerPage::OnStop() {} + +void BreathExerPage::SetUpImageAnimator() +{ + imageAnimator_ = new UIImageAnimatorView(); + if (imageAnimator_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::UIImageAnimatorView new Label SetUpImageAnimator fail"); + return; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathExerPage::SetUpImageAnimator "); + imageAnimator_ = new UIImageAnimatorView(); + for (uint32_t DATA = 0; DATA < IMAGEANIMATOERVIEW_SIZE; DATA++) { + searchImageInfo[DATA].imageInfo = + ImageCacheManager::GetInstance().LoadOneInMultiRes(g_imageAnimatorInfo[DATA], BREATH_IMAGE); + searchImageInfo[DATA].imageType = IMG_SRC_IMAGE_INFO; + searchImageInfo[DATA].pos.x = FIND_PHONE_IMAGE_X; + searchImageInfo[DATA].pos.y = FIND_PHONE_IMAGE_y; + searchImageInfo[DATA].width = IMAGE_SIZE; + searchImageInfo[DATA].height = IMAGE_SIZE; + } + imageAnimator_->SetPosition(BREATH_PHONE_IMAGE_POSITION_X, BREATH_PHONE_IMAGE_POSITION_y, BREATH_PHONE_IMAGE_WIDTH, + BREATH_PHONE_IMAGE_HEIGHT); + int imageNumber = IMAGEANIMATOERVIEW_SIZE; + int ImageUpdate = BreathModel::GetInstance().GetStatusRespiratory(); + imageAnimator_->SetImageAnimatorSrc(searchImageInfo, imageNumber, ImageUpdate); + imageAnimator_->LayoutCenterOfParent(); + imageAnimator_->SetDraggable(true); + imageAnimator_->SetRepeat(false); + imageAnimator_->SetRepeatTimes(palyNumber); + imageAnimator_->SetOnDragListener(this); + group->Add(imageAnimator_); + InitImageInfo(); +} + +void BreathExerPage::BreathExerPageCallback::Callback(UIView *view) +{ + UNUSED(view); + static int count = 0; + struct timeval currentTime; + uint32_t breathingTime; + + breathingTime = BreathModel::GetInstance().GetTimeBreathing(); + gettimeofday(¤tTime, nullptr); + int32_t StartTime = BreathModel::GetInstance().GetBeginsTime(); + int32_t remTime = breathingTime - (currentTime.tv_sec - StartTime); + if (remTime <= END_TIME) { + if (BreathExerPage->imageAnimator_->GetState() == false) { + BreathExerPage->animation->Stop(); + BreathExerPage->imageAnimator_->Stop(); + BreathExerPage->imageAnimator_->SetVisible(false); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_RESULT_VIEW, nullptr, + TransitionType::TRANSITION_INVALID, true); + } + } +} + +void BreathExerPage::OnPause() +{ + animation->Stop(); + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); +} + +bool BreathExerPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathExerPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathExerPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + animation->Stop(); + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } + return true; +} +void BreathExerPage::OnTimer() {} + +void BreathExerPage::InitImageInfo() +{ + const uint16_t pixelByteSize = FIND_PHONE_PIXELBYTE_SIZE; + const uint16_t width = FIND_PHONE_PIXELBYTEH; + const uint16_t height = FIND_PHONE_PIXELBYTEH; + uint32_t dataSize = width * height * pixelByteSize; + uint8_t *srcData1 = static_cast(UIMalloc(dataSize)); + if (srcData1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::InitImageInfo new srcData1 ERROR"); + return; + } + + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData1[i] = SET_INT_MAX_; + srcData1[i + BREATH_ONE] = 0; + srcData1[i + BREATH_TWO] = 0; + srcData1[i + BREATH_THREE] = OPA_OPAQUE; + } + imageInfoOen = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfoOen == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::InitImageInfo new imageInfoOen ERROR"); + UIFree(srcData1); + return; + } + + imageInfoOen->header.width = width; + imageInfoOen->header.height = height; + imageInfoOen->header.colorMode = ColorMode::ARGB8888; + imageInfoOen->dataSize = dataSize; + imageInfoOen->data = srcData1; + + uint8_t *srcData2 = static_cast(UIMalloc(dataSize)); + if (srcData2 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::InitImageInfo new srcData2 ERROR"); + UIFree(imageInfoOen); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData2[i] = 0; + srcData2[i + BREATH_ONE] = SET_INT_MAX_; + srcData2[i + BREATH_TWO] = 0; + srcData2[i + BREATH_THREE] = OPA_OPAQUE; + } + + imageInfoTwo = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfoTwo == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::InitImageInfo new imageInfoTwo ERROR"); + UIFree(srcData2); + UIFree(imageInfoOen); + UIFree(srcData1); + return; + } + imageInfoTwo->header.width = width; + imageInfoTwo->header.height = height; + imageInfoTwo->header.colorMode = ARGB8888; + imageInfoTwo->dataSize = dataSize; + imageInfoTwo->data = srcData2; + + uint8_t *srcData3 = static_cast(UIMalloc(dataSize)); + if (srcData3 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::InitImageInfo new srcData3 ERROR"); + UIFree(imageInfoTwo); + UIFree(srcData2); + UIFree(imageInfoOen); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData3[i] = 0; + srcData3[i + BREATH_ONE] = 0; + srcData3[i + BREATH_TWO] = SET_INT_MAX_; + srcData3[i + BREATH_THREE] = OPA_OPAQUE; + } + + imageInfoThree = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfoThree == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathExerPage::InitImageInfo new imageInfoThree ERROR"); + UIFree(srcData3); + UIFree(imageInfoTwo); + UIFree(srcData2); + UIFree(imageInfoOen); + UIFree(srcData1); + return; + } + imageInfoThree->header.width = width; + imageInfoThree->header.height = height; + imageInfoThree->header.colorMode = ARGB8888; + imageInfoThree->dataSize = dataSize; + imageInfoThree->data = srcData3; + + imageAnimatorImageInfo[BREATH_ZERO].imageInfo = imageInfoOen; + imageAnimatorImageInfo[BREATH_ZERO].pos = {BREATH_PHONE_IMAGEANIMATOR_POSITION_X, + BREATH_PHONE_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo[BREATH_ZERO].width = BREATH_PHONE_IMAGEANIMATOR_WIDTH; + imageAnimatorImageInfo[BREATH_ZERO].height = BREATH_PHONE_IMAGEANIMATOR_HEIGHT; + imageAnimatorImageInfo[BREATH_ZERO].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo[BREATH_ONE].imageInfo = imageInfoTwo; + imageAnimatorImageInfo[BREATH_ONE].pos = {BREATH_PHONE_IMAGEANIMATOR_POSITION_X, + BREATH_PHONE_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo[BREATH_ONE].width = BREATH_PHONE_IMAGEANIMATOR_WIDTH; + imageAnimatorImageInfo[BREATH_ONE].height = BREATH_PHONE_IMAGEANIMATOR_HEIGHT; + imageAnimatorImageInfo[BREATH_ONE].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo[BREATH_TWO].imageInfo = imageInfoThree; + imageAnimatorImageInfo[BREATH_TWO].pos = {BREATH_PHONE_IMAGEANIMATOR_POSITION_X, + BREATH_PHONE_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo[BREATH_TWO].width = BREATH_PHONE_IMAGEANIMATOR_WIDTH; + imageAnimatorImageInfo[BREATH_TWO].height = BREATH_PHONE_IMAGEANIMATOR_HEIGHT; + imageAnimatorImageInfo[BREATH_TWO].imageType = IMG_SRC_IMAGE_INFO; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathMainPage.cpp new file mode 100644 index 000000000..3b12ef70f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathMainPage.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathMainPage + * Create: 2025-5-13 + */ +#include "gfx_utils/graphic_math.h" +#include "UiConfig.h" +#include "AppViewIDs.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "alarm/MainAlarmView.h" +#include "NativeAbility.h" +#include "TransitionType.h" +#include "SlicePageFactory.h" +#include "PageTransitionMgr.h" +#include "ui_resource_breath.h" +#include "main/LoadImg.h" +#include "breath/BreathModel.h" +#include "breath/BreathMainPage.h" + +namespace OHOS { + +#define WND_BTHMAIN_BTN_DUR_ID "BTH_MAIN_DUR" +#define WND_BTHMAIN_BTN_RHY_ID "BTH_MAIN_RHY" +#define WND_BTHMAIN_BTN_START_ID "BTH_MAIN_START" +#define WND_BTHMAIN_TITLE_X 97 +#define WND_BTHMAIN_TITLE_Y 34 +#define WND_BTHMAIN_TITLE_W 260 +#define WND_BTHMAIN_TITLE_H 53 +#define WND_BTHMAIN_TITLE_FONT_SIZE 38 +#define WND_BTHMAIN_DURBTN_X 16 +#define WND_BTHMAIN_DURBTN_Y 190 +#define WND_BTHMAIN_DURBTN_W 74 +#define WND_BTHMAIN_DURBTN_H 74 +#define WND_BTHMAIN_RHYBTN_X 364 +#define WND_BTHMAIN_RHYBTN_Y 190 +#define WND_BTHMAIN_RHYBTN_W 74 +#define WND_BTHMAIN_RHYBTN_H 74 +#define WND_BTHMAIN_STARTBTN_X 60 +#define WND_BTHMAIN_STARTBTN_Y 358 +#define WND_BTHMAIN_STARTBTN_W 333 +#define WND_BTHMAIN_STARTBTN_H 96 +#define WND_BTHMAIN_DURLAB_X 20 +#define WND_BTHMAIN_DURLAB_Y 275 +#define WND_BTHMAIN_DURLAB_W 65 +#define WND_BTHMAIN_DURLAB_H 30 +#define WND_BTHMAIN_RHYLAB_X 376 +#define WND_BTHMAIN_RHYLAB_Y 275 +#define WND_BTHMAIN_RHYLAB_W 50 +#define WND_BTHMAIN_RHYLAB_H 30 +#define WND_BTHMAIN_CENTER_XY 127 +#define WND_BTHMAIN_CENTER_WH 200 +#define WND_BTHMAIN_lableSetting_FONT_SIZE 24 +#define WND_BTHMAIN_lableTime_FONT_SIZE 20 +#define BREATH_GROUP_SIZE 466 + +REGIST_SLICE_PAGE(VIEW_MAIN_BREATHEASE, BrearhView::BREATH_MAIN_VIEW, BreathMainPage, true); + +BreathMainPage::~BreathMainPage() +{ + group->RemoveAll(); + if (lableSetting != nullptr) { + delete lableSetting; + lableSetting = nullptr; + } + if (buttonStart != nullptr) { + delete buttonStart; + buttonStart = nullptr; + } + if (buttonSetting != nullptr) { + delete buttonSetting; + buttonSetting = nullptr; + } + if (buttonTime != nullptr) { + delete buttonTime; + buttonTime = nullptr; + } + if (lableBreathing != nullptr) { + delete lableBreathing; + lableBreathing = nullptr; + } + if (lableTime != nullptr) { + delete lableTime; + lableTime = nullptr; + } + if (group != nullptr) { + delete group; + group = nullptr; + } + if (background != nullptr) { + delete background; + background = nullptr; + } + if (center != nullptr) { + delete center; + center = nullptr; + } +} + +void BreathMainPage::OnStart(void *data) +{ + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new group ERROR"); + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetTouchable(true); + group->SetDraggable(true); + group->SetOnDragListener(this); + + if (background == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new Background ERROR"); + background = new UIImageView(); + } + background->SetPosition(0, 0); + background->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + LOADIMG::LoadImageViewImg(background, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH001); + group->Add(background); + + if (center == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new Center ERROR"); + center = new UIImageView(); + } + center->SetPosition(WND_BTHMAIN_CENTER_XY, WND_BTHMAIN_CENTER_XY); + center->Resize(WND_BTHMAIN_CENTER_WH, WND_BTHMAIN_CENTER_WH); + LOADIMG::LoadImageViewImg(center, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH012); + group->Add(center); + + if (lableBreathing == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new lableBreathing ERROR"); + lableBreathing = new UILabel(); + } + lableBreathing->SetPosition(WND_BTHMAIN_TITLE_X, WND_BTHMAIN_TITLE_Y); + lableBreathing->Resize(WND_BTHMAIN_TITLE_W, WND_BTHMAIN_TITLE_H); + lableBreathing->SetText("呼吸"); + lableBreathing->SetTextColor(Color::White()); + lableBreathing->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + lableBreathing->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_TITLE_FONT_SIZE); + group->Add(lableBreathing); + + if (buttonTime == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new buttonTime ERROR"); + buttonTime = new UIButton(); + } + buttonTime->SetPosition(WND_BTHMAIN_DURBTN_X, WND_BTHMAIN_DURBTN_Y); + buttonTime->Resize(WND_BTHMAIN_DURBTN_W, WND_BTHMAIN_DURBTN_H); + buttonTime->SetViewId(WND_BTHMAIN_BTN_DUR_ID); + buttonTime->SetOnClickListener(this); + LOADIMG::LoadBtnImage(buttonTime, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH002, IMAGE_CONVERTER_TOOL_BREATH002); + buttonTime->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + buttonTime->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + group->Add(buttonTime); + + if (buttonSetting == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new buttonSetting ERROR"); + buttonSetting = new UIButton(); + } + buttonSetting->SetPosition(WND_BTHMAIN_RHYBTN_X, WND_BTHMAIN_RHYBTN_Y); + buttonSetting->Resize(WND_BTHMAIN_RHYBTN_W, WND_BTHMAIN_RHYBTN_H); + buttonSetting->SetViewId(WND_BTHMAIN_BTN_RHY_ID); + buttonSetting->SetOnClickListener(this); + LOADIMG::LoadBtnImage(buttonSetting, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH004, IMAGE_CONVERTER_TOOL_BREATH004); + buttonSetting->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + buttonSetting->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + group->Add(buttonSetting); + + if (buttonStart == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new buttonStart ERROR"); + buttonStart = new UIButton(); + } + buttonStart->SetPosition(WND_BTHMAIN_STARTBTN_X, WND_BTHMAIN_STARTBTN_Y); + buttonStart->Resize(WND_BTHMAIN_STARTBTN_W, WND_BTHMAIN_STARTBTN_H); + buttonStart->SetViewId(WND_BTHMAIN_BTN_START_ID); + buttonStart->SetOnClickListener(this); + LOADIMG::LoadBtnImage(buttonStart, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH006, IMAGE_CONVERTER_TOOL_BREATH006); + buttonStart->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + buttonStart->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + group->Add(buttonStart); + + if (lableSetting == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new lableSetting ERROR"); + lableSetting = new UILabel(); + } + lableSetting->SetPosition(WND_BTHMAIN_RHYLAB_X, WND_BTHMAIN_RHYLAB_Y); + lableSetting->Resize(WND_BTHMAIN_RHYLAB_W, WND_BTHMAIN_RHYLAB_H); + lableSetting->SetText("设置"); + lableSetting->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + lableSetting->SetTextColor(Color::White()); + lableSetting->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + lableSetting->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_lableSetting_FONT_SIZE); + group->Add(lableSetting); + + if (lableTime == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnStart new lableTime ERROR"); + lableTime = new UILabel(); + } + lableTime->SetPosition(WND_BTHMAIN_DURLAB_X, WND_BTHMAIN_DURLAB_Y); + lableTime->Resize(WND_BTHMAIN_DURLAB_W, WND_BTHMAIN_DURLAB_H); + lableTime->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + lableTime->SetTextColor(Color::White()); + lableTime->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + lableTime->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_lableTime_FONT_SIZE); + group->Add(lableTime); + + AddViewToPageContainer(group); +} + +void BreathMainPage::OnStop(void) {} + +void BreathMainPage::OnResume(void) +{ + lableTime->SetText(BreathModel::GetInstance().GetTimeDuration()); +} + +bool BreathMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + if (strcmp(view.GetViewId(), WND_BTHMAIN_BTN_DUR_ID) == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathMainPage OnClick...ChangeTo DUR"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_DUR_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } else if (strcmp(view.GetViewId(), WND_BTHMAIN_BTN_RHY_ID) == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathMainPage OnClick...ChangeTo RHY"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_RHY_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } else if (strcmp(view.GetViewId(), WND_BTHMAIN_BTN_START_ID) == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathMainPage OnClick...ChangeTo START"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_START_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + uint32_t remTime = current_time.tv_sec; + BreathModel::GetInstance().SetSaveTime(remTime); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage OnClick...ChangeTo unknow"); + return false; + } + return true; +} + +bool BreathMainPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathMainPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathModel.cpp new file mode 100644 index 000000000..ef067f2c9 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathModel.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathModel + * Create: 2025-5-13 + */ +#include "uiservice/ui_service.h" +#include "main/HealthModel.h" +#include "breath/BreathDurPage.h" +#include "breath/BreathModel.h" + +namespace OHOS { +#define MINUTE_IDX_1 0 +#define MINUTE_IDX_2 1 +#define MINUTE_IDX_3 2 +#define SPEED_IDX_1 0 +#define SPEED_IDX_2 1 +#define SPEED_IDX_3 2 +#define MINUTE_1 "1 分钟" +#define MINUTE_2 "2 分钟" +#define MINUTE_3 "3 分钟" +#define SPEED_FAST_8 "稍快 8次/分" +#define SPEED_SLOW_7 "舒缓 7次/分" +#define SPEED_SLOW_6 "缓慢 6次/分" +#define TIME_1 "1" +#define TIME_2 "2" +#define TIME_3 "3" +#define SPEED_FASTER_LITTLE "稍快" +#define SPEED_SOOTHING "舒缓" +#define SPEED_SLOWING "缓慢" +#define MINUTE_0_DATA 0 +#define MINUTE_1_DATA 1 +#define MINUTE_2_DATA 2 +#define MINUTE_3_DATA 3 +#define NUMBLE_PLAY_8_DATA 8 +#define NUMBLE_PLAY_7_DATA 7 +#define NUMBLE_PLAY_6_DATA 6 +#define NUMBLE_PLAY_16_DATA 16 +#define NUMBLE_PLAY_14_DATA 14 +#define NUMBLE_PLAY_12_DATA 12 +#define NUMBLE_PLAY_24_DATA 24 +#define NUMBLE_PLAY_21_DATA 21 +#define NUMBLE_PLAY_18_DATA 18 +#define Frequency_Score_LOWER 60 +#define Frequency_Score_RANGE 40 +#define Heart_Rate_LOWER 90 +#define Heart_Rate_RANGE 10 +#define ONE_MINUTE 60 +#define TWO_MINUTES 120 +#define THREE_MINUTES 180 +#define SIX_POINTS_FOR_ONE 125 +#define SEVEN_POINTS_FOR_ONE 106 +#define EIGHT_POINTS_FOR_ONE 98 +uint8_t g_frequencyScore; +uint8_t g_heartRate; + +BreathModel::BreathModel() +{ + DefaultData(); +} + +BreathModel::~BreathModel() {} + +void BreathModel::DefaultData() +{ + durList[MINUTE_IDX_1] = MINUTE_1; + durList[MINUTE_IDX_2] = MINUTE_2; + durList[MINUTE_IDX_3] = MINUTE_3; + rhyList[SPEED_IDX_1] = SPEED_FAST_8; + rhyList[SPEED_IDX_2] = SPEED_SLOW_7; + rhyList[SPEED_IDX_3] = SPEED_SLOW_6; + durListVal[MINUTE_IDX_1] = MINUTE_1_DATA; + durListVal[MINUTE_IDX_2] = MINUTE_2_DATA; + durListVal[MINUTE_IDX_3] = MINUTE_3_DATA; +} + +BreathModel &BreathModel::GetInstance() +{ + static BreathModel instance; + return instance; +} + +const char **BreathModel::GetDurListData() +{ + return durList; +} + +const char **BreathModel::GetRhyListData() +{ + return rhyList; +} + +uint8_t BreathModel::GetDurListSize() +{ + return sizeof(durList) / sizeof(durList[0]); +} + +uint8_t BreathModel::GetRhyListSize() +{ + return sizeof(rhyList) / sizeof(rhyList[0]); +} + +void BreathModel::SetTimeDuration(uint16_t idx) +{ + data = idx; +} + +void BreathModel::SetTimeRhyation(uint16_t idx) +{ + date = idx; +} + +uint8_t BreathModel::GetSelectTime() +{ + if (data == MINUTE_0_DATA) { + return MINUTE_IDX_1; + } else if (data == MINUTE_1_DATA) { + return MINUTE_IDX_2; + } else if (data == MINUTE_2_DATA) { + return MINUTE_IDX_3; + } + return 0; +} + +uint8_t BreathModel::GetSelectTempo() +{ + if (date == MINUTE_0_DATA) { + return SPEED_IDX_1; + } else if (date == MINUTE_1_DATA) { + return SPEED_IDX_2; + } else if (date == MINUTE_2_DATA) { + return SPEED_IDX_3; + } + return 0; +} + +char *BreathModel::GetTimeDuration() +{ + if (data == MINUTE_0_DATA) { + return MINUTE_1; + } else if (data == MINUTE_1_DATA) { + return MINUTE_2; + } else if (data == MINUTE_2_DATA) { + return MINUTE_3; + } + return nullptr; +} + +char *BreathModel::GetDuration() +{ + if (data == MINUTE_0_DATA) { + return TIME_1; + } else if (data == MINUTE_1_DATA) { + return TIME_2; + } else if (data == MINUTE_2_DATA) { + return TIME_3; + } + return nullptr; +} + +char *BreathModel::GetRhythm() +{ + if (date == MINUTE_0_DATA) { + return SPEED_FASTER_LITTLE; + } else if (date == MINUTE_1_DATA) { + return SPEED_SOOTHING; + } else if (date == MINUTE_2_DATA) { + return SPEED_SLOWING; + } + return nullptr; +} + +void BreathModel::SetSaveTime(int32_t idx) +{ + saveTime = idx; +} + +int32_t BreathModel::GetSaveTime() +{ + return saveTime; +} + +void BreathModel::SetBeginsTime(int32_t idx) +{ + beginsTime = idx; +} + +int32_t BreathModel::GetBeginsTime() +{ + return beginsTime; +} + +uint32_t BreathModel::GetTimeBreathing() +{ + if (data == MINUTE_0_DATA) { + return ONE_MINUTE; + } else if (data == MINUTE_1_DATA) { + return TWO_MINUTES; + } else if (data == MINUTE_2_DATA) { + return THREE_MINUTES; + } + return 0; +} + +uint32_t BreathModel::GetStatusRespiratory() +{ + if (date == MINUTE_0_DATA) { + return EIGHT_POINTS_FOR_ONE; + } else if (date == MINUTE_1_DATA) { + return SEVEN_POINTS_FOR_ONE; + } else if (date == MINUTE_2_DATA) { + return SIX_POINTS_FOR_ONE; + } + return 0; +} + +void BreathModel::SetFrequencyScore() +{ + g_frequencyScore = Frequency_Score_LOWER + rand() % Frequency_Score_RANGE; +} + +uint8_t BreathModel::GetFrequencyScore() +{ + return g_frequencyScore; +} + +void BreathModel::SetHeartRate() +{ + g_heartRate = Heart_Rate_LOWER + rand() % Heart_Rate_RANGE; +} + +uint8_t BreathModel::GetHeartRate() +{ + return g_heartRate; +} + +uint32_t BreathModel::GetTheNumberOfPlays() +{ + if (date == MINUTE_0_DATA && data == MINUTE_0_DATA) { + return NUMBLE_PLAY_8_DATA; + } else if (date == MINUTE_1_DATA && data == MINUTE_0_DATA) { + return NUMBLE_PLAY_7_DATA; + } else if (date == MINUTE_2_DATA && data == MINUTE_0_DATA) { + return NUMBLE_PLAY_6_DATA; + } else if (date == MINUTE_0_DATA && data == MINUTE_1_DATA) { + return NUMBLE_PLAY_16_DATA; + } else if (date == MINUTE_1_DATA && data == MINUTE_1_DATA) { + return NUMBLE_PLAY_14_DATA; + } else if (date == MINUTE_2_DATA && data == MINUTE_1_DATA) { + return NUMBLE_PLAY_12_DATA; + } else if (date == MINUTE_0_DATA && data == MINUTE_2_DATA) { + return NUMBLE_PLAY_24_DATA; + } else if (date == MINUTE_1_DATA && data == MINUTE_2_DATA) { + return NUMBLE_PLAY_21_DATA; + } else if (date == MINUTE_2_DATA && data == MINUTE_2_DATA) { + return NUMBLE_PLAY_18_DATA; + } + return 0; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathPresenter.cpp new file mode 100644 index 000000000..61c31fb7d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathPresenter.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathPresenter + * Create: 2025-5-13 + */ +#include "AppViewIDs.h" +#include "NativeRegisterManager.h" +#include "breath/BreathView.h" +#include "breath/BreathPresenter.h" + +namespace OHOS { +REGIST_MENU(VIEW_MAIN_BREATHEASE, BreathView, BreathPresenter, BREATH_MAIN_ICON, BREATH_MAIN_ICON, "呼吸训练"); +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathResultPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathResultPage.cpp new file mode 100644 index 000000000..1f4796678 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathResultPage.cpp @@ -0,0 +1,353 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathReult + * Create: 2025-5-13 + */ +#include +#include "gfx_utils/graphic_math.h" +#include "components/root_view.h" +#include "UiConfig.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "TransitionType.h" +#include "SlicePageFactory.h" +#include "main/LoadImg.h" +#include "ui_resource_breath.h" +#include "breath/BreathView.h" +#include "breath/BreathResultPage.h" + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_MAIN_BREATHEASE, BrearhView::BREATH_RESULT_VIEW, BreathResultPage, false); +#define WND_BTHMAIN_RESULTS_X 97 +#define WND_BTHMAIN_RESULTS_Y 34 +#define WND_BTHMAIN_RESULTS_W 260 +#define WND_BTHMAIN_RESULTS_H 53 +#define WND_BTHMAIN_MAX_FONT_SIZE 38 +#define WND_BTHMAIN_FREQUENCIES_X 140 +#define WND_BTHMAIN_FREQUENCIES_Y 133 +#define WND_BTHMAIN_FREQUENCIES_W 164 +#define WND_BTHMAIN_FREQUENCIES_H 30 +#define WND_BTHMAIN_MIN_FONT_SIZE 24 +#define WND_BTHMAIN_HEARTRATE_X 149 +#define WND_BTHMAIN_HEARTRATE_Y 233 +#define WND_BTHMAIN_HEARTRATE_W 120 +#define WND_BTHMAIN_HEARTRATE_H 30 +#define WND_BTHMAIN_FREQUEBCY_TIMES_X 204 +#define WND_BTHMAIN_FREQUEBCY_TIMES_Y 179 +#define WND_BTHMAIN_FREQUEBCY_TIMES_W 29 +#define WND_BTHMAIN_FREQUEBCY_TIMES_H 29 +#define WND_BTHMAIN_HEARTRATE_TIMES_X 204 +#define WND_BTHMAIN_HEARTRATE_TIMES_Y 279 +#define WND_BTHMAIN_HEARTRATE_TIMES_W 58 +#define WND_BTHMAIN_HEARTRATE_TIMES_H 29 +#define WND_BTHMAIN_DURATION_X 149 +#define WND_BTHMAIN_DURATION_Y 333 +#define WND_BTHMAIN_DURATION_W 96 +#define WND_BTHMAIN_DURATION_H 30 +#define WND_BTHMAIN_FREQUENCIES_SCOUT_X 149 +#define WND_BTHMAIN_FREQUENCIES_SCOUT_Y 165 +#define WND_BTHMAIN_FREQUENCIES_SCOUT_W 49 +#define WND_BTHMAIN_FREQUENCIES_SCOUT_H 49 +#define WND_BTHMAIN_SCOUT_FONT_SIZE 40 +#define WND_BTHMAIN_HEARTRATE_SCOUT_X 149 +#define WND_BTHMAIN_HEARTRATE_SCOUT_Y 265 +#define WND_BTHMAIN_HEARTRATE_SCOUT_W 49 +#define WND_BTHMAIN_HEARTRATE_SCOUT_H 49 +#define WND_BTHMAIN_RHYTHM_X 161 +#define WND_BTHMAIN_RHYTHM_Y 83 +#define WND_BTHMAIN_RHYTHM_W 132 +#define WND_BTHMAIN_RHYTHM_H 30 +#define WND_BTHMAIN_TIME_X 149 +#define WND_BTHMAIN_TIME_Y 365 +#define WND_BTHMAIN_TIME_W 25 +#define WND_BTHMAIN_TIME_H 48 +#define WND_BTHMAIN_TIME_UNIT_X 180 +#define WND_BTHMAIN_TIME_UNIT_Y 379 +#define WND_BTHMAIN_TIME_UNIT_W 58 +#define WND_BTHMAIN_TIME_UNIT_H 29 +#define WND_BTHMAIN_SCORES_X 241 +#define WND_BTHMAIN_SCORES_Y 177 +#define WND_BTHMAIN_SCORES_W 72 +#define WND_BTHMAIN_SCORES_H 32 +#define BREATH_GROUP_SIZE 466 +#define BREATH_GUINEAS_SIZE 100 +#define BREATH_NINETY_SIZE 90 +#define BREATH_EIGHTY_NINE_SIZE 89 +#define BREATH_EIGHTY_SIZE 80 +#define BREATH_SEVENTY_NINE_SIZE 79 +#define BREATH_SEVENTY_SIZE 70 +#define BREATH_SIXTY_NINE_SIZE 69 +#define BREATH_SIXTY_SIZE 60 +#define TEXT_OPACITY 147 +#define TEXT_SIZE 5 + +BreathResultPage::BreathResultPage() {} + +BreathResultPage::~BreathResultPage() +{ + group->RemoveAll(); + if (trainingResults != nullptr) { + delete trainingResults; + trainingResults = nullptr; + } + if (trainingFrequencies != nullptr) { + delete trainingFrequencies; + trainingFrequencies = nullptr; + } + if (trainingHeartRate != nullptr) { + delete trainingHeartRate; + trainingHeartRate = nullptr; + } + if (trainingDuration != nullptr) { + delete trainingDuration; + trainingDuration = nullptr; + } + if (frequenciesScout != nullptr) { + delete frequenciesScout; + frequenciesScout = nullptr; + } + if (heartRateScout != nullptr) { + delete heartRateScout; + heartRateScout = nullptr; + } + if (descriptionBreathing != nullptr) { + delete descriptionBreathing; + descriptionBreathing = nullptr; + } + if (time != nullptr) { + delete time; + time = nullptr; + } + if (timeUnit != nullptr) { + delete timeUnit; + timeUnit = nullptr; + } + if (heartRateTimes != nullptr) { + delete heartRateTimes; + heartRateTimes = nullptr; + } + if (frequencyTimes != nullptr) { + delete frequencyTimes; + frequencyTimes = nullptr; + } + if (group != nullptr) { + delete group; + group = nullptr; + } + if (scores != nullptr) { + delete scores; + scores = nullptr; + } +} + +void BreathResultPage::OnStart(void *data) +{ + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new group ERROR"); + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetTouchable(true); + group->SetDraggable(true); + group->SetOnDragListener(this); + + if (trainingResults == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new trainingResults ERROR"); + trainingResults = new UILabel(); + } + trainingResults->SetPosition(WND_BTHMAIN_RESULTS_X, WND_BTHMAIN_RESULTS_Y); + trainingResults->Resize(WND_BTHMAIN_RESULTS_W, WND_BTHMAIN_RESULTS_H); + trainingResults->SetText("训练结果"); + trainingResults->SetTextColor(Color::White()); + trainingResults->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MAX_FONT_SIZE); + trainingResults->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(trainingResults); + + if (trainingFrequencies == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new trainingFrequencies ERROR"); + trainingFrequencies = new UILabel(); + } + trainingFrequencies->SetPosition(WND_BTHMAIN_FREQUENCIES_X, WND_BTHMAIN_FREQUENCIES_Y); + trainingFrequencies->Resize(WND_BTHMAIN_FREQUENCIES_W, WND_BTHMAIN_FREQUENCIES_H); + trainingFrequencies->SetText("呼吸频率得分"); + trainingFrequencies->SetTextColor(Color::White()); + trainingFrequencies->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + trainingFrequencies->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + trainingFrequencies->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(trainingFrequencies); + + if (trainingHeartRate == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new trainingHeartRate ERROR"); + trainingHeartRate = new UILabel(); + } + trainingHeartRate->SetPosition(WND_BTHMAIN_HEARTRATE_X, WND_BTHMAIN_HEARTRATE_Y); + trainingHeartRate->Resize(WND_BTHMAIN_HEARTRATE_W, WND_BTHMAIN_HEARTRATE_H); + trainingHeartRate->SetText("呼吸前心率"); + trainingHeartRate->SetTextColor(Color::White()); + trainingHeartRate->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + trainingHeartRate->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + trainingHeartRate->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(trainingHeartRate); + + if (frequencyTimes == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new frequencyTimes ERROR"); + frequencyTimes = new UILabel(); + } + frequencyTimes->SetPosition(WND_BTHMAIN_FREQUEBCY_TIMES_X, WND_BTHMAIN_FREQUEBCY_TIMES_Y); + frequencyTimes->Resize(WND_BTHMAIN_FREQUEBCY_TIMES_W, WND_BTHMAIN_FREQUEBCY_TIMES_H); + frequencyTimes->SetText("分"); + frequencyTimes->SetTextColor(Color::White()); + frequencyTimes->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + frequencyTimes->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + frequencyTimes->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(frequencyTimes); + + if (heartRateTimes == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new HeartRate_Times ERROR"); + heartRateTimes = new UILabel(); + } + heartRateTimes->SetPosition(WND_BTHMAIN_HEARTRATE_TIMES_X, WND_BTHMAIN_HEARTRATE_TIMES_Y); + heartRateTimes->Resize(WND_BTHMAIN_HEARTRATE_TIMES_W, WND_BTHMAIN_HEARTRATE_TIMES_H); + heartRateTimes->SetText("次/分"); + heartRateTimes->SetTextColor(Color::White()); + heartRateTimes->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + heartRateTimes->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + heartRateTimes->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(heartRateTimes); + + if (trainingDuration == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new trainingDuration ERROR"); + trainingDuration = new UILabel(); + } + trainingDuration->SetPosition(WND_BTHMAIN_DURATION_X, WND_BTHMAIN_DURATION_Y); + trainingDuration->Resize(WND_BTHMAIN_DURATION_W, WND_BTHMAIN_DURATION_H); + trainingDuration->SetText("训练时长"); + trainingDuration->SetTextColor(Color::White()); + trainingDuration->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + trainingDuration->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + trainingDuration->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(trainingDuration); + + if (frequenciesScout == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new Frequencies_scout ERROR"); + frequenciesScout = new UILabel(); + } + frequenciesScout->SetPosition(WND_BTHMAIN_FREQUENCIES_SCOUT_X, WND_BTHMAIN_FREQUENCIES_SCOUT_Y); + frequenciesScout->Resize(WND_BTHMAIN_FREQUENCIES_SCOUT_W, WND_BTHMAIN_FREQUENCIES_SCOUT_H); + frequenciesScout->SetTextColor(Color::White()); + frequenciesScout->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_SCOUT_FONT_SIZE); + frequenciesScout->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(frequenciesScout); + + if (heartRateScout == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new HeartRate_scout ERROR"); + heartRateScout = new UILabel(); + } + heartRateScout->SetPosition(WND_BTHMAIN_HEARTRATE_SCOUT_X, WND_BTHMAIN_HEARTRATE_SCOUT_Y); + heartRateScout->Resize(WND_BTHMAIN_HEARTRATE_SCOUT_W, WND_BTHMAIN_HEARTRATE_SCOUT_H); + heartRateScout->SetTextColor(Color::White()); + heartRateScout->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_SCOUT_FONT_SIZE); + heartRateScout->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(heartRateScout); + + if (descriptionBreathing == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new Rhythm ERROR"); + descriptionBreathing = new UILabel(); + } + descriptionBreathing->SetPosition(WND_BTHMAIN_RHYTHM_X, WND_BTHMAIN_RHYTHM_Y); + descriptionBreathing->Resize(WND_BTHMAIN_RHYTHM_W, WND_BTHMAIN_RHYTHM_H); + descriptionBreathing->SetTextColor(Color::Green()); + descriptionBreathing->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + descriptionBreathing->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(descriptionBreathing); + + if (time == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new Time ERROR"); + time = new UILabel(); + } + time->SetPosition(WND_BTHMAIN_TIME_X, WND_BTHMAIN_TIME_Y); + time->Resize(WND_BTHMAIN_TIME_W, WND_BTHMAIN_TIME_H); + time->SetTextColor(Color::White()); + time->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_SCOUT_FONT_SIZE); + time->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(time); + + if (timeUnit == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new Time_Unit ERROR"); + timeUnit = new UILabel(); + } + timeUnit->SetPosition(WND_BTHMAIN_TIME_UNIT_X, WND_BTHMAIN_TIME_UNIT_Y); + timeUnit->Resize(WND_BTHMAIN_TIME_UNIT_W, WND_BTHMAIN_TIME_UNIT_H); + timeUnit->SetText("分钟"); + timeUnit->SetTextColor(Color::White()); + timeUnit->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHMAIN_MIN_FONT_SIZE); + timeUnit->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + timeUnit->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(timeUnit); + + if (scores == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnStart new Scores ERROR"); + scores = new UIImageView(); + } + scores->SetPosition(WND_BTHMAIN_SCORES_X, WND_BTHMAIN_SCORES_Y); + scores->Resize(WND_BTHMAIN_SCORES_W, WND_BTHMAIN_SCORES_H); + group->Add(scores); + + AddViewToPageContainer(group); +} +void BreathResultPage::OnStop() {} +void BreathResultPage::OnResume(void) +{ + std::ostringstream oss; + oss << BreathModel::GetInstance().GetTimeDuration() << " | " << BreathModel::GetInstance().GetRhythm(); + std::string weatherHumidity = oss.str(); + descriptionBreathing->SetText(weatherHumidity.c_str()); + time->SetText(BreathModel::GetInstance().GetDuration()); + + BreathModel::GetInstance().SetFrequencyScore(); + BreathModel::GetInstance().SetHeartRate(); + + frequencyScore = BreathModel::GetInstance().GetFrequencyScore(); + char szFrequencyScore[TEXT_SIZE] = ""; + sprintf_s(szFrequencyScore, sizeof(szFrequencyScore), "%d", frequencyScore); + frequenciesScout->SetText(szFrequencyScore); + + if (frequencyScore >= BREATH_NINETY_SIZE && frequencyScore <= BREATH_GUINEAS_SIZE) { + LOADIMG::LoadImageViewImg(scores, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH008); + } else if (frequencyScore >= BREATH_EIGHTY_SIZE && frequencyScore <= BREATH_EIGHTY_NINE_SIZE) { + LOADIMG::LoadImageViewImg(scores, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH007); + } else if (frequencyScore >= BREATH_SEVENTY_SIZE && frequencyScore <= BREATH_SEVENTY_NINE_SIZE) { + LOADIMG::LoadImageViewImg(scores, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH011); + } else if (frequencyScore >= BREATH_SIXTY_SIZE && frequencyScore <= BREATH_SIXTY_NINE_SIZE) { + LOADIMG::LoadImageViewImg(scores, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH009); + } else { + LOADIMG::LoadImageViewImg(scores, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH010); + } + + heartRate = BreathModel::GetInstance().GetHeartRate(); + char szHeartRate[TEXT_SIZE] = ""; + sprintf_s(szHeartRate, sizeof(szHeartRate), "%d", heartRate); + heartRateScout->SetText(szHeartRate); +} + +bool BreathResultPage::OnClick(UIView &view, const ClickEvent &event) +{ + return true; +} + +bool BreathResultPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathResultPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathRhyPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathRhyPage.cpp new file mode 100644 index 000000000..1265c9912 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathRhyPage.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathRhyPage + * Create: 2025-5-13 + */ +#include "gfx_utils/graphic_math.h" +#include "UiConfig.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "alarm/MainAlarmView.h" +#include "SlicePageFactory.h" +#include "ui_resource_breath.h" +#include "main/LoadImg.h" +#include "breath/BreathView.h" +#include "breath/BreathModel.h" +#include "breath/BreathRhyPage.h" + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_MAIN_BREATHEASE, BrearhView::BREATH_RHY_VIEW, BreathRhyPage, false); +#define WND_BTHRHY_BTN_OK_ID "BTH_RHY_OK" +#define WND_BTHRHY_TITLE_X 100 +#define WND_BTHRHY_TITLE_Y 38 +#define WND_BTHRHY_TITLE_W 253 +#define WND_BTHRHY_TITLE_H 53 +#define WND_BTHRHY_TITLE_FONT_SIZE 38 +#define WND_BTHRHY_PICKER_X 64 +#define WND_BTHRHY_PICKER_Y 109 +#define WND_BTHRHY_PICKER_W 321 +#define WND_BTHRHY_PICKER_H 218 +#define WND_BTHRHY_PICKER_B_FONT_SIZE 44 +#define WND_BTHRHY_PICKER_H_FONT_SIZE 44 +#define WND_BTHRHY_PICKER_ITEM_H 80 +#define WND_BTHRHY_OK_X 61 +#define WND_BTHRHY_OK_Y 362 +#define WND_BTHRHY_OK_W 331 +#define WND_BTHRHY_OK_H 98 +#define BREATH_GROUP_SIZE 466 + +BreathRhyPage::BreathRhyPage() {} + +BreathRhyPage::~BreathRhyPage() +{ + group->RemoveAll(); + if (lableRhythm != nullptr) { + delete lableRhythm; + lableRhythm = nullptr; + } + if (pickerRhythm != nullptr) { + delete pickerRhythm; + pickerRhythm = nullptr; + } + if (buttonOk != nullptr) { + delete buttonOk; + buttonOk = nullptr; + } + if (group != nullptr) { + delete group; + group = nullptr; + } + if (center != nullptr) { + delete center; + center = nullptr; + } +} + +void BreathRhyPage::OnStart(void *data) +{ + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnStart new group ERROR"); + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetTouchable(false); + group->SetDraggable(false); + + if (lableRhythm == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnStart new lableRhythm ERROR"); + lableRhythm = new UILabel(); + } + lableRhythm->SetPosition(WND_BTHRHY_TITLE_X, WND_BTHRHY_TITLE_Y); + lableRhythm->Resize(WND_BTHRHY_TITLE_W, WND_BTHRHY_TITLE_H); + lableRhythm->SetText("节奏设置"); + lableRhythm->SetTextColor(Color::White()); + lableRhythm->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + lableRhythm->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHRHY_TITLE_FONT_SIZE); + group->Add(lableRhythm); + + if (pickerRhythm == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnStart new pickerRhythm ERROR"); + pickerRhythm = new UIPicker(); + } + pickerRhythm->SetPosition(WND_BTHRHY_PICKER_X, WND_BTHRHY_PICKER_Y); + pickerRhythm->Resize(WND_BTHRHY_PICKER_W, WND_BTHRHY_PICKER_H); + pickerRhythm->SetBackgroundFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHRHY_PICKER_B_FONT_SIZE); + pickerRhythm->SetHighlightFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHRHY_PICKER_H_FONT_SIZE); + pickerRhythm->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + pickerRhythm->SetItemHeight(WND_BTHRHY_PICKER_ITEM_H); + pickerRhythm->SetTextColor(Color::GetColorFromRGBA(0xfa, 0xf3, 0xf3, 0xff), + Color::GetColorFromRGBA(0xfa, 0xf3, 0xf3, 0xff)); + uint8_t selectTempo = BreathModel::GetInstance().GetSelectTempo(); + pickerRhythm->SetSelected(selectTempo); + pickerRhythm->RegisterSelectedListener(this); + pickerRhythm->SetVisible(true); + pickerRhythm->SetOnDragListener(this); + pickerRhythm->SetLoopState(false); + group->Add(pickerRhythm); + + if (center == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnStart new Center ERROR"); + center = new UIImageView(); + } + center->SetPosition(WND_BTHRHY_PICKER_X, WND_BTHRHY_PICKER_Y); + center->Resize(WND_BTHRHY_PICKER_W, WND_BTHRHY_PICKER_H); + LOADIMG::LoadImageViewImg(center, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH013); + group->Add(center); + + if (buttonOk == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnStart new buttonOk ERROR"); + buttonOk = new UIButton(); + } + buttonOk->SetPosition(WND_BTHRHY_OK_X, WND_BTHRHY_OK_Y); + buttonOk->Resize(WND_BTHRHY_OK_W, WND_BTHRHY_OK_H); + buttonOk->SetViewId(WND_BTHRHY_BTN_OK_ID); + buttonOk->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + LOADIMG::LoadBtnImage(buttonOk, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH005, IMAGE_CONVERTER_TOOL_BREATH005); + buttonOk->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + buttonOk->SetOnClickListener(this); + group->Add(buttonOk); + + AddViewToPageContainer(group); +} +void BreathRhyPage::OnResume() +{ + pickerRhythm->SetValues(BreathModel::GetInstance().GetRhyListData(), BreathModel::GetInstance().GetRhyListSize()); + GetSlicePageContainer()->SetIntercept(true); + GetSlicePageContainer()->SetOnDragListener(nullptr); +} + +void BreathRhyPage::OnPause() {} + +void BreathRhyPage::OnStop() {} + +bool BreathRhyPage::OnClick(UIView &view, const ClickEvent &event) +{ + if (strcmp(view.GetViewId(), WND_BTHRHY_BTN_OK_ID) == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathRhyPage OnClick...ChangeTo DUR"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + BreathModel::GetInstance().SetTimeRhyation(pickerRhythm->GetSelected()); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathRhyPage OnClick...ChangeTo unknow"); + return false; + } + return true; +} + +bool BreathRhyPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathRhyPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathStartPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathStartPage.cpp new file mode 100644 index 000000000..6545ac442 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/breath/src/BreathStartPage.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathStartPage + * Create: 2025-5-13 + */ +#include +#include +#include +#include "gfx_utils/graphic_math.h" +#include "components/root_view.h" +#include "UiConfig.h" +#include "ohos_timer.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "TransitionType.h" +#include "SlicePageFactory.h" +#include "PageTransitionMgr.h" +#include "ui_resource_breath.h" +#include "main/LoadImg.h" +#include "breath/BreathView.h" +#include "breath/BreathModel.h" +#include "breath/BreathStartPage.h" + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_MAIN_BREATHEASE, BrearhView::BREATH_START_VIEW, BreathStartPage, false); + +#define WND_BTHSTART_TITLE_X 97 +#define WND_BTHSTART_TITLE_Y 40 +#define WND_BTHSTART_TITLE_W 260 +#define WND_BTHSTART_TITLE_H 53 +#define WND_BTHSTART_TITLE_FONT_SIZE 36 +#define WND_BTHSTART_CENTERIMG_X 88 +#define WND_BTHSTART_CENTERIMG_Y 88 +#define WND_BTHSTART_CENTERIMG_W 279 +#define WND_BTHSTART_CENTERIMG_H 280 +#define WND_BTHSTART_GUIDE_X 126 +#define WND_BTHSTART_GUIDE_Y 354 +#define WND_BTHSTART_GUIDE_W 202 +#define WND_BTHSTART_GUIDE_H 68 +#define WND_BTHSTART_GUIDE_FONT_SIZE 24 +#define BREATH_GROUP_SIZE 466 +#define TEXT_OPACITY 147 +#define countDown 5 +#define SIZE 64 + +BreathStartPage::BreathStartPage() {} + +BreathStartPage::~BreathStartPage() +{ + group->RemoveAll(); + if (titleLable != nullptr) { + delete titleLable; + titleLable = nullptr; + } + if (guideLable != nullptr) { + delete guideLable; + guideLable = nullptr; + } + if (centerImge != nullptr) { + delete centerImge; + centerImge = nullptr; + } + if (group != nullptr) { + delete group; + group = nullptr; + } + if (background != nullptr) { + delete background; + background = nullptr; + } + if (animation != nullptr) { + delete animation; + animation = nullptr; + } + if (animatorCallBack != nullptr) { + delete animatorCallBack; + animatorCallBack = nullptr; + } +} + +void BreathStartPage::OnStart(void *data) +{ + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new group ERROR"); + group = new UIViewGroup(); + } + group->SetPosition(0, 0); + group->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetTouchable(true); + group->SetDraggable(true); + group->SetOnDragListener(this); + + if (background == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new background ERROR"); + background = new UIImageView(); + } + background->SetPosition(0, 0); + background->Resize(BREATH_GROUP_SIZE, BREATH_GROUP_SIZE); + LOADIMG::LoadImageViewImg(background, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH001); + group->Add(background); + + if (titleLable == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new titleLable ERROR"); + titleLable = new UILabel(); + } + titleLable->SetPosition(WND_BTHSTART_TITLE_X, WND_BTHSTART_TITLE_Y); + titleLable->Resize(WND_BTHSTART_TITLE_W, WND_BTHSTART_TITLE_H); + titleLable->SetText("请保持静止"); + titleLable->SetTextColor(Color::White()); + titleLable->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + titleLable->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHSTART_TITLE_FONT_SIZE); + group->Add(titleLable); + + if (centerImge == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new centerImg ERROR"); + centerImge = new UIImageView(); + } + centerImge->SetPosition(WND_BTHSTART_CENTERIMG_X, WND_BTHSTART_CENTERIMG_Y); + centerImge->Resize(WND_BTHSTART_CENTERIMG_W, WND_BTHSTART_CENTERIMG_H); + LOADIMG::LoadImageViewImg(centerImge, BREATH_IMAGE, IMAGE_CONVERTER_TOOL_BREATH003); + group->Add(centerImge); + + if (guideLable == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new guideLable ERROR"); + guideLable = new UILabel(); + } + guideLable->SetPosition(WND_BTHSTART_GUIDE_X, WND_BTHSTART_GUIDE_Y); + guideLable->Resize(WND_BTHSTART_GUIDE_W, WND_BTHSTART_GUIDE_H); + guideLable->SetTextColor(Color::White()); + guideLable->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + guideLable->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WND_BTHSTART_GUIDE_FONT_SIZE); + guideLable->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + guideLable->SetStyle(STYLE_TEXT_OPA, TEXT_OPACITY); + group->Add(guideLable); + + animatorCallBack = new BreathStartCallback(this); + if (animatorCallBack == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new animatorCallBack ERROR"); + return; + } + animation = new Animator(animatorCallBack, nullptr, 0, true); + if (animation == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnStart new animation ERROR"); + return; + } + animation->Start(); + AddViewToPageContainer(group); +} + +void BreathStartPage::OnStop() {} + +void BreathStartPage::BreathStartCallback::Callback(UIView *view) +{ + UNUSED(view); + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + int32_t overTime = countDown; + int32_t start_time = BreathModel::GetInstance().GetSaveTime(); + int32_t remTime = overTime - (current_time.tv_sec - start_time); + + char szText[SIZE] = ""; + sprintf_s(szText, sizeof(szText), "%d秒后跟随训练指引开始吸气和呼气", remTime); + BreathStartPage->guideLable->SetText(szText); + if (remTime <= 0) { + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_EXER_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + BreathStartPage->animation->Stop(); + struct timeval start_breathing_time; + gettimeofday(&start_breathing_time, nullptr); + uint32_t breathing_time = start_breathing_time.tv_sec; + BreathModel::GetInstance().SetBeginsTime(breathing_time); + } +} + +void BreathStartPage::OnPause() +{ + animation->Stop(); +} + +bool BreathStartPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BreathStartPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().SwitchPageInSlice(BREATH_MAIN_VIEW, nullptr, TransitionType::TRANSITION_INVALID, + true); + } + return true; +} + +void BreathStartPage::OnTimer() {} + +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerItemView.cpp index c63f1851c..70b62303c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerItemView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerItemView.cpp @@ -5,9 +5,12 @@ * Create: 2021-10-12 */ -#include "CallerItemView.h" -#include "CallerLogPresenter.h" +#include "callerlog/CallerItemView.h" +#include "sys/time.h" #include "wearable_log.h" +#ifdef BUILD_IN_LINUX +#include "localtime.h" +#endif namespace OHOS { static constexpr int16 ICON_X = 100; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogModel.cpp index 5e9e96d73..11d24831b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogModel.cpp @@ -4,15 +4,15 @@ * Author: * Create: 2021-10-12 */ -#include "CallerLogModel.h" -#include "CallerLogView.h" -#include "DialingScreenView.h" -#include "CallingView.h" +#include "callerlog/CallerLogModel.h" +#include "callerlog/CallerLogView.h" +#include "makephone/DialingScreenView.h" +#include "makephone/CallingView.h" #include "ohos_timer.h" #include "graphic_timer.h" #include "samgr_lite.h" -#include "MainCallingPresenter.h" -#include "PlayersModel.h" +#include "makephone/MainCallingPresenter.h" +#include "player/PlayersModel.h" #include "graphic_service.h" #ifdef __cplusplus diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogPresenter.cpp index 6c87b1fa7..398f25152 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogPresenter.cpp @@ -5,11 +5,11 @@ * Create: 2021-10-12 */ -#include "CallerLogPresenter.h" -#include "CallerLogView.h" +#include "callerlog/CallerLogPresenter.h" +#include "callerlog/CallerLogView.h" #include "common/task_manager.h" #include "wearable_log.h" -#include "PhoneService.h" +#include "phoneservice/PhoneService.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogView.cpp index 5edabaa18..a9d012a1c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/callerlog/src/CallerLogView.cpp @@ -5,9 +5,9 @@ * Create: 2021-10-12 */ -#include "CallerLogView.h" -#include "CallerLogPresenter.h" -#include "CallerLogModel.h" +#include "callerlog/CallerLogView.h" +#include "callerlog/CallerLogPresenter.h" +#include "callerlog/CallerLogModel.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraMainPage.cpp new file mode 100644 index 000000000..6aca1160c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraMainPage.cpp @@ -0,0 +1,376 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraMainPage + * Created: 2025-06-05 + */ + +#include +#include "ui_test_group.h" +#include "phoneservice/PhoneService.h" +#include "uiservice/ui_service.h" +#include "common/image_cache_manager.h" +#include "main/LoadImg.h" +#include "msg_center_device.h" +#include "bts_spp.h" +#include "ui_resource_camera.h" +#include "camera/CameraView.h" +#include "camera/CameraMainPage.h" +#include "camera/CameraPresenter.h" + +namespace OHOS { +static CameraMainPage *g_pCameraMainPage = nullptr; + +static constexpr uint16_t BLUETOOTH_XPOS = 158; +static constexpr uint16_t BLUETOOTH_XPOY = 154; +static constexpr uint16_t TITLE_XPOS = 15; +static constexpr uint16_t TITLE_XPOY = 329; +static constexpr uint16_t TITLE_WIDTH = 424; +static constexpr uint16_t TITLE_HIGHT = 50; +static constexpr uint16_t TITLE_FONT_SIZE = 36; +static constexpr uint16_t CAMERATITLE_FONT_SIZE = 38; +static constexpr uint16_t CAMERATITLE_XPOS = 97; +static constexpr uint16_t CAMERATITLE_XPOY = 37; +static constexpr uint16_t CAMERATITLE_WIDTH = 260; +static constexpr uint16_t CAMERATITLE_HIGHT = 53; +static constexpr uint16_t CAMERAFIND_XPOS = 123; +static constexpr uint16_t CAMERAFIND_XPOY = 200; +static constexpr uint16_t CAMERAFIND_WIDTH = 250; +static constexpr uint16_t CAMERAFIND_HIGHT = 42; +static constexpr uint16_t CAMERATIME_XPOS = 200; +static constexpr uint16_t BUTTON_WIDTH = 171; +static constexpr uint16_t BUTTON_HIGHT = 171; +static constexpr uint16_t COUNTDOWN_TIME = 5; +static constexpr uint16_t CAMERA_SIZE = 466; +static constexpr uint16_t CAMERA_BUTTON_POSITION_X = 144; +static constexpr uint16_t CAMERA_BUTTON_POSITION_Y = 154; +static constexpr uint16_t TIME_FONT_SIZE = 50; +static constexpr uint16_t CAMERATIME_HIGHT = 55; +static constexpr uint16_t ERROR_NUM = 2; + +REGIST_SLICE_PAGE(VIEW_CAMERA, CAMERA_PAGES::CAMERA_MAIN_PAGE, CameraMainPage, true); + +CameraMainPage::CameraMainPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CameraMainPage::CameraMainPage"); + ImageCacheManager::GetInstance().LoadAllInMultiRes(CAMERA_IMAGE); + g_pCameraMainPage = this; +} + +CameraMainPage::~CameraMainPage() +{ + g_pCameraMainPage = nullptr; + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (bluetoothDisconnected != nullptr) { + delete bluetoothDisconnected; + bluetoothDisconnected = nullptr; + } + + if (cameraFind != nullptr) { + delete cameraFind; + cameraFind = nullptr; + } + + if (cameraTitle != nullptr) { + delete cameraTitle; + cameraTitle = nullptr; + } + + if (cameraTime != nullptr) { + delete cameraTime; + cameraTime = nullptr; + } + + if (button != nullptr) { + delete button; + button = nullptr; + } + + if (animator_ != nullptr) { + delete animator_; + animator_ = nullptr; + } + + if (callBack_ != nullptr) { + delete callBack_; + callBack_ = nullptr; + } + ImageCacheManager::GetInstance().UnloadAllInMultiRes(CAMERA_IMAGE); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CameraMainPage::~CameraMainPage"); +} + +CameraMainPage *CameraMainPage::GetInstance() +{ + return g_pCameraMainPage; +} + +void CameraMainPage::OnStart(void *data) +{ + if (container_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CameraMainPage::new container fail"); + container_ = new UIScrollView(); + container_->SetPosition(0, 0, CAMERA_SIZE, CAMERA_SIZE); + container_->SetStyle(STYLE_BACKGROUND_OPA, 0); + } + container_->SetTouchable(true); + container_->SetDraggable(true); + container_->SetOnDragListener(this); + + bluetoothDisconnected = new UIImageView(); + if (bluetoothDisconnected == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "bluetoothDisconnected is nullptr"); + return; + } + LOADIMG::LoadImageViewImg(bluetoothDisconnected, CAMERA_IMAGE, IMAGE_CONVERTER_TOOL_CAMERA_2); + bluetoothDisconnected->SetPosition(BLUETOOTH_XPOS, BLUETOOTH_XPOY); + bluetoothDisconnected->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + bluetoothDisconnected->SetVisible(false); + container_->Add(bluetoothDisconnected); + + title = new UILabel(); + if (title == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "title is nullptr"); + return; + } + title->SetText("蓝牙已断开"); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TITLE_FONT_SIZE); + title->SetPosition(TITLE_XPOS, TITLE_XPOY, TITLE_WIDTH, TITLE_HIGHT); + title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + title->SetVisible(false); + container_->Add(title); + + cameraTitle = new UILabel(); + if (cameraTitle == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cameraTitle is nullptr"); + return; + } + cameraTitle->SetText("相机"); + cameraTitle->SetFont(DEFAULT_VECTOR_FONT_FILENAME, CAMERATITLE_FONT_SIZE); + cameraTitle->SetPosition(CAMERATITLE_XPOS, CAMERATITLE_XPOY, CAMERATITLE_WIDTH, CAMERATITLE_HIGHT); + cameraTitle->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + cameraTitle->SetVisible(false); + container_->Add(cameraTitle); + + cameraFind = new UILabel(); + if (cameraFind == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cameraFind is nullptr"); + return; + } + cameraFind->SetText("正在连接手机..."); + cameraFind->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TITLE_FONT_SIZE); + cameraFind->SetPosition(CAMERAFIND_XPOS, CAMERAFIND_XPOY, CAMERAFIND_WIDTH, CAMERAFIND_HIGHT); + cameraFind->SetVisible(false); + container_->Add(cameraFind); + + cameraTime = new UILabel(); + if (cameraTime == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cameraTime is nullptr"); + return; + } + cameraTime->SetText("5s"); + cameraTime->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIME_FONT_SIZE); + cameraTime->SetPosition(CAMERATIME_XPOS, CAMERAFIND_XPOY, CAMERAFIND_WIDTH, CAMERATIME_HIGHT); + cameraTime->SetVisible(false); + container_->Add(cameraTime); + SetUpButton(); + callBack_ = new CameraAnimatorCallback(this); + animator_ = new Animator(callBack_, nullptr, 0, true); + + AddViewToPageContainer(container_); + InitCameraView(); +} + +uint8_t CameraMainPage::GetConnectStatus() +{ + uint8_t conn_status = 0; + +#ifdef _WIN32 + conn_status = 1; +#else + if (msg_center_get_trans_channel() == DIAG_FRAME_FID_PHONE) { + conn_status = is_spp_connected(0) == true ? 1 : 0; + } else if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) { + conn_status = msg_center_get_ble_conn_state(); + } +#endif + return conn_status; +} + +void CameraMainPage::InitCameraView() +{ + if (GetConnectStatus() == 1) { + cameraTitle->SetVisible(true); + cameraFind->SetVisible(true); + title->SetVisible(false); + bluetoothDisconnected->SetVisible(false); + cameraTime->SetVisible(false); + button->SetVisible(false); + button->SetTouchable(false); + container_->Invalidate(); + uint8_t value = 1; + errcode_t ret; +#ifdef _WIN32 + ret = 0; +#else + ret = msg_center_send_data(MSGCENTER_CMD_DEVICE, + MSGCENTER_TYPE_ID_CAMERA_CONNECT_PHONE, &value, sizeof(value)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MSGCENTER_TYPE_ID_CAMERA_CONNECT_PHONE ret = %d", ret); +#endif + } else { + title->SetVisible(true); + bluetoothDisconnected->SetVisible(true); + cameraTitle->SetVisible(false); + cameraFind->SetVisible(false); + cameraTime->SetVisible(false); + button->SetVisible(false); + button->SetTouchable(false); + container_->Invalidate(); + } +} + +void CameraMainPage::Refresh_page() +{ + cameraTitle->SetVisible(true); + button->SetVisible(true); + button->SetTouchable(true); + cameraFind->SetVisible(false); + title->SetVisible(false); + bluetoothDisconnected->SetVisible(false); + cameraTime->SetVisible(false); + container_->Invalidate(); +} + +void CameraMainPage::SetUpButton() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CameraMainPage::SetupButton new Label"); + if (button == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "button is nullptr"); + button = new UILabelButton(); + } + + button->SetPosition(CAMERA_BUTTON_POSITION_X, CAMERA_BUTTON_POSITION_Y); + button->Resize(BUTTON_WIDTH, BUTTON_HIGHT); + button->SetViewId("button1"); + button->SetOnClickListener(this); + button->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + button->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + button->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::RELEASED); + button->SetVisible(false); + button->SetTouchable(false); + LOADIMG::LoadBtnImage(button, CAMERA_IMAGE, IMAGE_CONVERTER_TOOL_CAMERA_1, IMAGE_CONVERTER_TOOL_CAMERA_1); + container_->Add(button); +} + +void CameraMainPage::OnPause() +{ + animator_->Stop(); +} + +bool CameraMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + if (view.GetViewId() == "button1") { + if (GetConnectStatus() == 1) { + button->SetVisible(false); + cameraTime->SetVisible(true); + SetFirstFlag(true); + animator_->Start(); + } else { + title->SetVisible(true); + bluetoothDisconnected->SetVisible(true); + cameraTitle->SetVisible(false); + cameraFind->SetVisible(false); + cameraTime->SetVisible(false); + button->SetVisible(false); + button->SetTouchable(false); + container_->Invalidate(); + } + } + return true; +} + +bool CameraMainPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CameraPresenter::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CameraOnDragListener::OnDrag ChangeSlice(VIEW_APPLIST)"); + uint8_t value = 1; + errcode_t ret; +#ifdef _WIN32 + ret = 0; +#else + ret = msg_center_send_data(MSGCENTER_CMD_DEVICE, + MSGCENTER_TYPE_ID_CAMERA_PHONE_EXIT, &value, sizeof(value)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MSGCENTER_TYPE_ID_CAMERA_PHONE_EXIT ret = %d", ret); +#endif + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + return true; +} + +void CameraMainPage::CameraAnimatorCallback::Callback(UIView *view) +{ + (void)view; + static int count = 0; + static struct timeval start_time; + struct timeval current_time; + if (page_->GetFirstFlag()) { + gettimeofday(&start_time, nullptr); + page_->SetFirstFlag(false); + } + gettimeofday(¤t_time, nullptr); + int time = current_time.tv_sec - start_time.tv_sec; + std::string strTime1 = std::to_string(COUNTDOWN_TIME - time) + "s"; + page_->SetCameraTime(time); + if (time == COUNTDOWN_TIME) { + page_->StopAnimator(); + } +} + +void CameraMainPage::StopAnimator() +{ + animator_->Stop(); + button->SetVisible(true); + cameraTime->SetVisible(false); + cameraTime->SetText("5s"); + SetFirstFlag(false); + uint8_t value = 1; + errcode_t ret; +#ifdef _WIN32 + ret = 0; +#else + ret = msg_center_send_data(MSGCENTER_CMD_DEVICE, + MSGCENTER_TYPE_ID_ON_CAMERA, &value, sizeof(value)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MSGCENTER_TYPE_ID_ON_CAMERA ret = %d", ret); +#endif +} + +void CameraMainPage::SetCameraTime(int time) +{ + int progressTime = COUNTDOWN_TIME - time; + int progressValue = 0; + std::string strTime = std::to_string(COUNTDOWN_TIME - time) + "s"; + cameraTime->SetText(strTime.c_str()); +} + +bool CameraMainPage::GetFirstFlag() +{ + return isFirst; +} + +void CameraMainPage::SetFirstFlag(bool value) +{ + isFirst = value; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraModel.cpp new file mode 100644 index 000000000..669c55b3d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraModel.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraModel + * Created: 2025-06-05 + */ + +#include +#include "ohos_timer.h" +#include "wearable_log.h" +#include "camera/CameraModel.h" +#include "camera/CameraView.h" + +namespace OHOS { + +CameraModel::CameraModel() {} + +CameraModel::~CameraModel() {} + +CameraModel &CameraModel::GetInstance() +{ + static CameraModel instance; + return instance; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraPresenter.cpp new file mode 100644 index 000000000..4d94013c8 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/camera/src/CameraPresenter.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraPresenter + * Created: 2025-06-05 + */ + +#include "uiservice/ui_service.h" +#include "NativeRegisterManager.h" +#include "camera/CameraView.h" +#include "camera/CameraModel.h" +#include "camera/CameraPresenter.h" + +namespace OHOS { +REGIST_MENU(VIEW_CAMERA, CameraView, CameraPresenter, CAMERA_MAIN_ICON, PNG_APPLIST_SETTING_IMAGE, "相机"); +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/clock/src/AmbientClockView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/clock/src/AmbientClockView.cpp index 7bc705a74..c0e50762d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/clock/src/AmbientClockView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/clock/src/AmbientClockView.cpp @@ -5,14 +5,18 @@ * Create: 2024-10-30 */ -#include "AmbientClockView.h" -#include "MainPresenterSample.h" +#include "clock/AmbientClockView.h" +#include "main/MainPresenterSample.h" #include "components/ui_label.h" #include "wearable_log.h" #include "ui_resource_image.h" #include "common/image_cache_manager.h" +#include "UICardPageFactory.h" namespace OHOS { + +REGIST_WATCH_DIAL(DIAL_DISPLAY_MODE_AOD, DIAL_CLOCK, AmbientClockView); + static constexpr uint16_t POINT_POSITION_X = 202; static constexpr uint16_t POINT_POSITION_Y = 16; static constexpr uint16_t SECOND_POINT_POSITION_Y = 16; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/clock/src/MainClockView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/clock/src/MainClockView.cpp index 9beeb512f..1fdfcf4da 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/clock/src/MainClockView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/clock/src/MainClockView.cpp @@ -5,15 +5,19 @@ * Create: 2021-08-14 */ -#include "MainClockView.h" -#include "MainPresenterSample.h" +#include "clock/MainClockView.h" +#include "main/MainPresenterSample.h" #include "components/ui_label.h" #include "wearable_log.h" #include "ui_resource_image.h" #include "common/image_cache_manager.h" +#include "UICardPageFactory.h" #include namespace OHOS { + +REGIST_WATCH_DIAL(DIAL_DISPLAY_MODE_MAIN, DIAL_CLOCK, MainClockView); + static MainClockView *g_pMainClockView = nullptr; static constexpr uint16_t FONT_DEFAULT_SIZE = 25; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassCalibrationView.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassCalibrationView.h deleted file mode 100644 index 704e60d96..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassCalibrationView.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. - * Description: CompassCalibrationView.h - * Author: - * Create: 2022-04-02 - */ - -#ifndef COMPASS_CALIBRATION_VIEW_H -#define COMPASS_CALIBRATION_VIEW_H - -#include "components/ui_label.h" -#include "View.h" -#include "ohos_types.h" -#include "AppGroupView.h" -#include "components/ui_image_view.h" - -namespace OHOS { -class CompassCalibrationView : public AppGroupView { -public: - CompassCalibrationView(); - ~CompassCalibrationView() override; - - bool CreateUIViewGroup(void); - static CompassCalibrationView *GetInstance(void); - bool InitView(void *caller) override; -private: - UILabel *labelOne{nullptr}; - UILabel *labelTwo{nullptr}; - UIImageView *imageView{nullptr}; - - void ClearAll(void); -}; -} -#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassControlView.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassControlView.h deleted file mode 100644 index 3dc43f20f..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassControlView.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. - * Description: CompassControlView.h - * Author: - * Create: 2022-04-02 - */ - -#ifndef COMPASS_CONTROL_VIEW_H -#define COMPASS_CONTROL_VIEW_H - -#include "components/root_view.h" -#include "UiConfig.h" -#include "components/ui_card_page.h" -#include "CompassCalibrationView.h" -#include "CompassView.h" - -namespace OHOS { - -class CompassControlView : public UICardPage { -public: - CompassControlView(); - ~CompassControlView() override; - bool InitView(void); - void PreLoad(void) override; - void UnLoad(void) override; - void SetCalibrationView(bool flag); -private: - CompassCalibrationView *compassCalibrationView{nullptr}; - CompassView *compassView{nullptr}; - bool viewiInitStatus{false}; - bool isCalibration{false}; - - void ClearAll(void); -}; -} -#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassModel.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassModel.h deleted file mode 100644 index 80cfd2f6a..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassModel.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. - * Description: CompassModel.h - * Author: - * Create: 2022-04-02 - */ - -#ifndef COMPASS_MODEL_H -#define COMPASS_MODEL_H - -#include - -namespace OHOS { -class CompassModel { -public: - static CompassModel *GetInstance(void); - bool OpenCompassSensor(void); - bool CloseCompassSensor(void); - void SetCalibrationStatus(uint8_t status); - uint8_t GetCalibrationStatus(void); - void SetDisplayAngle(uint16_t angle); - uint16_t GetDisplayAngle(void); -#if defined(_WIN32) -#undef GetCurrentTime -#endif - time_t GetCurrentTime(void); - void SetLastTime(time_t value); - time_t GetLastTime(void); - -private: - uint8_t calibrationStatus{1}; - uint16_t displayAngle{0}; - time_t lastTime{0}; -}; -} - -#endif - diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassPresenter.h deleted file mode 100644 index 68d6877d8..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassPresenter.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: CompassPresenter.h - * Author: - * Create: 2021-12-21 - */ -#ifndef COMPASS_PRESENTER_H -#define COMPASS_PRESENTER_H - -#include "Presenter.h" -#include "components/ui_view.h" -#include "components/ui_image_view.h" -#include "ohos_types.h" -#include "UiConfig.h" -#include "AppViewIDs.h" -#include "CompassView.h" - -namespace OHOS { -typedef struct { - uint16_t beginAngle; - uint16_t endAngle; - const char *dir; -} CompassItem; - -class CompassView; -class CompassPresenter { -public: - CompassPresenter(); - virtual ~CompassPresenter(); - - static CompassPresenter *GetInstance(void); - void DisplayAngleDir(uint16_t angle); - void DetermineToRotate(void); - void InScopeRotate(void); - void TimeCreateRandomNum(void); - void DisplayAngleRight(uint16_t angle); - -private: - int16_t lastRotateAngle{0}; - int16_t currentRotateAngle{0}; - int16_t angleDiff{0}; - bool getAngleStatus{false}; - bool initDisplayStatus{true}; -}; -} -#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassView.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassView.h deleted file mode 100644 index 97cd957d1..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/CompassView.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: CompassView.h - * Author: - * Create: 2021-12-21 - */ - -#ifndef COMPASS_VIEW_H -#define COMPASS_VIEW_H - -#include "View.h" -#include "components/root_view.h" -#include "components/ui_label.h" -#include "components/ui_image_view.h" -#include "ChangeSliceListener.h" -#include "UiConfig.h" -#include "AppGroupView.h" -#include "CompassCalibrationView.h" - -namespace OHOS { -static constexpr float VIEW_CENTERS = 227; - -class CompassView : public AppGroupView { -public: - CompassView(); - ~CompassView() override; - - void DirectionSetText(const char *text, const char *angle); - static CompassView *GetInstance(void); - void CompassStartRotate(int16_t numb); - bool InitPage(void); - bool InitView(void *caller) override; - bool GetInitViewState(void); - bool InitCompassImage(void); - -private: - bool LoadCompassImage(UIImageView *view, uint32_t resId); - void ClearAll(void); - UILabel *directionLabel{nullptr}; - UILabel *angledLabel{nullptr}; - UIImageView *backGround{nullptr}; - UIImageView *rotateShaft{nullptr}; - UIImageView *triangulation{nullptr}; - const Vector2 VIEW_CENTER = {VIEW_CENTERS, VIEW_CENTERS}; -}; -} -#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassPresenter.h deleted file mode 100644 index cd025a41b..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassPresenter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: MainCompassPresenter.h - * Author: - * Create: 2021-12-21 - */ -#ifndef COMPASS_MAINPRESENTER_H -#define COMPASS_MAINPRESENTER_H - -#include "Presenter.h" -#include "ModelListenerSample.h" -#include "ohos_types.h" -#include "UiConfig.h" -#include "AppViewIDs.h" -#include "MainCompassView.h" -#include "CompassPresenter.h" -#include "CompassModel.h" -#include "CompassCalibrationView.h" - -namespace OHOS { -class MainCompassPresenter : public Presenter, public CompassPresenter, - public ModelListenerSample, public UIView::OnDragListener { -public: - MainCompassPresenter(); - ~MainCompassPresenter() override; - - static MainCompassPresenter *GetInstance(void); - bool OnDrag(UIView& view, const DragEvent& event) override; - void Notify() override; -}; -} -#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassView.h b/code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassView.h deleted file mode 100644 index 306496a5a..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/include/MainCompassView.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: MainCompassView - * Author: - * Create: 2021-12-23 - */ - -#ifndef MAIN_COMPASS_VIEW_H -#define MAIN_COMPASS_VIEW_H - -#include -#include "View.h" -#include "components/ui_label.h" -#include "components/root_view.h" -#include "components/ui_view_group.h" -#include "components/ui_image_view.h" -#include "components/ui_label_button.h" -#include "ChangeSliceListener.h" -#include "graphic_config.h" -#include "CompassView.h" -#include "CompassModel.h" -#include "CompassCalibrationView.h" - -namespace OHOS { -class MainCompassPresenter; -class CompassView; -class MainCompassView : public View { -public: - MainCompassView(); - ~MainCompassView() override; - - void OnStart() override; - void OnStop() override; - - static MainCompassView *GetInstance(void); - void SetDisplayTure(void); - void SetDisplayFalse(void); - -private: - CompassView *compassView{nullptr}; - CompassCalibrationView *compassCalibrationView{nullptr}; -}; -} // namespace OHOS -#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassCalibrationView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassCalibrationView.cpp deleted file mode 100644 index 390c0ae82..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassCalibrationView.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. - * Description: CompassCalibrationView.cpp - * Author: - * Create: 2022-04-02 - */ -#include "UiConfig.h" -#include "wearable_log.h" -#include "CompassCalibrationView.h" -#include "CompassModel.h" - -namespace OHOS { -// 标签设置 -static constexpr uint16_t LABEL_POSITION_X = 118; -static constexpr uint16_t LABEL_POSITION_Y = 80; -static constexpr uint16_t LABEL_POSITION_WIDTH = 200; -static constexpr uint16_t LABEL_POSITION_HEIGHT = 50; - -static constexpr uint16_t LABEL_POSITION_X1 = 28; -static constexpr uint16_t LABEL_POSITION_Y1 = 130; -static constexpr uint16_t LABEL_POSITION_WIDTH1 = 400; -static constexpr uint16_t LABEL_POSITION_HEIGHT1 = 50; -static constexpr uint16_t FONT_DEFAULT_SIZE = 35; - -static CompassCalibrationView *g_pMainView = nullptr; -CompassCalibrationView::CompassCalibrationView() -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::CompassCalibrationView"); - SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); - g_pMainView = this; -} - -CompassCalibrationView::~CompassCalibrationView() -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::~CompassCalibrationView"); - ClearAll(); - g_pMainView = nullptr; -} - -void CompassCalibrationView::ClearAll(void) -{ - RemoveAll(); - if (labelOne != nullptr) { - delete labelOne; - labelOne = nullptr; - } - if (imageView != nullptr) { - delete imageView; - imageView = nullptr; - } - if (labelTwo != nullptr) { - delete labelTwo; - labelTwo = nullptr; - } -} - -CompassCalibrationView *CompassCalibrationView::GetInstance(void) -{ - return g_pMainView; -} - -bool CompassCalibrationView::CreateUIViewGroup(void) -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::CreateUIViewGroup"); - imageView = new UIImageView(); - if (imageView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::new UIImageView fail"); - return false; - } - imageView->SetPosition(0, 0); - imageView->SetSrc(COMPASS_CALIBRATE_IMAGE); - - labelOne = new UILabel(); - if (labelOne == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::new labelOne fail"); - ClearAll(); - return false; - } - - labelOne->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_POSITION_WIDTH, LABEL_POSITION_HEIGHT); - labelOne->SetText("请按图示"); - labelOne->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); - labelOne->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - labelOne->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); - labelOne->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); - labelOne->SetStyle(STYLE_TEXT_COLOR, Color::White().full); - - labelTwo = new UILabel(); - if (labelTwo == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::new labelTwo fail"); - ClearAll(); - return false; - } - - labelTwo->SetPosition(LABEL_POSITION_X1, LABEL_POSITION_Y1, LABEL_POSITION_WIDTH1, LABEL_POSITION_HEIGHT1); - labelTwo->SetText("旋转手表进行校准"); - labelTwo->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); - labelTwo->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - labelTwo->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); - labelTwo->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); - labelTwo->SetStyle(STYLE_TEXT_COLOR, Color::White().full); - - Add(imageView); - Add(labelOne); - Add(labelTwo); - SetDraggable(false); - SetTouchable(false); - initViewStatus = true; - return true; -} - -bool CompassCalibrationView::InitView(void *caller) -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView InitView %p", caller); - bool ret = CreateUIViewGroup(); - if (!ret) { - return false; - } - SetDraggable(true); - SetTouchable(true); - return true; -} - -} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassControlView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassControlView.cpp index 546dd33f8..d4139a5b9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassControlView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassControlView.cpp @@ -4,95 +4,64 @@ * Author: * Create: 2022-04-02 */ -#include "CompassControlView.h" -#include "CompassModel.h" +#include "compass/CompassControlView.h" +#include "wearable_log.h" namespace OHOS { CompassControlView::CompassControlView() { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassControlView::CompassControlView()"); SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); } -CompassControlView::~CompassControlView() +void CompassControlView::PreLoad(void) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassControlView::~CompassControlView()"); - if (viewiInitStatus) { - ClearAll(); + if (compassFragment_ == nullptr) { + compassFragment_ = new CompassFragment(); + if (compassFragment_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassView::new compassFragment_ fail"); + return; + } } + + compassFragment_->CreateView(); + Add(compassFragment_->GetFragmentView()); } -void CompassControlView::ClearAll(void) +void CompassControlView::UnLoad(void) { - RemoveAll(); - if (compassCalibrationView != nullptr) { - delete compassCalibrationView; - compassCalibrationView = nullptr; - } - if (compassView != nullptr) { - delete compassView; - compassView = nullptr; + if (compassFragment_ != nullptr) { + compassFragment_->DestroyView(); + Remove(compassFragment_->GetFragmentView()); + delete compassFragment_; + compassFragment_ = nullptr; } } -bool CompassControlView::InitView(void) +void CompassControlView::OnPause(void) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassControlView InitView"); - compassCalibrationView = new CompassCalibrationView(); - if (compassCalibrationView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassCalibrationView::new compassCalibrationView fail"); - return false; - } - if (!compassCalibrationView->CreateUIViewGroup()) { - return false; - } - - compassView = new CompassView(); - if (compassView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassView::new compassView fail"); - return false; + if (compassFragment_ != nullptr) { + compassFragment_->PauseView(); } - if (!compassView->InitPage()) { - return false; - } - Add(compassView); - Add(compassCalibrationView); - uint8_t status = CompassModel::GetInstance()->GetCalibrationStatus(); - if (status == 1) { - compassView->SetVisible(false); - compassCalibrationView->SetVisible(true); - } else { - compassView->SetVisible(true); - compassCalibrationView->SetVisible(false); - } - return true; } -void CompassControlView::SetCalibrationView(bool flag) +void CompassControlView::OnActive(void) { - if (flag == isCalibration) { - return; - } - - if (flag) { - compassCalibrationView->SetVisible(true); - compassView->SetVisible(false); - } else { - compassCalibrationView->SetVisible(false); - compassView->SetVisible(true); + if (compassFragment_ != nullptr) { + compassFragment_->ResumeView(); } } -void CompassControlView::PreLoad(void) +void CompassControlView::ScrollBegin(bool isActive) { - if (!viewiInitStatus) { - InitView(); - viewiInitStatus = true; + if (isActive && (compassFragment_ != nullptr)) { + compassFragment_->PauseView(); } } -void CompassControlView::UnLoad(void) +void CompassControlView::ScrollEnd(bool isActive) { - // Compass's usage scenes is complicated, so we do not release it's resources inner slice. + if (isActive && (compassFragment_ != nullptr)) { + compassFragment_->ResumeView(); + } } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassFragment.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassFragment.cpp new file mode 100644 index 000000000..cca744b26 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassFragment.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: CompassFragment.cpp + * Author: + * Create: 2021-12-21 + */ +#include "compass/CompassFragment.h" + +#include +#include "UiConfig.h" +#include "common/image_cache_manager.h" +#include "ui_resource_image.h" +#include "compass/CompassModel.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr float VIEW_CENTERS = 227; +static constexpr int16_t POINT_CENTER_IMAGE_X = 150; +static constexpr int16_t POINT_CENTER_IMAGE_Y = 150; +static constexpr int16_t trianImg__X = 210; +static constexpr int16_t trianImg__Y = 0; +static constexpr int16_t directionLabel__X = 160; +static constexpr int16_t directionLabel__Y = 215; +static constexpr int16_t FONT_TEXT_SIZE = 25; +static constexpr int16_t angleLabel__X = 215; +static constexpr int16_t angleLabel__Y = 215; +static constexpr int16_t TEXT_WIDTH = 90; +static constexpr int16_t TEXT_HEIGHT = 35; +static constexpr int16_t RANDOM_NUMBER_720 = 720; +static constexpr int16_t RANDOM_NUMBER_360 = 360; +static constexpr int16_t DELAYING_NUMS = 2000; +static constexpr int16_t RIGHT_NORTH_DOWN_23 = 23; +static constexpr int16_t RIGHT_EASTNORTH_UP_68 = 68; +static constexpr int16_t RIGHT_WESTNORTH_UP_338 = 338; +static constexpr int16_t RIGHT_SOUTH_UP_203 = 203; +static constexpr int16_t RIGHT_EASTSOUTH_UP_158 = 158; +static constexpr int16_t RIGHT_WESTSOUTH_UP_248 = 248; +static constexpr int16_t RIGHT_WEST_UP_293 = 293; +static constexpr int16_t RIGHT_EAST_UP_113 = 113; +static constexpr int16_t DIRECTION_COUNT = 7; + +typedef struct { + uint16_t beginAngle; + uint16_t endAngle; + const char *dir; +} CompassItem; + +const CompassItem g_compassList[] = { + {RIGHT_NORTH_DOWN_23, RIGHT_EASTNORTH_UP_68, "东北"}, + {RIGHT_EASTNORTH_UP_68, RIGHT_EAST_UP_113, "东"}, + {RIGHT_EAST_UP_113, RIGHT_EASTSOUTH_UP_158, "东南"}, + {RIGHT_EASTSOUTH_UP_158, RIGHT_SOUTH_UP_203, "南"}, + {RIGHT_SOUTH_UP_203, RIGHT_WESTSOUTH_UP_248, "西南"}, + {RIGHT_WESTSOUTH_UP_248, RIGHT_WEST_UP_293, "西"}, + {RIGHT_WEST_UP_293, RIGHT_WESTNORTH_UP_338, "西北"} +}; + +void CompassFragment::Callback(void) +{ + if (!initialized_) { + return; + } + int16_t angle = CompassModel::GetInstance()->GetAngle(); + bgImg_->Rotate(-angle, Vector2(VIEW_CENTERS, VIEW_CENTERS)); + if ((angle >= RIGHT_WESTNORTH_UP_338) || (angle >= 0 && angle < RIGHT_NORTH_DOWN_23)) { + directionLabel_->SetText("北"); + angleLabel_->SetText((std::to_string(angle) + "°").c_str()); + } + for (int i = 0; i < DIRECTION_COUNT; i++) { + if ((angle >= g_compassList[i].beginAngle) && (angle < g_compassList[i].endAngle)) { + directionLabel_->SetText(g_compassList[i].dir); + angleLabel_->SetText((std::to_string(angle) + "°").c_str()); + } + } + CompassModel::GetInstance()->UpdateAngle(); +} + +bool CompassFragment::LoadCompassImage(UIImageView *view, uint32_t resId) +{ + std::string file = COMPASS_IAMGES; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassFragment LoadCompassImage: %s, resID=0x%x", COMPASS_IAMGES, resId); + ImageInfo* image = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId, file); + if (image == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassFragment::LoadCompassImage %x fail", resId); + return false; + } + view->SetSrc(image); + return true; +} + +bool CompassFragment::InitCompassImage(void) +{ + bgImg_ = new UIImageView(); + if (bgImg_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], bgImg_ new fail", __LINE__); + return false; + } + bgImg_->SetPosition(0, 0); + + if (!LoadCompassImage(bgImg_, COMPASS_COMPASS)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], trianImg_ load fail", __LINE__); + return false; + } + + fgImg_ = new UIImageView(); + if (fgImg_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], fgImg_ new fail", __LINE__); + return false; + } + fgImg_->SetPosition(POINT_CENTER_IMAGE_X, POINT_CENTER_IMAGE_Y); + if (!LoadCompassImage(fgImg_, COMPASS_ROTATE_CENTER_IMAGE)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], fgImg_ load fail", __LINE__); + return false; + } + + trianImg_ = new UIImageView(); + if (trianImg_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], trianImg_ new fail", __LINE__); + return false; + } + trianImg_->SetPosition(trianImg__X, trianImg__Y); + if (!LoadCompassImage(trianImg_, COMPASS_CORRESPONDENCE_DEGREE)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trianImg_ load fail"); + return false; + } + return true; +} + +void CompassFragment::OnCreateView(void* data) +{ + fragmentView_.SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassFragment InitView"); + if (!InitCompassImage()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitCompassImage fail"); + initialized_ = false; + return; + } + + directionLabel_ = new UILabel(); + if (directionLabel_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "directionLabel_ new fail"); + initialized_ = false; + return; + } + directionLabel_->SetPosition(directionLabel__X, directionLabel__Y); + directionLabel_->Resize(TEXT_WIDTH, TEXT_HEIGHT); + directionLabel_->SetText("北"); + directionLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_TEXT_SIZE); + directionLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + directionLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + directionLabel_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + directionLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + + angleLabel_ = new UILabel(); + if (angleLabel_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "angleLabel_ new fail"); + initialized_ = false; + return; + } + angleLabel_->SetPosition(angleLabel__X, angleLabel__Y); + angleLabel_->Resize(TEXT_WIDTH, TEXT_HEIGHT); + angleLabel_->SetText("0°"); + angleLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_TEXT_SIZE); + angleLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + angleLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + angleLabel_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + angleLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + + fragmentView_.Add(bgImg_); + fragmentView_.Add(fgImg_); + fragmentView_.Add(trianImg_); + fragmentView_.Add(directionLabel_); + fragmentView_.Add(angleLabel_); + CompassModel::GetInstance()->ResetAngle(); + initialized_ = true; +} + +void CompassFragment::OnPauseView() +{ + Deinit(); +} + +void CompassFragment::OnResumeView() +{ + Init(); +} + +void CompassFragment::OnDestroyView() +{ + Deinit(); + fragmentView_.RemoveAll(); + if (directionLabel_ != nullptr) { + delete directionLabel_; + directionLabel_= nullptr; + } + if (angleLabel_ != nullptr) { + delete angleLabel_; + angleLabel_ = nullptr; + } + if (bgImg_ != nullptr) { + delete bgImg_; + bgImg_ = nullptr; + } + if (fgImg_ != nullptr) { + delete fgImg_; + fgImg_ = nullptr; + } + if (trianImg_ != nullptr) { + delete trianImg_; + trianImg_ = nullptr; + } +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp index e9ff3f5c8..80774e6a6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp @@ -5,9 +5,8 @@ * Create: 2022-04-02 */ -#include -#include "CompassModel.h" -#include +#include "compass/CompassModel.h" +#include "gfx_utils/graphic_math.h" #ifdef __cplusplus extern "C" { @@ -20,59 +19,50 @@ using namespace OHOS; #endif namespace OHOS { +static constexpr int16_t DELTA_ANGLE = 1; + CompassModel *CompassModel::GetInstance(void) { static CompassModel instance; return &instance; } -void CompassModel::SetCalibrationStatus(uint8_t status) -{ - calibrationStatus = status; -} - -uint8_t CompassModel::GetCalibrationStatus(void) +void CompassModel::UpdateAngle() { - return 0; -} - -void CompassModel::SetDisplayAngle(uint16_t angle) -{ - displayAngle += angle; - if (displayAngle > 359) { - displayAngle = 0; + if (clockwise_) { + angle_ += DELTA_ANGLE; + } else { + angle_ -= DELTA_ANGLE; + } + if (angle_ >= CIRCLE_IN_DEGREE) { + angle_ = 360; + clockwise_ = false; + } + if (angle_ <= 0) { + angle_ = 0; + clockwise_ = true; } } -uint16_t CompassModel::GetDisplayAngle(void) -{ - return displayAngle; -} - -void CompassModel::SetLastTime(time_t value) -{ - lastTime = value; -} - -time_t CompassModel::GetLastTime(void) +int16_t CompassModel::GetAngle(void) { - return lastTime; + return angle_; } -time_t CompassModel::GetCurrentTime(void) +void CompassModel::ResetAngle(void) { - struct timeval tv; - gettimeofday(&tv, nullptr); - return tv.tv_sec; + angle_ = 0; } bool CompassModel::OpenCompassSensor(void) { + // Add implemetion later return true; } bool CompassModel::CloseCompassSensor(void) { + // Add implemetion later return true; } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassPresenter.cpp deleted file mode 100644 index 4a48b5458..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassPresenter.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: CompassPresenter.cpp - * Author: - * Create: 2021-12-21 - */ -#include "CompassView.h" -#include "CompassPresenter.h" -#include "CompassModel.h" -#include "graphic_service.h" - -namespace OHOS { -static constexpr int16_t RIGHT_NORTH_DOWN_23 = 23; -static constexpr int16_t RIGHT_EASTNORTH_UP_68 = 68; -static constexpr int16_t RIGHT_WESTNORTH_UP_338 = 338; -static constexpr int16_t RIGHT_SOUTH_UP_203 = 203; -static constexpr int16_t RIGHT_EASTSOUTH_UP_158 = 158; -static constexpr int16_t RIGHT_WESTSOUTH_UP_248 = 248; -static constexpr int16_t RIGHT_WEST_UP_293 = 293; -static constexpr int16_t RIGHT_EAST_UP_113 = 113; -static constexpr int16_t RIGHT_MAX_ANGLE_360 = 360; -static constexpr int16_t RIGHT_HALF_ANGLE_180 = 180; -static constexpr int16_t RIGHT_ROTATION_INTERVAL = 2; -static constexpr int16_t DIRECTION_COUNT = 7; -static constexpr int16_t LEFT_NORTH_DOWN_23 = -23; -static constexpr int16_t LEFT_EASTNORTH_DOWN_337 = -337; -static constexpr int16_t LEFT_WESTNORTH_DOWN_68 = -68; -static constexpr int16_t LEFT_SOUTH_DOWN_202 = -202; -static constexpr int16_t LEFT_EASTSOUTH_DOWN_247 = -247; -static constexpr int16_t LEFT_WESTSOUTH_DOWN_157 = -157; -static constexpr int16_t LEFT_WEST_DOWN_113 = -113; -static constexpr int16_t LEFT_EAST_DOWN_292 = -292; -static constexpr int16_t RIGHT_MIN_ANGLE_360 = -360; -static constexpr int16_t LEFT_HALF_ANGLE_180 = -180; -static constexpr int16_t LEFT_ROTATION_INTERVAL = -2; - -static constexpr const char *NORTH_DIRECTION = (char *)"北"; -static constexpr const char *SOUTH_DIRECTION = (char *)"南"; -static constexpr const char *WEST_DIRECTION = (char *)"西"; -static constexpr const char *EAST_DIRECTION = (char *)"东"; -static constexpr const char *WESTNORTH_DIRECTION = (char *)"西北"; -static constexpr const char *WESTSOUTH_DIRECTION = (char *)"西南"; -static constexpr const char *EASTSOUTH_DIRECTION = (char *)"东南"; -static constexpr const char *EASTNORTH_DIRECTION = (char *)"东北"; - -const CompassItem g_compassList[] = { - {RIGHT_NORTH_DOWN_23, RIGHT_EASTNORTH_UP_68, EASTNORTH_DIRECTION}, - {RIGHT_EASTNORTH_UP_68, RIGHT_EAST_UP_113, EAST_DIRECTION}, - {RIGHT_EAST_UP_113, RIGHT_EASTSOUTH_UP_158, EASTSOUTH_DIRECTION}, - {RIGHT_EASTSOUTH_UP_158, RIGHT_SOUTH_UP_203, SOUTH_DIRECTION}, - {RIGHT_SOUTH_UP_203, RIGHT_WESTSOUTH_UP_248, WESTSOUTH_DIRECTION}, - {RIGHT_WESTSOUTH_UP_248, RIGHT_WEST_UP_293, WEST_DIRECTION}, - {RIGHT_WEST_UP_293, RIGHT_WESTNORTH_UP_338, WESTNORTH_DIRECTION} -}; - -static CompassPresenter *g_pMainView = nullptr; - -CompassPresenter::CompassPresenter() -{ - g_pMainView = this; -} - -CompassPresenter::~CompassPresenter() -{ - g_pMainView = nullptr; -} - -CompassPresenter* CompassPresenter::GetInstance(void) -{ - return g_pMainView; -} - -void CompassPresenter::DisplayAngleRight(uint16_t angle) -{ - if ((angle >= RIGHT_WESTNORTH_UP_338) || (angle >= 0 && angle < RIGHT_NORTH_DOWN_23)) { - CompassView::GetInstance()->DirectionSetText(NORTH_DIRECTION, (std::to_string(angle) + "°").c_str()); - } - for (int i = 0; i < DIRECTION_COUNT; i++) { - if ((angle >= g_compassList[i].beginAngle) && (angle < g_compassList[i].endAngle)) { - CompassView::GetInstance()->DirectionSetText(g_compassList[i].dir, (std::to_string(angle) + "°").c_str()); - } - } -} - -void CompassPresenter::DisplayAngleDir(uint16_t angle) -{ - if (CompassView::GetInstance() == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DisplayAngleDir]CompassView::GetInstance() is nullptr"); - return; - } - if (angle >= 0 && angle <= RIGHT_MAX_ANGLE_360) { - DisplayAngleRight(angle); - } -} - - -void CompassPresenter::InScopeRotate(void) -{ - angleDiff = lastRotateAngle - currentRotateAngle; - if (angleDiff > LEFT_HALF_ANGLE_180 && angleDiff < RIGHT_HALF_ANGLE_180) { - if (lastRotateAngle < currentRotateAngle) { - CompassView::GetInstance()->CompassStartRotate(lastRotateAngle); - if (angleDiff <= LEFT_ROTATION_INTERVAL) { - lastRotateAngle+=RIGHT_ROTATION_INTERVAL; - } else { - lastRotateAngle++; - } - } else if (lastRotateAngle != currentRotateAngle) { - CompassView::GetInstance()->CompassStartRotate(lastRotateAngle); - if (angleDiff >= RIGHT_ROTATION_INTERVAL) { - lastRotateAngle-=RIGHT_ROTATION_INTERVAL; - } else { - lastRotateAngle--; - } - } - } else { - if (lastRotateAngle < currentRotateAngle) { - CompassView::GetInstance()->CompassStartRotate(lastRotateAngle); - if (angleDiff <= LEFT_ROTATION_INTERVAL) { - lastRotateAngle-=RIGHT_ROTATION_INTERVAL; - } else { - lastRotateAngle--; - } - if (lastRotateAngle <= 0) { - lastRotateAngle = RIGHT_MAX_ANGLE_360; - } - } else if (lastRotateAngle != currentRotateAngle) { - CompassView::GetInstance()->CompassStartRotate(lastRotateAngle); - if (angleDiff >= RIGHT_ROTATION_INTERVAL) { - lastRotateAngle+=RIGHT_ROTATION_INTERVAL; - } else { - lastRotateAngle++; - } - if (lastRotateAngle >= RIGHT_MAX_ANGLE_360) { - lastRotateAngle = 0; - } - } - } -} - -void CompassPresenter::DetermineToRotate(void) -{ - if (CompassView::GetInstance() == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DetermineToRotate]CompassView::GetInstance() is nullptr"); - return; - } - bool initState = CompassView::GetInstance()->GetInitViewState(); - if (initState) { - if (initDisplayStatus) { - currentRotateAngle = CompassModel::GetInstance()->GetDisplayAngle(); - lastRotateAngle = currentRotateAngle; - CompassView::GetInstance()->CompassStartRotate(lastRotateAngle); - DisplayAngleDir(currentRotateAngle); - initDisplayStatus = false; - } else { - if (!getAngleStatus) { - currentRotateAngle = CompassModel::GetInstance()->GetDisplayAngle(); - } - InScopeRotate(); - getAngleStatus = true; - if (lastRotateAngle == currentRotateAngle) { - CompassView::GetInstance()->CompassStartRotate(lastRotateAngle); - DisplayAngleDir(currentRotateAngle); - getAngleStatus = false; - } - } - } - CompassModel::GetInstance()->SetDisplayAngle(1); -} - -} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassView.cpp deleted file mode 100644 index 5b3bbc27d..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassView.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: CompassView.cpp - * Author: - * Create: 2021-12-21 - */ -#include -#include "common/image_cache_manager.h" -#include "ui_resource_image.h" -#include "CompassView.h" -#include "MainCompassView.h" - -namespace OHOS { -static constexpr int16_t POINT_CENTER_IMAGE_X = 150; -static constexpr int16_t POINT_CENTER_IMAGE_Y = 150; -static constexpr int16_t TRIANGULATION_X = 210; -static constexpr int16_t TRIANGULATION_Y = 0; -static constexpr int16_t DIRECTIONLABEL_X = 160; -static constexpr int16_t DIRECTIONLABEL_Y = 215; -static constexpr int16_t FONT_TEXT_SIZE = 25; -static constexpr int16_t ANGLEDLABEL_X = 215; -static constexpr int16_t ANGLEDLABEL_Y = 215; -static constexpr int16_t TEXT_WIDTH = 90; -static constexpr int16_t TEXT_HEIGHT = 35; -static constexpr int16_t RANDOM_NUMBER_720 = 720; -static constexpr int16_t RANDOM_NUMBER_360 = 360; -static constexpr int16_t DELAYING_NUMS = 2000; - -static CompassView *g_pCompassView = nullptr; - -CompassView::CompassView() -{ - SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); - g_pCompassView = this; -} - -CompassView::~CompassView() -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassView::~CompassView()"); - ClearAll(); - g_pCompassView = nullptr; -} - -void CompassView::ClearAll(void) -{ - RemoveAll(); - if (directionLabel != nullptr) { - delete directionLabel; - directionLabel= nullptr; - } - if (angledLabel != nullptr) { - delete angledLabel; - angledLabel = nullptr; - } - if (backGround != nullptr) { - delete backGround; - backGround = nullptr; - } - if (rotateShaft != nullptr) { - delete rotateShaft; - rotateShaft = nullptr; - } - if (triangulation != nullptr) { - delete triangulation; - triangulation = nullptr; - } -} - -void CompassView::DirectionSetText(const char *text, const char *angle) -{ - directionLabel->SetText(text); - angledLabel->SetText(angle); -} - -bool CompassView::LoadCompassImage(UIImageView *view, uint32_t resId) -{ - std::string file = COMPASS_IAMGES; - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassView LoadCompassImage: %s, resID=0x%x", COMPASS_IAMGES, resId); - ImageInfo* image = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId, file); - if (image == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CompassView::LoadCompassImage %x fail", resId); - return false; - } - view->SetSrc(image); - return true; -} - -bool CompassView::InitCompassImage(void) -{ - backGround = new UIImageView(); - if (backGround == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], backGround new fail", __LINE__); - return false; - } - backGround->SetPosition(0, 0); - - if (!LoadCompassImage(backGround, COMPASS_COMPASS)) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], triangulation load fail", __LINE__); - return false; - } - - rotateShaft = new UIImageView(); - if (rotateShaft == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], rotateShaft new fail", __LINE__); - return false; - } - rotateShaft->SetPosition(POINT_CENTER_IMAGE_X, POINT_CENTER_IMAGE_Y); - if (!LoadCompassImage(rotateShaft, COMPASS_ROTATE_CENTER_IMAGE)) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], rotateShaft load fail", __LINE__); - return false; - } - - triangulation = new UIImageView(); - if (triangulation == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d], triangulation new fail", __LINE__); - return false; - } - triangulation->SetPosition(TRIANGULATION_X, TRIANGULATION_Y); - if (!LoadCompassImage(triangulation, COMPASS_CORRESPONDENCE_DEGREE)) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "triangulation load fail"); - return false; - } - return true; -} - -bool CompassView::InitPage(void) -{ - if (!InitCompassImage()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitCompassImage fail"); - ClearAll(); - return false; - } - - directionLabel = new UILabel(); - if (directionLabel == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "directionLabel new fail"); - ClearAll(); - return false; - } - directionLabel->SetPosition(DIRECTIONLABEL_X, DIRECTIONLABEL_Y); - directionLabel->Resize(TEXT_WIDTH, TEXT_HEIGHT); - directionLabel->SetText("北"); - directionLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_TEXT_SIZE); - directionLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - directionLabel->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); - directionLabel->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); - directionLabel->SetStyle(STYLE_TEXT_COLOR, Color::White().full); - - angledLabel = new UILabel(); - if (angledLabel == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "angledLabel new fail"); - ClearAll(); - return false; - } - angledLabel->SetPosition(ANGLEDLABEL_X, ANGLEDLABEL_Y); - angledLabel->Resize(TEXT_WIDTH, TEXT_HEIGHT); - angledLabel->SetText("0°"); - angledLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_TEXT_SIZE); - angledLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - angledLabel->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); - angledLabel->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); - angledLabel->SetStyle(STYLE_TEXT_COLOR, Color::White().full); - - Add(backGround); - Add(rotateShaft); - Add(triangulation); - Add(directionLabel); - Add(angledLabel); - SetDraggable(false); - SetTouchable(false); - initViewStatus = true; - return true; -} - - -bool CompassView::InitView(void *caller) -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CompassView InitView %p", caller); - if (!InitPage()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitPage fail"); - return false; - } - SetDraggable(true); - SetTouchable(true); - return true; -} - -bool CompassView::GetInitViewState(void) -{ - return initViewStatus; -} - -CompassView *CompassView::GetInstance(void) -{ - return g_pCompassView; -} - -void CompassView::CompassStartRotate(int16_t numb) -{ - if (backGround == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backGround is nullptr"); - return; - } - backGround->Rotate(-numb, VIEW_CENTER); -} -} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassPresenter.cpp index 72dc3b726..11a3b45cd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassPresenter.cpp @@ -4,54 +4,36 @@ * Author: * Create: 2021-12-21 */ -#include "CompassView.h" -#include "MainCompassPresenter.h" -#include "MainCompassView.h" +#include "compass/MainCompassPresenter.h" +#include "compass/MainCompassView.h" #include "NativeRegisterManager.h" namespace OHOS { -REGIST_MENU(VIEW_COMPASS, MainCompassView, MainCompassPresenter, PNG_APPLIST_COMPASS_IMAGE, PNG_APPLIST_DEFAULT_IMG, "指南针"); - -static MainCompassPresenter *g_pMainView = nullptr; - -MainCompassPresenter::MainCompassPresenter() -{ - g_pMainView = this; -} - -MainCompassPresenter::~MainCompassPresenter() -{ - g_pMainView = nullptr; -} - - -MainCompassPresenter* MainCompassPresenter::GetInstance() -{ - return g_pMainView; -} +REGIST_MENU(VIEW_COMPASS, MainCompassView, MainCompassPresenter, PNG_APPLIST_COMPASS_IMAGE, + PNG_APPLIST_DEFAULT_IMG, "指南针"); bool MainCompassPresenter::OnDrag(UIView& view, const DragEvent& event) { UNUSED(view); - if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) { + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); } return true; } -void MainCompassPresenter::Notify() +void MainCompassPresenter::OnResume() { - if (MainCompassView::GetInstance() == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Notify]MainCompassView::GetInstance() == nullptr"); - return; + if ((view_ != nullptr) && (view_->compassFragment_ != nullptr)) { + view_->compassFragment_->ResumeView(); } - uint8_t status = CompassModel::GetInstance()->GetCalibrationStatus(); - if (status == 1) { - MainCompassView::GetInstance()->SetDisplayTure(); - } else { - MainCompassView::GetInstance()->SetDisplayFalse(); - DetermineToRotate(); +} + +void MainCompassPresenter::OnPause() +{ + if ((view_ != nullptr) && (view_->compassFragment_ != nullptr)) { + view_->compassFragment_->PauseView(); } } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassView.cpp index b5311d462..9f7ecb0fa 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/MainCompassView.cpp @@ -5,107 +5,36 @@ * Create: 2021-12-23 */ -#include "MainCompassView.h" -#include "MainCompassPresenter.h" +#include "compass/MainCompassView.h" +#include "compass/MainCompassPresenter.h" +#include "compass/CompassModel.h" +#include "wearable_log.h" namespace OHOS { static constexpr int16_t TWO_HOUR_SECOND = 7200; -static MainCompassView *g_pMainCompassView = nullptr; - -MainCompassView::MainCompassView() -{ - g_pMainCompassView = this; -} - -MainCompassView::~MainCompassView() -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MainCompassView::~MainCompassView"); - delete compassView; - compassView = nullptr; - delete compassCalibrationView; - compassCalibrationView = nullptr; - g_pMainCompassView = nullptr; -} - -MainCompassView *MainCompassView::GetInstance() -{ - return g_pMainCompassView; -} - -void MainCompassView::SetDisplayTure() -{ - if (compassView == nullptr || compassCalibrationView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MainCompassView::SetDisplayTure null"); - return; - } - compassView->SetVisible(false); - compassCalibrationView->SetVisible(true); -} - -void MainCompassView::SetDisplayFalse() -{ - if (compassView == nullptr || compassCalibrationView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MainCompassView::SetDisplayFalse null"); - return; - } - compassView->SetVisible(true); - compassCalibrationView->SetVisible(false); -} void MainCompassView::OnStart() { - - compassCalibrationView = new CompassCalibrationView(); - if (compassCalibrationView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MainCompassView:: OnStart compassCalibrationView null"); - return; - } - - compassView = new CompassView(); - if (compassView == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MainCompassView:: OnStart compassView null"); + compassFragment_ = new CompassFragment(); + if (compassFragment_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MainCompassView:: OnStart compassFragment_ null"); return; } - - UIView::OnDragListener *compassCalibrationDragListener = (UIView::OnDragListener *) - OHOS::MainCompassPresenter::GetInstance(); - if (compassCalibrationDragListener == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "compassCalibrationDragListener new fail"); - return; - } - - UIView::OnDragListener *compassDragListener = (UIView::OnDragListener *)OHOS::MainCompassPresenter::GetInstance(); - if (compassDragListener == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "compassDragListener new fail"); - return; - } - compassView->SetOnDragListener(compassDragListener); - compassView->InitView(this); - - compassCalibrationView->SetOnDragListener(compassCalibrationDragListener); - compassCalibrationView->InitView(this); - AddViewToRootContainer(compassView); - AddViewToRootContainer(compassCalibrationView); - - time_t currTime = CompassModel::GetInstance()->GetCurrentTime(); - time_t lastTime = CompassModel::GetInstance()->GetLastTime(); - if (currTime >= TWO_HOUR_SECOND + lastTime) { - CompassModel::GetInstance()->SetCalibrationStatus(1); - } - - uint8_t status = CompassModel::GetInstance()->GetCalibrationStatus(); - if (status == 1) { - compassView->SetVisible(false); - compassCalibrationView->SetVisible(true); - } else { - compassView->SetVisible(true); - compassCalibrationView->SetVisible(false); - } + compassFragment_->CreateView(); + compassFragment_->GetFragmentView()->SetTouchable(true); + compassFragment_->GetFragmentView()->SetDraggable(true); + compassFragment_->GetFragmentView()->SetOnDragListener(presenter_); + AddViewToRootContainer(compassFragment_->GetFragmentView()); CompassModel::GetInstance()->OpenCompassSensor(); } void MainCompassView::OnStop() { + if (compassFragment_ != nullptr) { + compassFragment_->DestroyView(); + delete compassFragment_; + compassFragment_ = nullptr; + } CompassModel::GetInstance()->CloseCompassSensor(); return; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectOpenView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectOpenView.cpp index ac8fee5af..2b5a5f419 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectOpenView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectOpenView.cpp @@ -3,11 +3,12 @@ * Description: ConnectOpen View * Create: 2022-03-22 */ -#include "ConnectOpenView.h" +#include "connectnewphone/ConnectOpenView.h" +#include "PageTransitionMgr.h" #include "wearable_log.h" #include "UiConfig.h" -#include "ConnectPhonePresenter.h" -#include "BluetoothModel.h" +#include "connectnewphone/ConnectPhonePresenter.h" +#include "bluetooth/BluetoothModel.h" namespace OHOS { static ConnectOpenView *g_pConnectOpenView{nullptr}; @@ -120,7 +121,7 @@ UIViewGroup *ConnectOpenView::InitShowUpView(void) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "tipsDragListener GetInstance fail"); return nullptr; } - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly group->SetOnDragListener(tipsDragListener); } group->SetViewId(CONNECT_OPEN_VIEW); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhonePresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhonePresenter.cpp index 4994756ca..a9a89852c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhonePresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhonePresenter.cpp @@ -4,13 +4,13 @@ * Create: 2022-01-19 */ -#include "ConnectPhonePresenter.h" -#include "ConnectPhoneView.h" +#include "connectnewphone/ConnectPhonePresenter.h" +#include "connectnewphone/ConnectPhoneView.h" #include "drag_event.h" #include "cmsis_os.h" #include "UiConfig.h" #include "wearable_log.h" -#include "ui_service.h" +#include "uiservice/ui_service.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhoneView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhoneView.cpp index 5e9c6b58c..1e5b1c109 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhoneView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectPhoneView.cpp @@ -4,7 +4,7 @@ * Create: 2022-01-19 */ -#include "ConnectPhoneView.h" +#include "connectnewphone/ConnectPhoneView.h" #include "components/ui_label.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectSelectView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectSelectView.cpp index 3a4196111..4465006bc 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectSelectView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/src/ConnectSelectView.cpp @@ -3,10 +3,11 @@ * Description: ConnectSelect View * Create: 2022-03-22 */ -#include "ConnectSelectView.h" +#include "connectnewphone/ConnectSelectView.h" +#include "PageTransitionMgr.h" #include "wearable_log.h" #include "UiConfig.h" -#include "ConnectPhonePresenter.h" +#include "connectnewphone/ConnectPhonePresenter.h" namespace OHOS { static ConnectSelectView *g_pConnectSelectView{nullptr}; @@ -109,7 +110,7 @@ UIViewGroup *ConnectSelectView::InitShowUpView() WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "connectDragListener GetInstance fail"); return nullptr; } - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly group->SetOnDragListener(connectDragListener); } group->SetViewId(CONNECT_SELECT_VIEW); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateAdapter.cpp new file mode 100644 index 000000000..944e5b6fc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateAdapter.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateAdapter + * Create: 2025-03-23 + */ + +#include "date/DateAdapter.h" + +namespace OHOS { +DateAdapter::DateAdapter() {} + +DateAdapter::~DateAdapter() +{ + listData.clear(); +} + +uint16_t DateAdapter::GetCount(void) +{ + return listData.size(); +} + +void DateAdapter::SetData(std::list &data) +{ + if (!listData.empty()) { + listData.clear(); + } + std::list::iterator it; + for (it = data.begin(); it != data.end(); it++) { + listData.push_back(*it); + } +} + +UIView *DateAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData.size()) { + return nullptr; + } + + std::list::iterator it = listData.begin(); + for (int i = 0; i < index; i++) { + it++; + } + DateItem itemData = *it; + DateItemView *item = nullptr; + if (inView == nullptr) { + item = new DateItemView(); + } else { + item = static_cast(inView); + } + + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void DateAdapter::AddListItem(const DateItem &item) +{ + listData.push_back(item); +} + +void DateAdapter::ClearListItem() +{ + listData.clear(); +} + +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonAdapter.cpp new file mode 100644 index 000000000..c187d094c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonAdapter.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateButtonAdapter + * Create: 2025-03-23 + */ + +#include "date/DateButtonAdapter.h" + +namespace OHOS { +DateButtonAdapter::DateButtonAdapter() {} + +DateButtonAdapter::~DateButtonAdapter() +{ + listData.clear(); +} + +uint16_t DateButtonAdapter::GetCount(void) +{ + return listData.size(); +} + +void DateButtonAdapter::SetData(std::list &data) +{ + if (!listData.empty()) { + listData.clear(); + } + std::list::iterator it; + for (it = data.begin(); it != data.end(); it++) { + listData.push_back(*it); + } +} + +UIView *DateButtonAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData.size()) { + return nullptr; + } + + std::list::iterator it = listData.begin(); + for (int i = 0; i < index; i++) { + it++; + } + DateButtonItem itemData = *it; + DateButtonItemView *item = nullptr; + if (inView == nullptr) { + item = new DateButtonItemView(); + } else { + item = static_cast(inView); + } + + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void DateButtonAdapter::AddListItem(const DateButtonItem &item) +{ + listData.push_back(item); +} + +void DateButtonAdapter::ClearListItem() +{ + listData.clear(); +} + +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonItemView.cpp new file mode 100644 index 000000000..210f188bc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateButtonItemView.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateButtonItemView + * Create: 2025-03-23 + */ + +#include "date/DateButtonItemView.h" +#include "UiConfig.h" +#include "common/image_cache_manager.h" +#include "ui_resource_date.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr int16_t DATE_ITEM_BUTTON_POSITION_X = 0; +static constexpr int16_t DATE_ITEM_BUTTON_POSITION_Y = 20; +static constexpr int16_t DATE_ITEM_BUTTON_WIDTH = 80; +static constexpr int16_t DATE_ITEM_BUTTON_HEIGHT = 55; +static constexpr int16 DATE_ITEM_FONT_SIZE = 36; +static constexpr int16_t DATE_ITEM_WIDTH = 95; +static constexpr int16_t DATE_ITEM_HEIGHT = 60; + +DateButtonItemView::DateButtonItemView() +{ + SetPosition(0, 0, DATE_ITEM_WIDTH, DATE_ITEM_HEIGHT); + SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + SetTouchable(true); + SetUpChild(); + + Add(&sLabelButton); +} + +DateButtonItemView::~DateButtonItemView() +{ + Remove(&sLabelButton); +} + +void DateButtonItemView::SetItemInfo(const DateButtonItem itemInfo) +{ + sItemInfo = itemInfo; + sLabelButton.SetText(sItemInfo.button_day); + ImageInfo *image1; + ImageInfo *image2; + if (sItemInfo.isFirst) { + if (sItemInfo.isSelect) { + image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE6, DATE_IMAGE); + sLabelButton.SetTextColor(Color::White()); + } else { + sLabelButton.SetTextColor(Color::GetColorFromRGBA(0xe0, 0x2d, 0x2f, 0xff)); + image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE3, DATE_IMAGE); + } + if (image1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadBtnImage resId1 fail"); + return; + } + image2 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE6, DATE_IMAGE); + if (image2 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadBtnImage resId2 fail"); + return; + } + } else { + if (sItemInfo.isSelect) { + image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE4, DATE_IMAGE); + } else { + image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE2, DATE_IMAGE); + } + if (image1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadBtnImage resId1 fail"); + return; + } + image2 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE4, DATE_IMAGE); + if (image2 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadBtnImage resId2 fail"); + return; + } + sLabelButton.SetTextColor(Color::White()); + } + sLabelButton.SetImageSrc(image1, image2); +} + +void DateButtonItemView::SetUpChild() +{ + sLabelButton.SetPosition(DATE_ITEM_BUTTON_POSITION_X, 0); + sLabelButton.Resize(DATE_ITEM_BUTTON_WIDTH, DATE_ITEM_BUTTON_HEIGHT); + sLabelButton.SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_ITEM_FONT_SIZE); + sLabelButton.SetAlign(TEXT_ALIGNMENT_CENTER); + sLabelButton.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabelButton.SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + sLabelButton.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); +} + +DateButtonItem DateButtonItemView ::GetItem() +{ + return sItemInfo; +} + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateItemView.cpp new file mode 100644 index 000000000..a20141236 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateItemView.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateItemView + * Create: 2025-03-23 + */ + +#include "date/DateItemView.h" +#include "UiConfig.h" +#include "common/image_cache_manager.h" +#include "ui_resource_date.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr int16_t DATE_ITEM_BUTTON_HEIGHT = 65; +static constexpr int16_t DATE_ITEM_LABEL_POSITION_X = 43; +static constexpr int16_t DATE_ITEM_LABEL_POSITION_Y = 22; +static constexpr int16_t DATE_ITEM_LABEL_TWO_POSITION_X = 23; +static constexpr int16_t DATE_ITEM_LABEL_TWO_POSITION_Y = 60; +static constexpr int16_t DATE_ITEM_LABEL_WIDTH = 135; +static constexpr int16_t DATE_ITEM_LABEL_HEIGHT = 40; +static constexpr int16_t DATE_ITEM_LABEL2_HEIGHT = 96; +static constexpr int16_t DATE_ITEM_LABEL_TWO_WIDTH = 314; +static constexpr int16 DATE_ITEM_FONT_SIZE = 24; +static constexpr int16 DATE_ITEM_FONT2_SIZE = 32; +static constexpr int16_t DATE_ITEM_WIDTH = 376; +static constexpr int16_t DATE_ITEM_HEIGHT = 190; + +DateItemView::DateItemView() +{ + SetPosition(0, 0, DATE_ITEM_WIDTH, DATE_ITEM_HEIGHT); + SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + SetTouchable(true); + SetUpChild(); + + Add(&sLabel_1); + Add(&sLabel_2); + Add(&Signs); + Add(&BackGround); +} + +DateItemView::~DateItemView() +{ + Remove(&sLabel_1); + Remove(&sLabel_2); + Remove(&Signs); + Remove(&BackGround); +} + +void DateItemView::SetItemInfo(const DateItem itemInfo) +{ + sItemInfo = itemInfo; + sLabel_1.SetText(itemInfo.label_1); + sLabel_2.SetText(itemInfo.label_2); + BackGround.SetPosition(0, 0); + if (itemInfo.visiable) { + int offsetX1 = 100; + int offsetY1 = 10; + int offsetX2 = 30; + int offsetY2 = 40; + sLabel_1.SetPosition(DATE_ITEM_LABEL_POSITION_X + offsetX1, DATE_ITEM_LABEL_POSITION_Y + offsetY1); + sLabel_2.SetPosition(DATE_ITEM_LABEL_TWO_POSITION_X + offsetX2, DATE_ITEM_LABEL_TWO_POSITION_Y + offsetY2); + sLabel_1.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel_2.SetStyle(STYLE_TEXT_COLOR, Color::Gray().full); + sLabel_1.SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_ITEM_FONT2_SIZE); + sLabel_2.SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_ITEM_FONT_SIZE); + Signs.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + } else { + sLabel_1.SetPosition(DATE_ITEM_LABEL_POSITION_X, DATE_ITEM_LABEL_POSITION_Y); + sLabel_2.SetPosition(DATE_ITEM_LABEL_TWO_POSITION_X, DATE_ITEM_LABEL_TWO_POSITION_Y); + sLabel_1.SetStyle(STYLE_TEXT_COLOR, Color::Gray().full); + sLabel_2.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel_1.SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_ITEM_FONT_SIZE); + sLabel_2.SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_ITEM_FONT2_SIZE); + Signs.SetPosition(DATE_ITEM_LABEL_TWO_POSITION_X, DATE_ITEM_FONT_SIZE); + } + Signs.SetVisible(!itemInfo.visiable); +} + +void DateItemView::SetUpChild() +{ + sLabel_1.Resize(DATE_ITEM_LABEL_WIDTH, DATE_ITEM_LABEL_HEIGHT); + sLabel_1.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_LEFT); + sLabel_1.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_1.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel_1.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sLabel_2.Resize(DATE_ITEM_LABEL_TWO_WIDTH, DATE_ITEM_LABEL2_HEIGHT); + sLabel_2.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_LEFT); + sLabel_2.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_2.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel_2.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE5, DATE_IMAGE); + if (image == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "DateMessagePage::OnStart LoadStopwatchImage IMAGE_CONVERTER_TOOL_DATE5 fail"); + return; + } + Signs.SetSrc(image); + image = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE1, DATE_IMAGE); + if (image == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "DateMessagePage::OnStart LoadStopwatchImage IMAGE_CONVERTER_TOOL_DATE1 fail"); + return; + } + BackGround.SetSrc(image); +} + +const char *DateItemView ::GetViewId() +{ + return sItemInfo.index; +} +bool DateItemView::GetVisiable() +{ + return sItemInfo.visiable; +} + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMainPage.cpp new file mode 100644 index 000000000..5072468de --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMainPage.cpp @@ -0,0 +1,303 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateMainPage + * Created: 2025-4 + */ + +#include "date/DateMainPage.h" +#include "date/DateModel.h" +#include "date/DatePresenter.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "UiConfig.h" +#include "common/image_cache_manager.h" +#include "components/ui_button.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "ui_resource_date.h" + +static constexpr int16_t DOWNSELECTPOSITION = 100; +static constexpr int16_t DOWNCONTENTLIST_POSITION_X = 39; +static constexpr int16_t DOWNCONTENTLIST_POSITION_Y = 171; +static constexpr int16_t DOWNCONTENTLIST_WIDTH = 376; +static constexpr int16_t DOWNCONTENTLIST_HEIGHT = 260; +static constexpr int16_t BUTTONCONTENTLIST_POSITION_X = 36; +static constexpr int16_t BUTTONCONTENTLIST_POSITION_Y = 97; +static constexpr int16_t BUTTONCONTENTLIST_WIDTH = 410; +static constexpr int16_t BUTTONCONTENTLIST_HEIGHT = 55; +static constexpr int16_t BUTTONCONTENTLIST_SELECT_POSITON = 90; +static constexpr uint16_t DATE_MONTH_FONT = 25; +static constexpr uint16_t DATE_MONTH_POS_X = 129; +static constexpr uint16_t DATE_MONTH_POS_Y = 31; +static constexpr uint16_t DATE_MONTH_WIDTH = 196; +static constexpr uint16_t LIST_POSITION_Y = 155; +static constexpr uint16_t DATE_MONTH_HEIGHT = 50; +static constexpr uint8_t FONT_FORTY_SIZE = 36; + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_DATE, DATE_PAGES::DATE_MAIN_PAGE, DateMainPage, true); + +DateMainPage::DateMainPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DateMainPage::DateMainPage"); +} + +DateMainPage::~DateMainPage() +{ + if (uiScrollView != nullptr) { + uiScrollView->RemoveAll(); + delete uiScrollView; + uiScrollView = nullptr; + } + + if (listAdapter != nullptr) { + delete listAdapter; + listAdapter = nullptr; + } + + if (buttonAdapter != nullptr) { + delete buttonAdapter; + buttonAdapter = nullptr; + } + + if (buttonContentList != nullptr) { + delete buttonContentList; + buttonContentList = nullptr; + } + + if (downContentList != nullptr) { + delete downContentList; + downContentList = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (image1 != nullptr) { + delete image1; + image1 = nullptr; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DateMainPage::~DateMainPage"); +} + +void DateMainPage::OnStart(void *data) +{ + uiScrollView = new UIScrollView(); + if (uiScrollView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DateView::OnStart::scrollView is nullptr"); + return; + } + uiScrollView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + uiScrollView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + uiScrollView->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + uiScrollView->SetThrowDrag(true); + uiScrollView->SetOnDragListener(this); + uiScrollView->SetThrowDrag(true); + image1 = new UIImageView(); + if (image1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DateView::OnStart::image1 is nullptr"); + return; + } + image1->SetPosition(0, 0); + image1->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + ImageInfo *imgSrc = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE7, DATE_IMAGE); + if (imgSrc == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "DateMainPage::OnStart LoadOneInMultiRes IMAGE_CONVERTER_TOOL_DATE8 fail"); + return; + } + image1->SetSrc(imgSrc); + uiScrollView->Add(image1); + + DateModel::GetInstance().InitDate(); + title = new UILabel(); + if (title == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DateView::OnStart::title is nullptr"); + return; + } + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_MONTH_FONT); + std::stringstream ss; + title->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT, UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_FORTY_SIZE); + title->SetPosition(DATE_MONTH_POS_X, DATE_MONTH_POS_Y, DATE_MONTH_WIDTH, DATE_MONTH_HEIGHT); + uiScrollView->Add(title); + InitDownList(); + AddViewToPageContainer(uiScrollView); +} + +void DateMainPage::InitDownList() +{ + if (buttonContentList == nullptr) { + buttonContentList = new UIList(0); + } + buttonAdapter = new DateButtonAdapter(); + if (buttonAdapter == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DateView::OnStart::listAdapter is nullptr"); + return; + } + buttonAdapter->SetItemClickListener(this); + buttonContentList->SetViewId("buttonList"); + buttonContentList->SetPosition(BUTTONCONTENTLIST_POSITION_X, BUTTONCONTENTLIST_POSITION_Y, BUTTONCONTENTLIST_WIDTH, + BUTTONCONTENTLIST_HEIGHT); + buttonContentList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + buttonContentList->SetSelectPosition(BUTTONCONTENTLIST_SELECT_POSITON); + buttonContentList->SetDraggable(true); + buttonContentList->SetThrowDrag(true); + buttonContentList->EnableAutoAlign(true); + buttonContentList->ScrollTo(0); + buttonContentList->SetAdapter(buttonAdapter); + buttonContentList->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + InitDateTop(); + RefreshButtonListDate(0); + if (downContentList == nullptr) { + downContentList = new UIList(); + } + + listAdapter = new DateAdapter(); + if (listAdapter == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DateView::OnStart::listAdapter is nullptr"); + return; + } + listAdapter->SetItemClickListener(this); + SetDownListAdapter(); + downContentList->SetViewId("downList"); + downContentList->SetPosition(DOWNCONTENTLIST_POSITION_X, DOWNCONTENTLIST_POSITION_Y); + downContentList->Resize(DOWNCONTENTLIST_WIDTH, DOWNCONTENTLIST_HEIGHT); // 364: height + downContentList->SetSelectPosition(DOWNSELECTPOSITION); + downContentList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + downContentList->SetDraggable(true); + downContentList->SetThrowDrag(true); + downContentList->EnableAutoAlign(true); + downContentList->SetElastic(true); + downContentList->ScrollTo(0); + downContentList->SetAdapter(listAdapter); + UpdateMsg(listTop.front().button_viewId); + uiScrollView->Add(downContentList); + uiScrollView->Add(buttonContentList); +} + +int calculateWeekday(int year, int month, int day) +{ + if (month < SET_THREE) { + month += SET_TWELVE; + year--; + } + int K = year % SET_HUNDRED; + int J = year / SET_HUNDRED; + int h = (day + SET_THIRTEEN * (month + SET_ONE) / SET_FIVE + K + K / SET_FOUR + J / SET_FOUR + SET_FIVE * J) % + SET_SEVEN; + return h; +} + +// 刷新List数据 +void DateMainPage::UpdateMsg(std::string dateMsg) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DateView::UpdateMsg:%s", dateMsg.c_str()); + listAdapter->ClearListItem(); // 清空list数据 + DateModel::GetInstance().InitDateVec(dateMsg); + SetDownListAdapter(); // 将设置的数据写入list + int year; + int month; + int day; + int ret = sscanf_s(dateMsg.c_str(), "%d-%d-%d", &year, &month, &day); + if (ret != SET_THREE) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DateMainPage::OnStart strDate"); + return; + } + std::string weekDay[] = {"星期六", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五"}; + int today = calculateWeekday(year, month, day); + std::string titleDay; + if (dateMsg == listTop.front().button_viewId) { + titleDay = "今天 "; + } else { + titleDay = std::to_string(month) + "月 "; + } + titleDay += weekDay[today]; + DateModel::GetInstance().titleName = titleDay; + title->SetText(titleDay.c_str()); + downContentList->ScrollTo(SET_ZERO); + downContentList->RefreshList(); +} + +void DateMainPage::SetDownListAdapter() +{ + for (const auto &item : DateModel::GetInstance().listDate) { + listAdapter->AddListItem(item); + } +} + +void DateMainPage::RefreshButtonListDate(int value) +{ + buttonAdapter->ClearListItem(); + for (auto &item : listTop) { + if (item.index == value) { + item.isSelect = true; + } else { + item.isSelect = false; + } + buttonAdapter->AddListItem(item); + } + buttonContentList->RefreshList(); +} + +bool DateMainPage::InitDateTop() +{ + listTop.clear(); + for (int i = 0; i < SET_SEVEN; ++i) { + strDate[i] = GetFutureDate(i); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DateMainPage::OnStart strDate[%d]:%s", i, strDate[i].c_str()); + strDay[i] = strDate[i].substr(strDate[i].length() - SET_TWO); + if (i == 0) { + listTop.push_back({strDate[i].c_str(), strDay[i].c_str(), i, true, true}); + } else { + listTop.push_back({strDate[i].c_str(), strDay[i].c_str(), i, false, false}); + } + } + return true; +} + +std::string DateMainPage::GetFutureDate(int days_ahead) +{ + time_t now = time(nullptr); + time_t future_time = now + (days_ahead * HOUR_COUNT * NUM_TIME_MIN * NUM_TIME_MIN); + tm *tm = localtime(&future_time); + char buffer[80]; // 存储格式化后的日期字符串 + strftime(buffer, sizeof(buffer), "%Y-%m-%d", tm); + return std::string(buffer); +} + +bool DateMainPage::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + return true; +} + +bool DateMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + int posY = event.GetCurrentPos().y; + if (posY > LIST_POSITION_Y) { + DateItemView *dateItemView = static_cast(&view); + std::string view_id = dateItemView->GetViewId(); + bool visiable = dateItemView->GetVisiable(); + if (visiable) { + return false; + } + DateModel::GetInstance().messageIndex = view_id; + NativeAbility::GetInstance().SwitchPageInSlice(DATE_PAGES::DATE_MESSAGE_PAGE, nullptr, + TransitionType::TRANSITION_INVALID, true); + } else { + DateButtonItemView *dateButtonItemView = static_cast(&view); + DateButtonItem item = dateButtonItemView->GetItem(); + RefreshButtonListDate(item.index); + UpdateMsg(item.button_viewId); + } + UNUSED(event); + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMessagePage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMessagePage.cpp new file mode 100644 index 000000000..277e65596 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateMessagePage.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateMessagePage + * Create: 2025-03-15 + */ + +#include "date/DateMessagePage.h" +#include "date/DateModel.h" +#include "date/DatePresenter.h" +#include "date/DateView.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "UiConfig.h" +#include "common/image_cache_manager.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "ui_resource_date.h" + +namespace OHOS { +static constexpr uint16_t DATE_MONTH_WIDTH = 221; +static constexpr uint16_t DATE_MESSAGE_WIDTH = 180; +static constexpr uint16_t DATE_MESSAGE_HEIGHT = 50; +static constexpr uint16_t DATE_MESSAGE_POSITON_X = 117; +static constexpr uint16_t DATE_MESSAGE_POSITON_Y = 20; +static constexpr uint16_t DATE_MESSAGE_POSITON_X1 = 137; +static constexpr uint16_t DATE_MESSAGE_FRONT_SIZE_ONE = 36; +static constexpr uint16_t DATE_MESSAGE_FRONT_SIZE_TWO = 32; +static constexpr uint16_t DATE_MESSAGE_TWO_POSITION_X = 31; +static constexpr uint16_t DATE_MESSAGE_TWO_POSITION_Y = 100; +static constexpr uint16_t DATE_MESSAGE_TWO_WIDTH = 392; +static constexpr uint16_t DATE_MESSAGE_TWO_HEIGHT = 120; +static constexpr uint16_t DATE_MESSAGE_MAX_LINE_HEIGHT = 140; + +REGIST_SLICE_PAGE(VIEW_DATE, DATE_PAGES::DATE_MESSAGE_PAGE, DateMessagePage, false); + +DateMessagePage::DateMessagePage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DateMessagePage::DateMessagePage"); +} + +DateMessagePage::~DateMessagePage() +{ + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (image1 != nullptr) { + delete image1; + image1 = nullptr; + } + + if (labelTitle != nullptr) { + delete labelTitle; + labelTitle = nullptr; + } + + if (labelMessage != nullptr) { + delete labelMessage; + labelMessage = nullptr; + } + + if (labelTime != nullptr) { + delete labelTime; + labelTime = nullptr; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DateMessagePage::~DateMessagePage"); +} + +void DateMessagePage::OnStart(void *data) +{ + group = new UIViewGroup(); + group->SetPosition(0, 0); + group->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + image1 = new UIImageView; + if (image1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::title is nullptr"); + return; + } + image1->SetPosition(0, 0); + image1->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + ImageInfo *imgSrc = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_DATE8, DATE_IMAGE); + if (imgSrc == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WeatherMainPage::LoadOneInMultiRes fail"); + } + image1->SetSrc(imgSrc); + group->Add(image1); + + labelTitle = new UILabel(); + if (labelTitle == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::title is nullptr"); + return; + } + labelTitle->SetPosition(DATE_MESSAGE_POSITON_X, DATE_MESSAGE_POSITON_Y, DATE_MONTH_WIDTH, DATE_MESSAGE_HEIGHT); + labelTitle->SetStyle(STYLE_TEXT_COLOR, Color::Purple().full); + labelTitle->SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_MESSAGE_FRONT_SIZE_ONE); + labelTitle->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + labelTitle->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + labelTitle->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + group->Add(labelTitle); + + labelMessage = new UILabel(); + if (labelMessage == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::title is nullptr"); + return; + } + labelMessage->SetPosition(DATE_MESSAGE_TWO_POSITION_X, DATE_MESSAGE_TWO_POSITION_Y, DATE_MESSAGE_TWO_WIDTH, + DATE_MESSAGE_TWO_HEIGHT); + labelMessage->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + labelMessage->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + labelMessage->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + labelMessage->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + labelMessage->SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_MESSAGE_FRONT_SIZE_ONE); + labelMessage->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + labelMessage->SetRollSpeed(0); + group->Add(labelMessage); + + labelTime = new UILabel(); + if (labelTime == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::title is nullptr"); + return; + } + labelTime->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + labelTime->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + labelTime->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + labelTime->SetStyle(STYLE_TEXT_COLOR, Color::Gray().full); + labelTime->SetFont(DEFAULT_VECTOR_FONT_FILENAME, DATE_MESSAGE_FRONT_SIZE_TWO); + group->Add(labelTime); + + std::string strTitle = DateModel::GetInstance().titleName; + labelTitle->SetText(strTitle.c_str()); + for (const auto &item : DateModel::GetInstance().listDate) { + std::string strIndex = DateModel::GetInstance().messageIndex; + if (strIndex == item.index) { + labelTime->SetText(item.label_1); + labelMessage->SetText(item.label_2); + } + } + int posTextHeight = labelMessage->GetTextHeight(); + int posHeight = DATE_MESSAGE_TWO_POSITION_Y; + int pos = 0; + if (posTextHeight < DATE_MESSAGE_MAX_LINE_HEIGHT) { + int offsetY = 50; + pos = DATE_MESSAGE_TWO_POSITION_Y + posTextHeight + offsetY; + labelMessage->SetY(DATE_MESSAGE_TWO_POSITION_Y + offsetY); + } else { + pos = DATE_MESSAGE_TWO_POSITION_Y + posTextHeight; + labelMessage->SetY(DATE_MESSAGE_TWO_POSITION_Y); + } + labelMessage->SetHeight(posTextHeight); + labelTime->SetPosition(DATE_MESSAGE_POSITON_X1, pos, DATE_MESSAGE_WIDTH, DATE_MESSAGE_HEIGHT); + group->SetOnDragListener(this); + group->SetDraggable(true); + AddViewToPageContainer(group); +} + +bool DateMessagePage::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DatePresenter::OnDrag ChangeSlice(VIEW_APPLIST)"); + } + return true; +} + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateModel.cpp new file mode 100644 index 000000000..4792289fa --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DateModel.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateModel + * Create: 2025-03-23 + */ + +#include "date/DateModel.h" +#include "date/DatePresenter.h" +#include "phoneservice/PhoneService.h" +#include "ohos_timer.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr int16 DATE_COUNT = 24; +static constexpr int16 DATE_HOUR = 12; + +DateModel::DateModel() {} + +DateModel::~DateModel() {} + +DateModel &DateModel::GetInstance() +{ + static DateModel instance; + return instance; +} + +bool DateModel::InitDateVec(std::string dateStr) +{ + int index = 0; + listDate.clear(); + if (GetBtConnectStatus() != PROFILE_STATE_CONNECTED) { + listDate.push_back({"无日程", "请连接手机,同步日程信息", "0", true}); + } else { + for (const auto &msg : keyValues) { + for (const auto &item : msg.second) { + if (msg.first == dateStr) { + index++; + strIndex = std::to_string(index); + listDate.push_back({item.hour.c_str(), item.eventTitle.c_str(), strIndex.c_str(), false}); + } + } + } + if (listDate.size() == 0) { + listDate.push_back({"无日程", "请前往手机日历创建日程", "0", true}); + } + } + return true; +} + +bool DateModel::InitDate() +{ + keyValues.clear(); + std::ifstream file("/user/app/user/ace/data/com.vendor.Weather/calendar.json"); + if (!file.is_open()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cannot open file"); + return false; + } + std::stringstream buffer; + buffer << file.rdbuf(); + std::string content = buffer.str(); + int intsize = sizeof(content); + cJSON *root = nullptr; + if (intsize != 0) { + root = cJSON_Parse(content.c_str()); + } + if (root == NULL) { + const char *error_ptr; + return false; + } + cJSON *dateSum = cJSON_GetObjectItemCaseSensitive(root, "dateSum"); + if (!cJSON_IsObject(dateSum)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error observe:"); + cJSON_Delete(root); + return false; + } + int sum = std::atoi(cJSON_GetObjectItemCaseSensitive(dateSum, "count")->valuestring); + for (int i = 0; i < sum; i++) { + cJSON *date = cJSON_GetObjectItemCaseSensitive(dateSum, std::to_string(i).c_str()); + if (!cJSON_IsObject(date)) { + cJSON_Delete(root); + continue; + } + std::string hour = cJSON_GetObjectItemCaseSensitive(date, "hour")->valuestring; + std::string eventTitle = cJSON_GetObjectItemCaseSensitive(date, "eventTitle")->valuestring; + std::string startTime = cJSON_GetObjectItemCaseSensitive(date, "startTime")->valuestring; + std::string time = cJSON_GetObjectItemCaseSensitive(date, "time")->valuestring; + std::string week = cJSON_GetObjectItemCaseSensitive(date, "week")->valuestring; + DateMsg item = {hour, eventTitle, startTime, week}; + keyValues[time].push_back(item); + } + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/date/src/DatePresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DatePresenter.cpp new file mode 100644 index 000000000..64ba20fee --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/date/src/DatePresenter.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DatePresenter + * Create: 2025-03-23 + */ + +#include "date/DatePresenter.h" +#include "date/DateModel.h" +#include "date/DateView.h" +#include "NativeRegisterManager.h" +#include "uiservice/ui_service.h" +#include "wearable_log.h" + +namespace OHOS { +REGIST_MENU(VIEW_DATE, DateView, DatePresenter, DATE_MAIN_ICON, DATE_MAIN_ICON, "日程"); +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPage.cpp new file mode 100644 index 000000000..6860eaec8 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPage.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: EmptyPage + * Create: 2025-04-24 + */ + +#include "emptypage/EmptyPage.h" +#include "emptypage/EmptyPresenter.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "wearable_log.h" +#include "AppViewIDs.h" +#include "NativeAbility.h" + +namespace OHOS { +static const uint16_t MEM_LABEL_FONT_SIZE = 40; +static uint32_t EMPTY_PAGE = 1; +REGIST_SLICE_PAGE(VIEW_EMPTY, EMPTY_PAGE, EmptyPage, true); +void EmptyPage::OnStart(void *data) +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + // 设置界面组件回调函数 + container_->SetOnDragListener(this); + container_->SetOnClickListener(this); + } +#if !defined(_WIN32) + test_get_mem_info(1, &used_, &free_); +#endif + // Add Label to App + if (memLabel_ == nullptr) { + memLabel_ = new UILabel(); + } + memLabel_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + std::string memInfo = "Used : " + std::to_string(used_) + "\n" + "Free : " + std::to_string(free_); + memLabel_->SetText(memInfo.c_str()); + memLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + memLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, MEM_LABEL_FONT_SIZE); + container_->Add(memLabel_); + AddViewToPageContainer(container_); +} + +EmptyPage::~EmptyPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "EmptyPage::~EmptyPage"); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (memLabel_ != nullptr) { + delete memLabel_; + memLabel_ = nullptr; + } +} + +bool EmptyPage::OnDrag(UIView &view, const DragEvent &event) +{ + return false; +} + +bool EmptyPage::OnClick(UIView &view, const ClickEvent &event) +{ + return false; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPresenter.cpp new file mode 100644 index 000000000..1a429dfa6 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/emptypage/src/EmptyPresenter.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: EmptyPresenter + * Create: 2025-04-24 + */ + +#include "emptypage/EmptyView.h" +#include "emptypage/EmptyPresenter.h" +#include "NativeRegisterManager.h" + +namespace OHOS { +REGIST_MENU(VIEW_EMPTY, EmptyView, EmptyPresenter, FLASHLIGHT_MAIN_ICON, PNG_APPLIST_DEFAULT_IMG, "空页面"); +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneMainPage.cpp new file mode 100644 index 000000000..54396d287 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneMainPage.cpp @@ -0,0 +1,623 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhoneMainPage + * Create: 2025-03-23 + */ + +#include "phoneservice/PhoneService.h" +#include "UiConfig.h" +#include "bts_spp.h" +#include "common/image_cache_manager.h" +#include "main/LoadImg.h" +#include "ui_resource_findPhone.h" +#include "uiservice/ui_service.h" +#include "ui_test_group.h" +#include "wearable_onlinelog.h" +#include "msg_center_protocol.h" +#include "msg_center_device.h" +#include "findphone/FindPhoneMainPage.h" +#include "findphone/FindPhonePresenter.h" +#include "findphone/FindPhoneView.h" + +static uint8_t data = 0; +namespace OHOS { + +static FindPhoneMainPage *g_pFindPhoneMainPage = nullptr; +static constexpr uint16_t FIND_PHONE_IMAGE_WIDTH = 500; +static constexpr uint16_t FIND_PHONE_IMAGE_HEIGHT = 500; +static constexpr uint16_t FIND_PHONE_BUTTON_POSITION_X = 154; +static constexpr uint16_t FIND_PHONE_BUTTON_POSITION_Y = 154; +static constexpr uint16_t FIND_PHONE_BUTTON_WIDTH = 146; +static constexpr uint16_t FIND_PHONE_BUTTON_HEIGHT = 146; +static constexpr uint16_t FIND_PHONE_RTYBUTTON_POSITION_X = 179; +static constexpr uint16_t FIND_PHONE_RTYBUTTON_POSITION_Y = 289; +static constexpr uint16_t FIND_PHONE_RTYBUTTON = 96; +static constexpr uint16_t FIND_PHONE_SIZE = 466; +static constexpr uint16_t FIND_PHONE_IMAGEANIMATOR_POSITION_X = 170; +static constexpr uint16_t FIND_PHONE_IMAGEANIMATOR_POSITION_Y = 170; +static constexpr uint16_t FIND_PHONE_IMAGEANIMATOR_WIDTH = 100; +static constexpr uint16_t FIND_PHONE_IMAGEANIMATOR_HEIGHT = 100; +static constexpr uint16_t FONT_DEFAULT_SIZE_1 = 36; +static constexpr uint16_t FONT_DEFAULT_SIZE_2 = 38; +static constexpr uint16_t FIND_PHONE_INITIAL = 0; +static constexpr uint16_t FIND_PHONE_TITLDE_X = 140; +static constexpr uint16_t FIND_PHONE_TITLDE_Y = 345; +static constexpr uint16_t FIND_PHONE_TITLDE_WIDTH = 314; +static constexpr uint16_t FIND_PHONE_FINDTITLE_X = 150; +static constexpr uint16_t FIND_PHONE_FINDTITLE_Y = 31; +static constexpr uint16_t FIND_PHONE_FINDTITLE_WIDTH = 253; +static constexpr uint16_t FIND_PHONE_FINDTITLE_HEIGHT = 53; +static constexpr uint16_t FIND_PHONE_RINGING_X = 200; +static constexpr uint16_t FIND_PHONE_RINGING2_X = 156; +static constexpr uint16_t FIND_PHONE_RINGING_Y = 353; +static constexpr uint16_t FIND_PHONE_RINGING_WIDTH = 93; +static constexpr uint16_t FIND_PHONE_RINGING2_WIDTH = 144; +static constexpr uint16_t FIND_PHONE_RINGING_HEIGHT = 42; +static constexpr uint16_t FIND_PHONE_SEARCHTIMEOUT_X = 50; +static constexpr uint16_t FIND_PHONE_SEARCHTIMEOUT_Y = 185; +static constexpr uint16_t FIND_PHONE_SEARCHTIMEOUT_WIDTH = 424; +static constexpr uint16_t FIND_PHONE_SEARCHTIMEOUT_HEIGHT = 50; +static constexpr uint16_t FIND_PHONE_DURATION_TIME = 60; +static constexpr uint16_t IMAGE_SIZE = 500; +static constexpr uint16_t IMAGEANIMATOERVIEW_SIZE = 28; +static constexpr uint16_t IMAGEANIMATOERVIEW_TIME = 60; +static constexpr uint16_t FIND_PHONE_IMAGE_X = 5; +static constexpr uint16_t FIND_PHONE_IMAGE_y = 1; +static constexpr uint16_t FIND_PHONE_PIXELBYTE_SIZE = 4; +static constexpr uint16_t FIND_PHONE_PIXELBYTEH = 100; + +REGIST_SLICE_PAGE(VIEW_FIND_PHONE, FIND_PHONE_PAGES::FIND_PHONE_MAIN_PAGE, FindPhoneMainPage, true); + +const int g_imageAnimatorInfo[IMAGEANIMATOERVIEW_SIZE] = { + IMAGE_CONVERTER_TOOL_FINDPHONE001, IMAGE_CONVERTER_TOOL_FINDPHONE002, IMAGE_CONVERTER_TOOL_FINDPHONE003, + IMAGE_CONVERTER_TOOL_FINDPHONE004, IMAGE_CONVERTER_TOOL_FINDPHONE005, IMAGE_CONVERTER_TOOL_FINDPHONE006, + IMAGE_CONVERTER_TOOL_FINDPHONE007, IMAGE_CONVERTER_TOOL_FINDPHONE008, IMAGE_CONVERTER_TOOL_FINDPHONE009, + IMAGE_CONVERTER_TOOL_FINDPHONE010, IMAGE_CONVERTER_TOOL_FINDPHONE011, IMAGE_CONVERTER_TOOL_FINDPHONE012, + IMAGE_CONVERTER_TOOL_FINDPHONE013, IMAGE_CONVERTER_TOOL_FINDPHONE014, IMAGE_CONVERTER_TOOL_FINDPHONE015, + IMAGE_CONVERTER_TOOL_FINDPHONE016, IMAGE_CONVERTER_TOOL_FINDPHONE017, IMAGE_CONVERTER_TOOL_FINDPHONE018, + IMAGE_CONVERTER_TOOL_FINDPHONE019, IMAGE_CONVERTER_TOOL_FINDPHONE020, IMAGE_CONVERTER_TOOL_FINDPHONE021, + IMAGE_CONVERTER_TOOL_FINDPHONE022, IMAGE_CONVERTER_TOOL_FINDPHONE023, IMAGE_CONVERTER_TOOL_FINDPHONE024, + IMAGE_CONVERTER_TOOL_FINDPHONE025, IMAGE_CONVERTER_TOOL_FINDPHONE026, IMAGE_CONVERTER_TOOL_FINDPHONE027, + IMAGE_CONVERTER_TOOL_FINDPHONE028, +}; + +FindPhoneMainPage::FindPhoneMainPage() +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::FindPhoneMainPage"); + g_pFindPhoneMainPage = this; +} + +FindPhoneMainPage::~FindPhoneMainPage() +{ + g_pFindPhoneMainPage = nullptr; + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + + if (buttonFind != nullptr) { + delete buttonFind; + buttonFind = nullptr; + } + + if (mainImage != nullptr) { + delete mainImage; + mainImage = nullptr; + } + + if (labelUnder != nullptr) { + delete labelUnder; + labelUnder = nullptr; + } + + if (labelFindTitle != nullptr) { + delete labelFindTitle; + labelFindTitle = nullptr; + } + + if (labelRing != nullptr) { + delete labelRing; + labelRing = nullptr; + } + + if (buttonRty != nullptr) { + delete buttonRty; + buttonRty = nullptr; + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::~FindPhoneMainPage"); +} + +FindPhoneMainPage *FindPhoneMainPage::GetInstance() +{ + return g_pFindPhoneMainPage; +} + +void FindPhoneMainPage::OnStop() +{ + if (imageAnimator_->GetState() == true) { + DisableFindPhoneTimer(); +#ifndef _WIN32 + errcode_t result = + uapi_diag_service_send_log(msg_center_get_trans_channel(), MSGCENTER_TYPE_ID_OFF_FIND_PHONE, nullptr, 0); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnStop::uapi_diag_service_send_log OFF result:%d ", result); +#endif + ImageCacheManager::GetInstance().UnloadAllInMultiRes(FINDPHONE_IMAGE); + } + data = 0; +} + +void FindPhoneMainPage::OnStart(void *data) +{ + if (container_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new container_ fail"); + container_ = new UIViewGroup(); + container_->SetPosition(FIND_PHONE_INITIAL, FIND_PHONE_INITIAL, FIND_PHONE_SIZE, FIND_PHONE_SIZE); + container_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + } + container_->SetTouchable(true); + container_->SetDraggable(true); + container_->SetOnDragListener(this); + + if (mainImage == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new mainImage fail"); + mainImage = new UIImageView(); + } + mainImage->SetPosition(FIND_PHONE_INITIAL, FIND_PHONE_INITIAL); + LOADIMG::LoadImageViewImg(mainImage, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_2); + container_->Add(mainImage); + + SetUpImageAnimator(); + SetupButton(); + + labelUnder = new UILabel(); + if (labelUnder == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new labelUnder fail"); + return; + } + labelUnder->SetText("蓝牙已断开"); + labelUnder->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE_1); + labelUnder->SetPosition(FIND_PHONE_TITLDE_X, FIND_PHONE_TITLDE_Y, FIND_PHONE_TITLDE_WIDTH, + FIND_PHONE_IMAGEANIMATOR_HEIGHT); + container_->Add(labelUnder); + labelFindTitle = new UILabel(); + if (labelFindTitle == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new labelFindTitle fail"); + return; + } + labelFindTitle->SetText("查找手机"); + labelFindTitle->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE_2); + labelFindTitle->SetPosition(FIND_PHONE_FINDTITLE_X, FIND_PHONE_FINDTITLE_Y, FIND_PHONE_FINDTITLE_WIDTH, + FIND_PHONE_FINDTITLE_HEIGHT); + container_->Add(labelFindTitle); + + labelRing = new UILabel(); + if (labelRing == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new labelRing fail"); + return; + } + labelRing->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE_1); + container_->Add(labelRing); + if (GetConnectStatus() == 1) { + labelRing->SetVisible(true); + labelUnder->SetVisible(false); + LOADIMG::LoadBtnImage(buttonFind, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5); + buttonFind->Enable(); + } else { + LOADIMG::LoadBtnImage(buttonFind, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_4, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_4); + buttonFind->Disable(); + labelUnder->SetVisible(true); + labelRing->SetVisible(false); + } + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); + AddViewToPageContainer(container_); +} + +void FindPhoneMainPage::SetUpImageAnimator() +{ + imageAnimator_ = new UIImageAnimatorView(); + if (imageAnimator_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "FindPhoneMainPage::UIImageAnimatorView new Label SetUpImageAnimator fail"); + return; + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::SetUpImageAnimator "); + imageAnimator_ = new UIImageAnimatorView(); + for (data; data < IMAGEANIMATOERVIEW_SIZE; data++) { + searchImageInfo[data].imageInfo = + ImageCacheManager::GetInstance().LoadOneInMultiRes(g_imageAnimatorInfo[data], FINDPHONE_IMAGE); + ; + searchImageInfo[data].imageType = IMG_SRC_IMAGE_INFO; + searchImageInfo[data].pos.x = FIND_PHONE_IMAGE_X; + searchImageInfo[data].pos.y = FIND_PHONE_IMAGE_y; + searchImageInfo[data].width = IMAGE_SIZE; + searchImageInfo[data].height = IMAGE_SIZE; + } + imageAnimator_->SetPosition(FIND_PHONE_IMAGE_X, FIND_PHONE_IMAGE_y, FIND_PHONE_IMAGE_WIDTH, + FIND_PHONE_IMAGE_HEIGHT); // 50 : offset 50 : offset 200 : offset 200: offset + int imageNumber = IMAGEANIMATOERVIEW_SIZE; + int ImageUpdate = IMAGEANIMATOERVIEW_TIME; + imageAnimator_->SetImageAnimatorSrc(searchImageInfo, imageNumber, + ImageUpdate); // 4: the number of images, 100: updating time + imageAnimator_->Stop(); + imageAnimator_->LayoutCenterOfParent(); + imageAnimator_->SetDraggable(true); + imageAnimator_->SetOnDragListener(this); + container_->Add(imageAnimator_); + InitImageInfo(); +} + +void FindPhoneMainPage::SetupButton() +{ + // Add Button to App + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::SetupButton new Label"); + if (buttonFind == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new buttonFind fail"); + buttonFind = new UIButton(); + } + buttonFind->SetPosition(FIND_PHONE_BUTTON_POSITION_X, FIND_PHONE_BUTTON_POSITION_Y); + buttonFind->Resize(FIND_PHONE_BUTTON_WIDTH, FIND_PHONE_BUTTON_HEIGHT); + buttonFind->SetViewId("button1"); + buttonFind->SetOnClickListener(this); + buttonFind->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + buttonFind->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + buttonFind->SetVisible(true); + LOADIMG::LoadBtnImage(buttonFind, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5); + if (buttonRty == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new buttonRty fail"); + buttonRty = new UIButton(); + } + buttonRty->SetPosition(FIND_PHONE_RTYBUTTON_POSITION_X, FIND_PHONE_RTYBUTTON_POSITION_Y); + buttonRty->Resize(FIND_PHONE_RTYBUTTON, FIND_PHONE_RTYBUTTON); + buttonRty->SetViewId("buttonRty"); + buttonRty->SetOnClickListener(this); + buttonRty->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + buttonRty->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + LOADIMG::LoadBtnImage(buttonRty, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_7, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_7); + buttonRty->SetVisible(false); + // Add to rootView + container_->Add(buttonRty); + container_->Add(buttonFind); +} + +bool FindPhoneMainPage::ClickButtonChange() +{ +#ifndef _WIN32 + errcode_t result; + if (imageAnimator_->GetState() == true) { + // 关闭定时器 + result = + uapi_diag_service_send_log(msg_center_get_trans_channel(), MSGCENTER_TYPE_ID_OFF_FIND_PHONE, nullptr, 0); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_diag_service_send_log OFF result:%d ", result); + if (result == 0) { + DisableFindPhoneTimer(); + LOADIMG::LoadBtnImage(buttonFind, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5); + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); + buttonFind->SetOpaScale(OPA_OPAQUE); + mainImage->SetVisible(true); + labelRing->SetText("响铃"); + labelRing->SetPosition(FIND_PHONE_RINGING_X, FIND_PHONE_RINGING_Y, FIND_PHONE_RINGING_WIDTH, + FIND_PHONE_RINGING_HEIGHT); + return true; + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OFF send to phone fail:%d ", result); + return false; + } + } else { + // 开启定时器 + result = + uapi_diag_service_send_log(msg_center_get_trans_channel(), MSGCENTER_TYPE_ID_ON_FIND_PHONE, nullptr, 0); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_diag_service_send_log ON result:%d ", result); + if (result == 0) { + InitFindPhoneTimer(); + g_startCount->Start(); + imageAnimator_->Start(); + imageAnimator_->SetVisible(true); + buttonFind->SetOpaScale(OPA_TRANSPARENT); + mainImage->SetVisible(false); + labelRing->SetText("停止响铃"); + labelRing->SetPosition(FIND_PHONE_RINGING2_X, FIND_PHONE_RINGING_Y, FIND_PHONE_RINGING2_WIDTH, + FIND_PHONE_RINGING_HEIGHT); + return true; + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ON send to phone fail:%d ", result); + return false; + } + } +#endif + return true; +} + +void FindPhoneMainPage::ShowReset() +{ + // rtybutton、title显示,findTitle、button隐藏,imageAnimator停止 + labelUnder->SetText("查找手机超时,请重试"); + labelUnder->SetPosition(FIND_PHONE_SEARCHTIMEOUT_X, FIND_PHONE_SEARCHTIMEOUT_Y, FIND_PHONE_SEARCHTIMEOUT_WIDTH, + FIND_PHONE_SEARCHTIMEOUT_HEIGHT); + labelUnder->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE_1); + labelUnder->SetVisible(true); + buttonRty->SetVisible(true); + labelFindTitle->SetVisible(false); + labelRing->SetVisible(false); + buttonFind->SetVisible(false); + mainImage->SetVisible(false); + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); + DisableFindPhoneTimer(); +} + +bool FindPhoneMainPage::StopFindPhone() +{ +#ifndef _WIN32 + errcode_t result; + if (imageAnimator_->GetState() == true) { + // 关闭定时器 + result = + uapi_diag_service_send_log(msg_center_get_trans_channel(), MSGCENTER_TYPE_ID_OFF_FIND_PHONE, nullptr, 0); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_diag_service_send_log OFF result:%d ", result); + if (result == 0) { + DisableFindPhoneTimer(); + LOADIMG::LoadBtnImage(buttonFind, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_5); + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); + buttonFind->SetOpaScale(OPA_OPAQUE); + mainImage->SetVisible(true); + labelRing->SetText("响铃"); + labelRing->SetPosition(FIND_PHONE_RINGING_X, FIND_PHONE_RINGING_Y, FIND_PHONE_RINGING_WIDTH, + FIND_PHONE_RINGING_HEIGHT); + return true; + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OFF send to phone fail:%d ", result); + return false; + } + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::imageAnimator is stop"); + } +#endif + return true; +} + +bool FindPhoneMainPage::OnClick(UIView &view, const ClickEvent &event) +{ +#ifndef _WIN32 + UNUSED(event); + if (view.GetViewId() == "buttonRty") { + // rtybutton、title隐藏,findTitle、button显示,imageAnimator播放 + InitFindPhoneTimer(); + static uint8_t buffer[1024] = {16}; + errcode_t result = + uapi_diag_service_send_log(msg_center_get_trans_channel(), MSGCENTER_TYPE_ID_ON_FIND_PHONE, buffer, 16); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_diag_service_send_log ON result:%d ", result); + if (result == 0) { + buttonRty->SetVisible(false); + labelUnder->SetVisible(false); + mainImage->SetVisible(false); + buttonFind->SetVisible(true); + labelFindTitle->SetVisible(true); + imageAnimator_->Start(); + imageAnimator_->SetVisible(true); + buttonFind->SetOpaScale(OPA_TRANSPARENT); + labelRing->SetVisible(true); + labelRing->SetText("停止响铃"); + labelRing->SetPosition(FIND_PHONE_RINGING2_X, FIND_PHONE_RINGING_Y, FIND_PHONE_RINGING2_WIDTH, + FIND_PHONE_RINGING_HEIGHT); + return true; + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "try send to phone fail:%d ", result); + return false; + } + } else { + ClickButtonChange(); + } +#endif + return true; +} + +bool FindPhoneMainPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "FindPhonePresenter::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FindPhoneOnDragListener::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + return false; +} + +uint8_t FindPhoneMainPage::GetConnectStatus() +{ + uint8_t conn_status = 0; +#ifndef _WIN32 + if (msg_center_get_trans_channel() == DIAG_FRAME_FID_PHONE) { + conn_status = is_spp_connected(0) == true ? 1 : 0; + } else if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) { + conn_status = msg_center_get_ble_conn_state(); + } +#endif + return conn_status; +} + +void FindPhoneMainPage::ChangeToDisConnect() +{ + LOADIMG::LoadBtnImage(buttonFind, FINDPHONE_IMAGE, IMAGE_CONVERTER_TOOL_CONNECT_PHONE_4, + IMAGE_CONVERTER_TOOL_CONNECT_PHONE_4); + imageAnimator_->Stop(); + imageAnimator_->SetVisible(false); + buttonFind->SetOpaScale(OPA_OPAQUE); + buttonFind->Disable(); + labelFindTitle->SetVisible(false); + labelUnder->SetVisible(true); + labelRing->SetVisible(false); +} + +/* 定时器回调函数 */ +void FindPhoneTimerCallback(void *data) +{ + (void)data; + timeCount++; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::timeCount:%d", timeCount); + if (timeCount == FIND_PHONE_DURATION_TIME) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Searching for phone timed out!!"); + FindPhoneMainPage::GetInstance()->ShowReset(); + timeCount = 0; + } + if (FindPhoneMainPage::GetInstance()->GetConnectStatus() != 1) { + FindPhoneMainPage::GetInstance()->ChangeToDisConnect(); + } +} + +/* 开启定时器 */ +void FindPhoneMainPage::InitFindPhoneTimer() +{ + if (g_startCount != nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage already exists!!"); + return; + } + uint32 tick = GetOSTick(MS_ONE_SECONDS); + g_startCount = new GraphicTimer(tick, FindPhoneTimerCallback, nullptr, true); + if (g_startCount == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage new GraphicTimer failed!!"); + return; + } + bool retTimer = g_startCount->Start(); + if (!retTimer) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage osTimerStart failed!!"); + if (g_startCount != nullptr) { + delete g_startCount; + g_startCount = nullptr; + } + return; + } +} + +/* 关闭定时器 */ +void FindPhoneMainPage::DisableFindPhoneTimer() +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "CameraModel::DisableFindPhoneTimer!!"); + if (g_startCount != nullptr) { + g_startCount->Stop(); + delete g_startCount; + g_startCount = nullptr; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CameraModel::DisableFindPhoneTimer delete g_startCount!!"); + } + timeCount = 0; +} + +void FindPhoneMainPage::InitImageInfo() +{ + const uint16_t pixelByteSize = FIND_PHONE_PIXELBYTE_SIZE; // 4: bytes per pixel + const uint16_t width = FIND_PHONE_PIXELBYTEH; // 100: image's width + const uint16_t height = FIND_PHONE_PIXELBYTEH; // 100: image's height + uint32_t dataSize = width * height * pixelByteSize; + uint8_t *srcData1 = static_cast(UIMalloc(dataSize)); + if (srcData1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::srcData1 fail"); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData1[i] = SET_INT_MAX; // 255: pixel value + srcData1[i + 1] = 0; // 1: set green channel + srcData1[i + SET_TWO] = 0; // 2: set red channel + srcData1[i + SET_THREE] = OPA_OPAQUE; // 3: set alpha channel + } + imageInfo1_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo1_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new imageInfo1_ fail"); + UIFree(srcData1); + return; + } + + imageInfo1_->header.width = width; + imageInfo1_->header.height = height; + imageInfo1_->header.colorMode = ColorMode::ARGB8888; + imageInfo1_->dataSize = dataSize; + imageInfo1_->data = srcData1; + + uint8_t *srcData2 = static_cast(UIMalloc(dataSize)); + if (srcData2 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::srcData2 fail"); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData2[i] = 0; // set blue channel + srcData2[i + 1] = SET_INT_MAX; // 1: set green channel 255: pixel value + srcData2[i + SET_TWO] = 0; // 2: set red channel + srcData2[i + SET_THREE] = OPA_OPAQUE; // 3: set alpha channel + } + + imageInfo2_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo2_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new imageInfo2_ fail"); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + imageInfo2_->header.width = width; + imageInfo2_->header.height = height; + imageInfo2_->header.colorMode = ARGB8888; + imageInfo2_->dataSize = dataSize; + imageInfo2_->data = srcData2; + + uint8_t *srcData3 = static_cast(UIMalloc(dataSize)); + if (srcData3 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::srcData3 fail"); + UIFree(imageInfo2_); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData3[i] = 0; // set blue channel + srcData3[i + 1] = 0; // 1: set green channel + srcData3[i + SET_TWO] = SET_INT_MAX; // 2: set red channel 255: pixel value + srcData3[i + SET_THREE] = OPA_OPAQUE; // 3: set alpha channel + } + + imageInfo3_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo3_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FindPhoneMainPage::new imageInfo3_ fail"); + UIFree(srcData3); + UIFree(imageInfo2_); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + imageInfo3_->header.width = width; + imageInfo3_->header.height = height; + imageInfo3_->header.colorMode = ARGB8888; + imageInfo3_->dataSize = dataSize; + imageInfo3_->data = srcData3; + + imageAnimatorImageInfo_[0].imageInfo = imageInfo1_; + imageAnimatorImageInfo_[0].pos = {FIND_PHONE_IMAGEANIMATOR_POSITION_X, FIND_PHONE_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo_[0].width = FIND_PHONE_IMAGEANIMATOR_WIDTH; // 100: width value + imageAnimatorImageInfo_[0].height = FIND_PHONE_IMAGEANIMATOR_HEIGHT; // 100: height value + imageAnimatorImageInfo_[0].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo_[1].imageInfo = imageInfo2_; + imageAnimatorImageInfo_[1].pos = {FIND_PHONE_IMAGEANIMATOR_POSITION_X, FIND_PHONE_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo_[1].width = FIND_PHONE_IMAGEANIMATOR_WIDTH; // 100: width value + imageAnimatorImageInfo_[1].height = FIND_PHONE_IMAGEANIMATOR_HEIGHT; // 100: height value + imageAnimatorImageInfo_[1].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo_[SET_TWO].imageInfo = imageInfo3_; // 2: image index + imageAnimatorImageInfo_[SET_TWO].pos = {FIND_PHONE_IMAGEANIMATOR_POSITION_X, FIND_PHONE_IMAGEANIMATOR_POSITION_Y}; + imageAnimatorImageInfo_[SET_TWO].width = FIND_PHONE_IMAGEANIMATOR_WIDTH; // 2: image index, 100: width value + imageAnimatorImageInfo_[SET_TWO].height = FIND_PHONE_IMAGEANIMATOR_HEIGHT; // 2: image index, 100: height value + imageAnimatorImageInfo_[SET_TWO].imageType = IMG_SRC_IMAGE_INFO; // 2: image index +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneModel.cpp new file mode 100644 index 000000000..c4784a692 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhoneModel.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhoneModel + * Create: 2025-03-23 + */ + +#include "ohos_timer.h" +#include "wearable_log.h" +#include "findphone/FindPhoneModel.h" +#include "findphone/FindPhoneView.h" + +namespace OHOS { +static constexpr uint64_t CENTI_SECOND_UNIT = 100; +static constexpr uint64_t MS_ONE_SECONDS = 1000; +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t NUM_TIME_MIN = 60; +static constexpr uint16_t NUM_TIME_HOUR = 3600; +static constexpr int32_t NUM_TIME_DAY = 86400; +static constexpr int16_t MIN_TO_HOUR = 60; +static constexpr int16_t HOURLY_SYSTEM = 24; +FindPhoneModel::FindPhoneModel() {} + +FindPhoneModel::~FindPhoneModel() {} + +FindPhoneModel &FindPhoneModel::GetInstance() +{ + static FindPhoneModel instance; + return instance; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhonePresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhonePresenter.cpp new file mode 100644 index 000000000..96f909c52 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/findphone/src/FindPhonePresenter.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhonePresenter + * Create: 2025-03-23 + */ + +#include "NativeRegisterManager.h" +#include "uiservice/ui_service.h" +#include "findphone/FindPhonePresenter.h" +#include "findphone/FindPhoneModel.h" +#include "findphone/FindPhoneView.h" + +namespace OHOS { +REGIST_MENU(VIEW_FIND_PHONE, FindPhoneView, FindPhonePresenter, FINDPHONE_MAIN_ICON, FINDPHONE_MAIN_ICON, "查找手机"); +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightBlinkPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightBlinkPage.cpp new file mode 100644 index 000000000..521673522 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightBlinkPage.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightBlinkPage + * Create: 2025-04-24 + */ + +#include "flashlight/FlashLightBlinkPage.h" +#include "flashlight/FlashLightPresenter.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "flashlight/FlashLightModel.h" +#include "main/LoadImg.h" +#include "flashlight/FlashlightUiResourceImage.h" +namespace OHOS { +static const uint16_t BLINK_PICKER_POS_X = 106; +static const uint16_t BLINK_PICKER_POS_Y = 113; +static const uint16_t BLINK_PICKER_WIDTH = 254; +static const uint16_t BLINK_PICKER_HEIGHT = 218; +static const uint16_t BLINK_PICKER_BACKGROUND_FONT_SIZE = 38; +static const uint16_t BLINK_PICKER_HIGHLIGHT_FONT_SIZE = 44; +static const uint16_t BLINK_PICKER_ITEM_HEIGHT = 73; +static const uint16_t BLINK_PICKER_NUM = 3; +static const uint16_t BLINK_BUTTON_POS_X = 59; +static const uint16_t BLINK_BUTTON_POS_Y = 358; +static const uint16_t BLINK_BUTTON_WIDTH = 337; +static const uint16_t BLINK_BUTTON_HEIGHT = 96; +static const uint16_t BLINK_TEXT_POS_X = 100; +static const uint16_t BLINK_TEXT_POS_Y = 38; +static const uint16_t BLINK_TEXT_WIDTH = 253; +static const uint16_t BLINK_TEXT_HEIGHT = 53; +static const uint16_t BLINK_TEXT_FONT_SIZE = 38; +static const std::string START_BLINK_BUTTON_ID = "startBlink"; + +REGIST_SLICE_PAGE(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_BLINK_VIEW, FlashLightBlinkPage, false); +void FlashLightBlinkPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightBlinkPage::OnStart"); + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + container_->SetStyle(STYLE_BACKGROUND_OPA, 0); + } + + if (blinkLabel_ == nullptr) { + blinkLabel_ = new UILabel(); + } + blinkLabel_->SetPosition(BLINK_TEXT_POS_X, BLINK_TEXT_POS_Y, BLINK_TEXT_WIDTH, BLINK_TEXT_HEIGHT); + blinkLabel_->SetText("闪烁频率"); + blinkLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + blinkLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + blinkLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BLINK_TEXT_FONT_SIZE); + container_->Add(blinkLabel_); + blinkLabel_->SetVisible(true); + + // Add Picker to App + if (blinkPicker_ == nullptr) { + blinkPicker_ = new UIPicker(); + } + blinkPicker_->SetPosition(BLINK_PICKER_POS_X, BLINK_PICKER_POS_Y, BLINK_PICKER_WIDTH, BLINK_PICKER_HEIGHT); + blinkPicker_->SetViewId("uiPicker1"); + blinkPicker_->SetBackgroundFont(DEFAULT_VECTOR_FONT_FILENAME, BLINK_PICKER_BACKGROUND_FONT_SIZE); + blinkPicker_->SetHighlightFont(DEFAULT_VECTOR_FONT_FILENAME, BLINK_PICKER_HIGHLIGHT_FONT_SIZE); + const char *uiPicker1Data[] = {"慢", "å¿«", "不闪烁"}; + blinkPicker_->SetValues(uiPicker1Data, BLINK_PICKER_NUM); + uint16_t selectBlink = FlashLightModel::GetInstance().GetBlinkFrequency(); + blinkPicker_->SetSelected(selectBlink); + blinkPicker_->SetTextColor(Color::Gray(), Color::White()); + blinkPicker_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + blinkPicker_->SetItemHeight(BLINK_PICKER_ITEM_HEIGHT); + container_->Add(blinkPicker_); + blinkPicker_->SetVisible(true); + + // Add LabelButtonExt to App + if (blinkButton_ == nullptr) { + blinkButton_ = new UILabelButtonExt(); + } + blinkButton_->SetPosition(BLINK_BUTTON_POS_X, BLINK_BUTTON_POS_Y, BLINK_BUTTON_WIDTH, BLINK_BUTTON_HEIGHT); + blinkButton_->SetViewId(START_BLINK_BUTTON_ID.c_str()); + LOADIMG::LoadBtnImage(blinkButton_, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_BLINKBUTTON, + IMAGE_CONVERTER_TOOL_BLINKBUTTON); + blinkButton_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + blinkButton_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + container_->Add(blinkButton_); + blinkButton_->SetVisible(true); + + blinkButton_->SetOnClickListener(this); + container_->SetOnDragListener(this); + AddViewToPageContainer(container_); +} + +FlashLightBlinkPage::~FlashLightBlinkPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightBlinkPage::~FlashLightBlinkPage"); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (blinkLabel_ != nullptr) { + delete blinkLabel_; + blinkLabel_ = nullptr; + } + if (blinkPicker_ != nullptr) { + delete blinkPicker_; + blinkPicker_ = nullptr; + } + if (blinkButton_ != nullptr) { + delete blinkButton_; + blinkButton_ = nullptr; + } + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +bool FlashLightBlinkPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightBlinkPage::OnDrag"); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_SET_VIEW); + } + return false; +} + +bool FlashLightBlinkPage::OnClick(UIView &view, const ClickEvent &event) +{ + std::string viewId = view.GetViewId(); + uint16_t itemIndex = blinkPicker_->GetSelected(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightBlinkPage::OnClick [%s], itemIndex : [%d] ", viewId.c_str(), + itemIndex); + if (viewId == START_BLINK_BUTTON_ID) { + FlashLightModel::GetInstance().SetBlinkFrequency((FlashLightBlinkFrequency)itemIndex); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightBlinkPage::OnClick [Invalid]"); + } + return false; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightColorPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightColorPage.cpp new file mode 100644 index 000000000..20ae1c068 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightColorPage.cpp @@ -0,0 +1,330 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightColorPage + * Create: 2025-04-24 + */ + +#include "flashlight/FlashLightColorPage.h" +#include "flashlight/FlashLightPresenter.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "flashlight/FlashLightModel.h" +#include "main/LoadImg.h" +#include "flashlight/FlashlightUiResourceImage.h" +namespace OHOS { +static const uint16_t COLOR_LABEL_POS_X = 100; +static const uint16_t COLOR_LABEL_POS_Y = 38; +static const uint16_t COLOR_LABEL_WIDTH = 253; +static const uint16_t COLOR_LABEL_HEIGHT = 53; +static const uint16_t COLOR_LABEL_FONT_SIZE = 38; +static const uint16_t CONTAINER_BLANK_SIZE = 100; +// 行坐标 +const uint16_t FIRST_ROW_COLOR_BUTTON_POS_Y = 104; +const uint16_t SECOND_ROW_COLOR_BUTTON_POS_Y = 225; +const uint16_t THIRD_ROW_COLOR_BUTTON_POS_Y = 346; +// 列坐标 +const uint16_t FIRST_COLUMN_COLOR_BUTTON_POS_X = 46; +const uint16_t SECOND_COLUMN_COLOR_BUTTON_POS_X = 169; +const uint16_t THIRD_COLUMN_COLOR_BUTTON_POS_X = 290; +// 按钮大小 +const uint16_t COLOR_BUTTON_WIDTH = 117; +const uint16_t COLOR_BUTTON_HEIGHT = 117; +static const uint32_t SELECT_COLOR_BUTTON_RES[10] = { + 0, + IMAGE_CONVERTER_TOOL_COLOR1PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR2PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR3PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR4PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR5PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR6PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR7PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR8PRESSBUTTON, + IMAGE_CONVERTER_TOOL_COLOR9PRESSBUTTON, +}; +static const std::string COLOR1_BUTTON_ID = "color1Button"; +static const std::string COLOR2_BUTTON_ID = "color2Button"; +static const std::string COLOR3_BUTTON_ID = "color3Button"; +static const std::string COLOR4_BUTTON_ID = "color4Button"; +static const std::string COLOR5_BUTTON_ID = "color5Button"; +static const std::string COLOR6_BUTTON_ID = "color6Button"; +static const std::string COLOR7_BUTTON_ID = "color7Button"; +static const std::string COLOR8_BUTTON_ID = "color8Button"; +static const std::string COLOR9_BUTTON_ID = "color9Button"; +REGIST_SLICE_PAGE(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_COLOR_VIEW, FlashLightColorPage, false); +void FlashLightColorPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnStart"); + uint32_t COLOR_BUTTON_RES[10] = { + 0, + IMAGE_CONVERTER_TOOL_COLOR1BUTTON, + IMAGE_CONVERTER_TOOL_COLOR2BUTTON, + IMAGE_CONVERTER_TOOL_COLOR3BUTTON, + IMAGE_CONVERTER_TOOL_COLOR4BUTTON, + IMAGE_CONVERTER_TOOL_COLOR5BUTTON, + IMAGE_CONVERTER_TOOL_COLOR6BUTTON, + IMAGE_CONVERTER_TOOL_COLOR7BUTTON, + IMAGE_CONVERTER_TOOL_COLOR8BUTTON, + IMAGE_CONVERTER_TOOL_COLOR9BUTTON, + }; + uint16_t selectColor = (uint16_t)FlashLightModel::GetInstance().GetViewColor(); + COLOR_BUTTON_RES[selectColor] = SELECT_COLOR_BUTTON_RES[selectColor]; + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + container_->SetStyle(STYLE_BACKGROUND_OPA, 0); + container_->SetScrollBlankSize(CONTAINER_BLANK_SIZE, UIAbstractScroll::Direction::TOP); + container_->SetScrollBlankSize(CONTAINER_BLANK_SIZE, UIAbstractScroll::Direction::BOTTOM); + } + + if (colorLabel_ == nullptr) { + colorLabel_ = new UILabel(); + } + colorLabel_->SetPosition(COLOR_LABEL_POS_X, COLOR_LABEL_POS_Y, COLOR_LABEL_WIDTH, COLOR_LABEL_HEIGHT); + colorLabel_->SetText("灯光颜色"); + colorLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + colorLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + colorLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, COLOR_LABEL_FONT_SIZE); + container_->Add(colorLabel_); + colorLabel_->SetVisible(true); + // 第一行颜色按钮 + if (color1Button_ == nullptr) { + color1Button_ = new UILabelButtonExt(); + } + color1Button_->SetPosition(FIRST_COLUMN_COLOR_BUTTON_POS_X, FIRST_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color1Button_->SetViewId(COLOR1_BUTTON_ID.c_str()); + color1Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color1Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color1Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color1Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[WHITE_COLOR], COLOR_BUTTON_RES[WHITE_COLOR]); + container_->Add(color1Button_); + color1Button_->SetVisible(true); + + if (color2Button_ == nullptr) { + color2Button_ = new UILabelButtonExt(); + } + color2Button_->SetPosition(SECOND_COLUMN_COLOR_BUTTON_POS_X, FIRST_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color2Button_->SetViewId(COLOR2_BUTTON_ID.c_str()); + color2Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color2Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color2Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color2Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[RED_COLOR], COLOR_BUTTON_RES[RED_COLOR]); + container_->Add(color2Button_); + color2Button_->SetVisible(true); + + if (color3Button_ == nullptr) { + color3Button_ = new UILabelButtonExt(); + } + color3Button_->SetPosition(THIRD_COLUMN_COLOR_BUTTON_POS_X, FIRST_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color3Button_->SetViewId(COLOR3_BUTTON_ID.c_str()); + color3Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color3Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color3Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color3Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[ORANGE_COLOR], + COLOR_BUTTON_RES[ORANGE_COLOR]); + container_->Add(color3Button_); + color3Button_->SetVisible(true); + + // 第二行颜色按钮 + if (color4Button_ == nullptr) { + color4Button_ = new UILabelButtonExt(); + } + color4Button_->SetPosition(FIRST_COLUMN_COLOR_BUTTON_POS_X, SECOND_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color4Button_->SetViewId(COLOR4_BUTTON_ID.c_str()); + color4Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color4Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color4Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color4Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[YELLOW_COLOR], + COLOR_BUTTON_RES[YELLOW_COLOR]); + container_->Add(color4Button_); + color4Button_->SetVisible(true); + + if (color5Button_ == nullptr) { + color5Button_ = new UILabelButtonExt(); + } + color5Button_->SetPosition(SECOND_COLUMN_COLOR_BUTTON_POS_X, SECOND_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color5Button_->SetViewId(COLOR5_BUTTON_ID.c_str()); + color5Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color5Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color5Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color5Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[GREEN_COLOR], COLOR_BUTTON_RES[GREEN_COLOR]); + container_->Add(color5Button_); + color5Button_->SetVisible(true); + + if (color6Button_ == nullptr) { + color6Button_ = new UILabelButtonExt(); + } + color6Button_->SetPosition(THIRD_COLUMN_COLOR_BUTTON_POS_X, SECOND_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color6Button_->SetViewId(COLOR6_BUTTON_ID.c_str()); + color6Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color6Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color6Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color6Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[LIGHT_BLUE_COLOR], + COLOR_BUTTON_RES[LIGHT_BLUE_COLOR]); + + container_->Add(color6Button_); + color6Button_->SetVisible(true); + + // 第三行颜色按钮 + if (color7Button_ == nullptr) { + color7Button_ = new UILabelButtonExt(); + } + color7Button_->SetPosition(FIRST_COLUMN_COLOR_BUTTON_POS_X, THIRD_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color7Button_->SetViewId(COLOR7_BUTTON_ID.c_str()); + color7Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color7Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color7Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color7Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[DARK_BLUE_COLOR], + COLOR_BUTTON_RES[DARK_BLUE_COLOR]); + container_->Add(color7Button_); + color7Button_->SetVisible(true); + + if (color8Button_ == nullptr) { + color8Button_ = new UILabelButtonExt(); + } + color8Button_->SetPosition(SECOND_COLUMN_COLOR_BUTTON_POS_X, THIRD_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color8Button_->SetViewId(COLOR8_BUTTON_ID.c_str()); + color8Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color8Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color8Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color8Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[PURPLE_COLOR], + COLOR_BUTTON_RES[PURPLE_COLOR]); + container_->Add(color8Button_); + color8Button_->SetVisible(true); + + if (color9Button_ == nullptr) { + color9Button_ = new UILabelButtonExt(); + } + color9Button_->SetPosition(THIRD_COLUMN_COLOR_BUTTON_POS_X, THIRD_ROW_COLOR_BUTTON_POS_Y, COLOR_BUTTON_WIDTH, + COLOR_BUTTON_HEIGHT); + color9Button_->SetViewId(COLOR9_BUTTON_ID.c_str()); + color9Button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + color9Button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + color9Button_->SetAlign(TEXT_ALIGNMENT_CENTER); + LOADIMG::LoadBtnImage(color9Button_, FLASHLIGHT_IMAGE, COLOR_BUTTON_RES[MULTI_COLOR], COLOR_BUTTON_RES[MULTI_COLOR]); + container_->Add(color9Button_); + color9Button_->SetVisible(true); + + // 设置界面组件回调函数 + container_->SetOnDragListener(this); + // 设置手电筒多个颜色按钮回调函数 + color3Button_->SetOnClickListener(this); + color1Button_->SetOnClickListener(this); + color2Button_->SetOnClickListener(this); + color6Button_->SetOnClickListener(this); + color5Button_->SetOnClickListener(this); + color4Button_->SetOnClickListener(this); + color9Button_->SetOnClickListener(this); + color8Button_->SetOnClickListener(this); + color7Button_->SetOnClickListener(this); + AddViewToPageContainer(container_); +} + +FlashLightColorPage::~FlashLightColorPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::~FlashLightColorPage"); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (colorLabel_ != nullptr) { + delete colorLabel_; + colorLabel_ = nullptr; + } + if (color1Button_ != nullptr) { + delete color1Button_; + color1Button_ = nullptr; + } + if (color2Button_ != nullptr) { + delete color2Button_; + color2Button_ = nullptr; + } + if (color3Button_ != nullptr) { + delete color3Button_; + color3Button_ = nullptr; + } + if (color4Button_ != nullptr) { + delete color4Button_; + color4Button_ = nullptr; + } + if (color5Button_ != nullptr) { + delete color5Button_; + color5Button_ = nullptr; + } + if (color6Button_ != nullptr) { + delete color6Button_; + color6Button_ = nullptr; + } + if (color7Button_ != nullptr) { + delete color7Button_; + color7Button_ = nullptr; + } + if (color8Button_ != nullptr) { + delete color8Button_; + color8Button_ = nullptr; + } + if (color9Button_ != nullptr) { + delete color9Button_; + color9Button_ = nullptr; + } + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +bool FlashLightColorPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnDrag"); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_SET_VIEW); + } + return false; +} + +bool FlashLightColorPage::OnClick(UIView &view, const ClickEvent &event) +{ + std::string viewId = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnClick [%s]", viewId.c_str()); + if (viewId == COLOR1_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::WHITE_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR2_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::RED_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR3_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::ORANGE_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR4_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::YELLOW_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR5_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::GREEN_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR6_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::LIGHT_BLUE_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR7_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::DARK_BLUE_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR8_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::PURPLE_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else if (viewId == COLOR9_BUTTON_ID) { + FlashLightModel::GetInstance().SetViewColor(FlashLightColorAttribute::MULTI_COLOR); + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnClick [Invalid]"); + } + return false; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightDefaultPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightDefaultPage.cpp new file mode 100644 index 000000000..7b6582c39 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightDefaultPage.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightDefaultPage + * Create: 2025-04-24 + */ +#include "flashlight/FlashLightDefaultPage.h" +#include "flashlight/FlashLightPresenter.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "flashlight/FlashLightModel.h" +#include "main/LoadImg.h" +#include "flashlight/FlashlightUiResourceImage.h" +namespace OHOS { +static const uint16_t RECOVER_LABEL_POS_X = 15; +static const uint16_t RECOVER_LABEL_POS_Y = 185; +static const uint16_t RECOVER_LABEL_WIDTH = 424; +static const uint16_t RECOVER_LABEL_HEIGHT = 50; +static const uint16_t RECOVER_LABEL_FONT_SIZE = 36; +static const uint16_t CANCLE_BUTTON_POS_X = 115; +static const uint16_t CANCLE_BUTTON_POS_Y = 300; +static const uint16_t CONFIRM_BUTTON_POS_X = 255; +static const uint16_t CONFIRM_BUTTON_POS_Y = 300; +static const uint16_t CANCLE_BUTTON_WIDTH = 85; +static const uint16_t CANCLE_BUTTON_HEIGHT = 85; +static const std::string CANCLE_BUTTON_ID = "cancle"; +static const std::string CONFIRM_BUTTON_ID = "confirm"; + +REGIST_SLICE_PAGE(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_DEFAULT_VIEW, FlashLightDefaultPage, false); +void FlashLightDefaultPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightDefaultPage::OnStart"); + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + container_->SetStyle(STYLE_BACKGROUND_OPA, 0); + } + + if (recoverLabel_ == nullptr) { + recoverLabel_ = new UILabel(); + } + recoverLabel_->SetPosition(RECOVER_LABEL_POS_X, RECOVER_LABEL_POS_Y, RECOVER_LABEL_WIDTH, RECOVER_LABEL_HEIGHT); + recoverLabel_->SetText("是否恢复默认设置"); + recoverLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + recoverLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + recoverLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, RECOVER_LABEL_FONT_SIZE); + // Add to rootView + container_->Add(recoverLabel_); + recoverLabel_->SetVisible(true); + + if (cancelButton_ == nullptr) { + cancelButton_ = new UILabelButtonExt(); + } + cancelButton_->SetPosition(CANCLE_BUTTON_POS_X, CANCLE_BUTTON_POS_Y, CANCLE_BUTTON_WIDTH, CANCLE_BUTTON_HEIGHT); + cancelButton_->SetViewId(CANCLE_BUTTON_ID.c_str()); + LOADIMG::LoadBtnImage(cancelButton_, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_RECOVERCANCLE, + IMAGE_CONVERTER_TOOL_RECOVERCANCLE); + cancelButton_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + cancelButton_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + container_->Add(cancelButton_); + cancelButton_->SetVisible(true); + + if (confirmButton_ == nullptr) { + confirmButton_ = new UILabelButtonExt(); + } + confirmButton_->SetPosition(CONFIRM_BUTTON_POS_X, CONFIRM_BUTTON_POS_Y, CANCLE_BUTTON_WIDTH, CANCLE_BUTTON_HEIGHT); + confirmButton_->SetViewId(CONFIRM_BUTTON_ID.c_str()); + LOADIMG::LoadBtnImage(confirmButton_, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_RECOVERCONFIRM, + IMAGE_CONVERTER_TOOL_RECOVERCONFIRM); + confirmButton_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + confirmButton_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + container_->Add(confirmButton_); + confirmButton_->SetVisible(true); + + // 设置界面组件回调函数 + container_->SetOnDragListener(this); + cancelButton_->SetOnClickListener(this); + confirmButton_->SetOnClickListener(this); + AddViewToPageContainer(container_); +} + +FlashLightDefaultPage::~FlashLightDefaultPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightDefaultPage::~FlashLightDefaultPage"); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (recoverLabel_ != nullptr) { + delete recoverLabel_; + recoverLabel_ = nullptr; + } + if (cancelButton_ != nullptr) { + delete cancelButton_; + cancelButton_ = nullptr; + } + if (confirmButton_ != nullptr) { + delete confirmButton_; + confirmButton_ = nullptr; + } + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +bool FlashLightDefaultPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnDrag"); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_SET_VIEW); + } + return false; +} + +bool FlashLightDefaultPage::OnClick(UIView &view, const ClickEvent &event) +{ + std::string viewId = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightDefaultPage::OnClick [%s]", viewId.c_str()); + uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId(); + if (viewId == CONFIRM_BUTTON_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGTH_VIEW); + FlashLightModel::GetInstance().SetDefault(); + } else if (viewId == CANCLE_BUTTON_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_SET_VIEW); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightDefaultPage::OnClick [Invalid]"); + } + return false; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightModel.cpp new file mode 100644 index 000000000..273a4641a --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightModel.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightModel + * Create: 2025-04-24 + */ +#include "flashlight/FlashLightModel.h" +#ifdef BUILD_IN_LINUX +#include "localtime.h" +#endif + +namespace OHOS { +static const uint32_t TIME_DISPLAY_NUM = 10; +FlashLightModel::FlashLightModel(FlashLightColorAttribute color, FlashLightBlinkFrequency blinkFrequency) +{ + color_ = color; + blinkFrequency_ = blinkFrequency; +} + +FlashLightModel::~FlashLightModel() {} + +FlashLightModel &FlashLightModel::GetInstance() +{ + static FlashLightModel instance; + return instance; +} + +FlashLightColorAttribute FlashLightModel::GetViewColor() +{ + return color_; +} + +void FlashLightModel::SetViewColor(FlashLightColorAttribute color) +{ + color_ = color; +} + +FlashLightBlinkFrequency FlashLightModel::GetBlinkFrequency() +{ + return blinkFrequency_; +} + +void FlashLightModel::SetBlinkFrequency(FlashLightBlinkFrequency blinkFrequency) +{ + blinkFrequency_ = blinkFrequency; +} + +void FlashLightModel::SetDefault() +{ + blinkFrequency_ = FlashLightBlinkFrequency::NOT_BLINK; // 不闪烁; + color_ = FlashLightColorAttribute::WHITE_COLOR; // 白色; +} + +uint32_t FlashLightModel::GetSysCurrentTime(std::string ¤tTime) +{ +#ifdef _WIN32 + struct tm localTime; + time_t timep; + gettimeofday(&sysTime_, NULL); + timep = (time_t)sysTime_.tv_sec; + localtime_r(&timep, &localTime); +#else + struct tm localTime; + time64_t timep; + gettimeofday64(&sysTime_, NULL); + timep = (time64_t)sysTime_.tv_sec; + localtime64_r(&sysTime_.tv_sec, &localTime); +#endif + if (localTime.tm_hour < TIME_DISPLAY_NUM) { + currentTime += "0"; + } + currentTime += std::to_string(localTime.tm_hour) + ":"; + if (localTime.tm_min < TIME_DISPLAY_NUM) { + currentTime += "0"; + } + currentTime += std::to_string(localTime.tm_min); + return 0; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPage.cpp new file mode 100644 index 000000000..ba91d99ce --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPage.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightPage + * Create: 2025-04-24 + */ +#include +#include "flashlight/FlashLightPage.h" +#include "flashlight/FlashLightPresenter.h" +#include "flashlight/FlashLightModel.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "main/LoadImg.h" +#include "flashlight/FlashlightUiResourceImage.h" + +namespace OHOS { +static const uint16_t SWITCH_BUTTON_POS_X = 168; +static const uint16_t SWITCH_BUTTON_POS_Y = 168; +static const uint16_t SWITCH_BUTTON_WIDTH = 119; +static const uint16_t SWITCH_BUTTON_HEIGHT = 119; +static const uint16_t SWITCH_LABEL_POS_X = 168; +static const uint16_t SWITCH_LABEL_POS_Y = 308; +static const uint16_t SWITCH_LABEL_WIDTH = 128; +static const uint16_t SWITCH_LABEL_HEIGHT = 46; +static const uint16_t SWITCH_LABEL_FONT_SIZE = 32; +static const uint16_t TIME_LABEL_FONT_SIZE = 38; +static const uint16_t IMAGE_VIEW_POS_X = 213; +static const uint16_t IMAGE_VIEW_POS_Y = 414; +static const uint16_t TIME_TEXT_POS_X = 151; +static const uint16_t TIME_TEXT_POS_Y = 31; +static const uint16_t TIME_TEXT_WIDTH = 153; +static const uint16_t TIME_TEXT_HEIGHT = 53; +static const uint16_t Y_OFFSET = 300; +static const std::string SWITCH_BUTTON_ID = "switch"; + +REGIST_SLICE_PAGE(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGTH_VIEW, FlashLightPage, true); +void FlashLightPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPage::OnStart"); + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + } + + if (OnLabel_ == nullptr) { + OnLabel_ = new UILabel(); + } + OnLabel_->SetPosition(SWITCH_LABEL_POS_X, SWITCH_LABEL_POS_Y, SWITCH_LABEL_WIDTH, SWITCH_LABEL_HEIGHT); + OnLabel_->SetText("点击照明"); + OnLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + OnLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SWITCH_LABEL_FONT_SIZE); + OnLabel_->SetStyle(STYLE_BACKGROUND_COLOR, OPA_OPAQUE); + OnLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + OnLabel_->SetVisible(true); + container_->Add(OnLabel_); + + if (flashLightOn_ == nullptr) { + flashLightOn_ = new UILabelButton(); + } + flashLightOn_->SetPosition(SWITCH_BUTTON_POS_X, SWITCH_BUTTON_POS_Y, SWITCH_BUTTON_WIDTH, SWITCH_BUTTON_HEIGHT); + flashLightOn_->SetViewId(SWITCH_BUTTON_ID.c_str()); + flashLightOn_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + flashLightOn_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + LOADIMG::LoadBtnImage(flashLightOn_, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_FLASHLIGHTON, + IMAGE_CONVERTER_TOOL_FLASHLIGHTON); + flashLightOn_->SetVisible(true); + container_->Add(flashLightOn_); + + // 创建时间显示组件 + if (systemTime_ == nullptr) { + systemTime_ = new UILabel(); + } + systemTime_->SetPosition(TIME_TEXT_POS_X, TIME_TEXT_POS_Y, TIME_TEXT_WIDTH, TIME_TEXT_HEIGHT); + systemTime_->SetText("12:00"); + systemTime_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + systemTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIME_LABEL_FONT_SIZE); + systemTime_->SetStyle(STYLE_BACKGROUND_COLOR, OPA_OPAQUE); + systemTime_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + systemTime_->SetVisible(true); + container_->Add(systemTime_); + if (timeCallback_ == nullptr) { + timeCallback_ = new TimeAnimatorCallback(); + } + if (timeAnimator_ == nullptr) { + timeAnimator_ = new Animator(timeCallback_, systemTime_, 0, true); + } + timeAnimator_->Start(); + + // Add ImageView to App + if (imageArrow_ == nullptr) { + imageArrow_ = new UIImageView(); + } + imageArrow_->SetPosition(IMAGE_VIEW_POS_X, IMAGE_VIEW_POS_Y); + container_->Add(imageArrow_); + imageArrow_->SetVisible(true); + LOADIMG::LoadImageViewImg(imageArrow_, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_DOWNARROW); + + flashLightOn_->SetOnClickListener(this); + container_->SetOnDragListener(this); + AddViewToPageContainer(container_); +} + +FlashLightPage::~FlashLightPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPage::~FlashLightPage"); + if (timeAnimator_ != nullptr) { + timeAnimator_->Stop(); + } + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (flashLightOn_ != nullptr) { + delete flashLightOn_; + flashLightOn_ = nullptr; + } + if (systemTime_ != nullptr) { + delete systemTime_; + systemTime_ = nullptr; + } + if (imageArrow_ != nullptr) { + delete imageArrow_; + imageArrow_ = nullptr; + } + if (timeAnimator_ != nullptr) { + delete timeAnimator_; + timeAnimator_ = nullptr; + } + if (timeCallback_ != nullptr) { + delete timeCallback_; + timeCallback_ = nullptr; + } + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +bool FlashLightPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnDrag"); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } else if ((event.GetDragDirection() == DragEvent::DIRECTION_BOTTOM_TO_TOP) && + (event.GetStartPoint().y > Y_OFFSET)) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_SET_VIEW); + } + return false; +} + +bool FlashLightPage::OnClick(UIView &view, const ClickEvent &event) +{ + std::string viewId = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPage::OnClick [%s]", viewId.c_str()); + if (viewId == SWITCH_BUTTON_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPage::OnClick [Invalid]"); + } + return false; +} + +void FlashLightPage::TimeAnimatorCallback::Callback(UIView *view) +{ + UILabel *timeLabel = dynamic_cast(view); + if (timeLabel == nullptr) { + return; + } + std::string currTime; + FlashLightModel::GetInstance().GetSysCurrentTime(currTime); + timeLabel->SetText(currTime.c_str()); + timeLabel->Invalidate(); +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPlayPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPlayPage.cpp new file mode 100644 index 000000000..fdf35dccc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPlayPage.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightPlayPage + * Create: 2025-04-24 + */ + +#include "flashlight/FlashLightPlayPage.h" +#include "flashlight/FlashLightPresenter.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "wearable_log.h" +#include "AppViewIDs.h" +#include "NativeAbility.h" +#include "main/LoadImg.h" + +namespace OHOS { +static const uint32_t FLASHLIGHT_PAGE_RES[10] = { + IMAGE_CONVERTER_TOOL_PLAYBLACKPAGE, IMAGE_CONVERTER_TOOL_PLAY1PAGE, IMAGE_CONVERTER_TOOL_PLAY2PAGE, + IMAGE_CONVERTER_TOOL_PLAY3PAGE, IMAGE_CONVERTER_TOOL_PLAY4PAGE, IMAGE_CONVERTER_TOOL_PLAY5PAGE, + IMAGE_CONVERTER_TOOL_PLAY6PAGE, IMAGE_CONVERTER_TOOL_PLAY7PAGE, IMAGE_CONVERTER_TOOL_PLAY8PAGE, + IMAGE_CONVERTER_TOOL_PLAY9PAGE, +}; +static const uint32_t FLASHLIGHT_BLINK_FREQ[3] = {500, 100, 0}; +static const uint32_t IMAGE_NUM = 2; +static const std::string PLAY_VIEW_ID = "flashLightPlayPage"; + +REGIST_SLICE_PAGE(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_PLAY_VIEW, FlashLightPlayPage, false); +void FlashLightPlayPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPlayPage::OnStart"); + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + container_->SetViewId(PLAY_VIEW_ID.c_str()); + } + uint16_t colorIndex = (uint16_t)FlashLightModel::GetInstance().GetViewColor(); + uint16_t blinkIndex = (uint16_t)FlashLightModel::GetInstance().GetBlinkFrequency(); + if (playImageAnimal == nullptr) { + playImageAnimal = new UIImageAnimatorView(); + } + playImageInfo[0].imageInfo = + ImageCacheManager::GetInstance().LoadOneInMultiRes(FLASHLIGHT_PAGE_RES[colorIndex], FLASHLIGHT_IMAGE); + playImageInfo[0].imageType = IMG_SRC_IMAGE_INFO; + playImageInfo[0].pos.x = 0; + playImageInfo[0].pos.y = 0; + playImageInfo[0].width = HORIZONTAL_RESOLUTION; + playImageInfo[0].height = VERTICAL_RESOLUTION; + playImageInfo[1].imageInfo = + ImageCacheManager::GetInstance().LoadOneInMultiRes(FLASHLIGHT_PAGE_RES[0], FLASHLIGHT_IMAGE); + playImageInfo[1].imageType = IMG_SRC_IMAGE_INFO; + playImageInfo[1].pos.x = 0; + playImageInfo[1].pos.y = 0; + playImageInfo[1].width = HORIZONTAL_RESOLUTION; + playImageInfo[1].height = VERTICAL_RESOLUTION; + playImageAnimal->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + playImageAnimal->SetImageAnimatorSrc(playImageInfo, IMAGE_NUM, FLASHLIGHT_BLINK_FREQ[blinkIndex]); + playImageAnimal->SetRepeat(true); + playImageAnimal->SetAutoEnable(false); + playImageAnimal->SetResizeMode(UIImageView::FILL); + container_->Add(playImageAnimal); + + playImageAnimal->Start(); + container_->SetOnDragListener(this); + container_->SetOnClickListener(this); + AddViewToPageContainer(container_); +} + +FlashLightPlayPage::~FlashLightPlayPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPlayPage::~FlashLightPlayPage"); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (playImageAnimal != nullptr) { + playImageAnimal->Stop(); + delete playImageAnimal; + playImageAnimal = nullptr; + } + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +bool FlashLightPlayPage::OnDrag(UIView &view, const DragEvent &event) +{ + std::string id = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnDrag [%s]", id.c_str()); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + return false; +} + +bool FlashLightPlayPage::OnClick(UIView &view, const ClickEvent &event) +{ + std::string viewId = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightPlayPage::OnClick [%s]", viewId.c_str()); + if (viewId == PLAY_VIEW_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGTH_VIEW); + } + return false; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPresenter.cpp new file mode 100644 index 000000000..57bb513b2 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightPresenter.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightPresenter + * Create: 2025-04-24 + */ + +#include "flashlight/FlashLightView.h" +#include "flashlight/FlashLightPresenter.h" +#include "NativeRegisterManager.h" + +namespace OHOS { +REGIST_MENU(VIEW_FLASHLIGHT, FlashLightView, FlashLightPresenter, FLASHLIGHT_MAIN_ICON, PNG_APPLIST_DEFAULT_IMG, + "手电筒"); +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemAdapter.cpp new file mode 100644 index 000000000..2adbf459e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemAdapter.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightSetItemAdapter.cpp + * Create: 2025-11-23 + */ +#include "flashlight/FlashLightSetItemAdapter.h" +#include "flashlight/FlashLightSetItemView.h" + +namespace OHOS { +FlashLightSetItemAdapter::FlashLightSetItemAdapter() {} + +FlashLightSetItemAdapter::~FlashLightSetItemAdapter() +{ + itemDatas_.Clear(); +} + +uint16_t FlashLightSetItemAdapter::GetCount(void) +{ + return itemDatas_.Size(); +} + +void FlashLightSetItemAdapter::SetData(const Graphic::Vector &data) +{ + if (!itemDatas_.IsEmpty()) { + itemDatas_.Clear(); + } + itemDatas_ = data; +} + +UIView *FlashLightSetItemAdapter::GetView(UIView *inView, int16_t index) +{ + if (itemDatas_.IsEmpty()) { + return nullptr; + } + + if (index >= itemDatas_.Size() || index < 0) { + return nullptr; + } + + FlashLightSetItem itemData = itemDatas_[index]; + FlashLightSetItemView *item = nullptr; + if (inView == nullptr) { + item = new FlashLightSetItemView(); + } else { + item = static_cast(inView); + } + item->SetItemInfo(itemData); + item->SetViewId(itemData.label.c_str()); + item->SetOnClickListener(itemClickListener); + return item; +} + +void FlashLightSetItemAdapter::AddListItem(const FlashLightSetItem &item) +{ + itemDatas_.PushBack(item); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemView.cpp new file mode 100644 index 000000000..32f330bf3 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetItemView.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightSetItemView + * Create: 2025-02-15 + */ + +#include "wearable_log.h" +#include "UiConfig.h" +#include "flashlight/FlashLightSetItemView.h" +#include "screensetting/ScreenModels.h" +#include "main/LoadImg.h" +#include "flashlight/FlashLightModel.h" + +namespace OHOS { +static constexpr uint16_t ITEM_X = 0; +static constexpr uint16_t ITEM_Y = 0; +static constexpr uint16_t ITEM_W = 340; +static constexpr uint16_t ITEM_H = 122; +static constexpr uint16_t ICON_X = 0; +static constexpr uint16_t ICON_Y = 10; +static constexpr uint16_t LABEL_X = 109; +static constexpr uint16_t LABEL_Y = 0; +static constexpr uint16_t LABEL_W = 172; +static constexpr uint16_t LABEL_H = 53; +static constexpr uint16_t LABEL_FONT = 38; +static constexpr uint16_t IMAGE_X = 315; +static constexpr uint16_t IMAGE_Y = 33; +static constexpr uint16_t ITEM_LABEL_X = 109; +static constexpr uint16_t ITEM_LABEL_Y = 52; +static constexpr uint16_t ITEM_LABEL_W = 172; +static constexpr uint16_t ITEM_LABEL_H = 46; +static constexpr uint16_t ITEM_LABEL_FONT = 32; + +FlashLightSetItemView::FlashLightSetItemView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightSetItemView"); + SetPosition(ITEM_X, ITEM_Y, ITEM_W, ITEM_H); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + SetTouchable(true); + + sIcon.SetPosition(ICON_X, ICON_Y); + sIcon.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + sLabel.SetPosition(LABEL_X, LABEL_Y); + sLabel.Resize(LABEL_W, LABEL_H); + sLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_FONT); + sLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + sLabel.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + itemLabel.SetPosition(ITEM_LABEL_X, ITEM_LABEL_Y); + itemLabel.Resize(ITEM_LABEL_W, ITEM_LABEL_H); + itemLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, ITEM_LABEL_FONT); + itemLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + itemLabel.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + itemLabel.SetStyle(STYLE_TEXT_COLOR, Color::Gray().full); + itemLabel.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + itemLabel.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sNextImage.SetPosition(IMAGE_X, IMAGE_Y); + sNextImage.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + LOADIMG::LoadImageViewImg(&sNextImage, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_RIGHTARROW); + + Add(&sIcon); + Add(&sLabel); + Add(&itemLabel); + Add(&sNextImage); +} + +FlashLightSetItemView::~FlashLightSetItemView() +{ + Remove(&sIcon); + Remove(&sLabel); + Remove(&itemLabel); + Remove(&sNextImage); + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +void FlashLightSetItemView::SetItemInfo(const FlashLightSetItem itemInfo) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightSetItemView::SetItemInfo %[s]", itemInfo.viewId.c_str()); + sItemInfo = itemInfo; + sLabel.SetText(itemInfo.label.c_str()); + itemLabel.SetText(itemInfo.itemLabel.c_str()); + LOADIMG::LoadImageViewImg(&sIcon, FLASHLIGHT_IMAGE, itemInfo.resId); +} + +const char *FlashLightSetItemView::GetViewId() const +{ + return sItemInfo.viewId.c_str(); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetPage.cpp new file mode 100644 index 000000000..7a2361a61 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/flashlight/src/FlashLightSetPage.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightSetPage + * Create: 2025-04-24 + */ + +#include "flashlight/FlashLightSetPage.h" +#include "flashlight/FlashLightPresenter.h" +#include "SlicePageFactory.h" +#include "flashlight/FlashLightView.h" +#include "flashlight/FlashLightModel.h" +#include "AppViewIDs.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include +#include "main/LoadImg.h" + +namespace OHOS { + +static const uint16_t SET_LABEL_POS_X = 117; +static const uint16_t SET_LABEL_POS_Y = 31; +static const uint16_t SET_LABEL_WIDTH = 220; +static const uint16_t SET_LABEL_HEIGHT = 53; +static const uint16_t SET_LABEL_FONT_SIZE = 38; +static const uint16_t SET_LIST_POS_X = 59; +static const uint16_t SET_LIST_POS_Y = 127; +static const uint16_t SET_LIST_WIDTH = 340; +static const uint16_t SET_LIST_HEIGHT = 244; +static const uint16_t RECOVER_BUTTON_POS_X = 120; +static const uint16_t RECOVER_BUTTON_POS_Y = 408; +static const uint16_t RECOVER_BUTTON_WIDTH = 220; +static const uint16_t RECOVER_BUTTON_HEIGHT = 80; +static const uint16_t RECOVER_BUTTON_FONT_SIZE = 36; +static const uint16_t CONTAINER_BLANK_SIZE = 100; +static const std::string COLOR__BUTTON_ID = "setColorItem"; +static const std::string BLINK_BUTTON_ID = "setBlinkItem"; +static const std::string RECOVER_BUTTON_ID = "recoverDefault"; +static std::string BLINK_ITEM_CONTENT[3] = {"慢", "å¿«", "不闪烁"}; +static std::string COLOR_ITEM_CONTENT[10] = {"黑色", "白色", "红色", "橙色", "黄色", + "绿色", "浅蓝色", "深蓝色", "紫色", "彩色"}; + +REGIST_SLICE_PAGE(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_SET_VIEW, FlashLightSetPage, false); +void FlashLightSetPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightSetPage::OnStart"); + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + container_->SetStyle(STYLE_BACKGROUND_OPA, 0); + container_->SetScrollBlankSize(CONTAINER_BLANK_SIZE, UIAbstractScroll::Direction::TOP); + container_->SetScrollBlankSize(CONTAINER_BLANK_SIZE, UIAbstractScroll::Direction::BOTTOM); + } + + if (setLabel_ == nullptr) { + setLabel_ = new UILabel(); + } + setLabel_->SetPosition(SET_LABEL_POS_X, SET_LABEL_POS_Y, SET_LABEL_WIDTH, SET_LABEL_HEIGHT); + setLabel_->SetText("手电筒设置"); + setLabel_->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + setLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + setLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SET_LABEL_FONT_SIZE); + container_->Add(setLabel_); + setLabel_->SetVisible(true); + + if (setItemList_ == nullptr) { + setItemList_ = new UIList(); + } + setItemList_->SetPosition(SET_LIST_POS_X, SET_LIST_POS_Y, SET_LIST_WIDTH, SET_LIST_HEIGHT); + setItemList_->SetLoopState(false); + setItemList_->EnableAutoAlign(true); + if (setItemAdapter_ == nullptr) { + setItemAdapter_ = new FlashLightSetItemAdapter(); + } + uint16_t colorIndex = (uint16_t)FlashLightModel::GetInstance().GetViewColor(); + uint16_t blinkIndex = (uint16_t)FlashLightModel::GetInstance().GetBlinkFrequency(); + colorItem_.itemLabel = COLOR_ITEM_CONTENT[colorIndex]; + colorItem_.viewId = COLOR__BUTTON_ID; + blinkItem_.itemLabel = BLINK_ITEM_CONTENT[blinkIndex]; + blinkItem_.viewId = BLINK_BUTTON_ID; + setItemAdapter_->AddListItem(colorItem_); + setItemAdapter_->AddListItem(blinkItem_); + setItemAdapter_->SetItemClickListener(this); + setItemList_->SetAdapter(setItemAdapter_); + container_->Add(setItemList_); + setItemList_->SetVisible(true); + + if (recoverButton_ == nullptr) { + recoverButton_ = new UILabelButtonExt(); + } + recoverButton_->SetPosition(RECOVER_BUTTON_POS_X, RECOVER_BUTTON_POS_Y, RECOVER_BUTTON_WIDTH, + RECOVER_BUTTON_HEIGHT); + recoverButton_->SetViewId(RECOVER_BUTTON_ID.c_str()); + recoverButton_->SetText("恢复默认\n"); + recoverButton_->SetTextColor(Color::Red()); + recoverButton_->SetAlign(TEXT_ALIGNMENT_CENTER); + recoverButton_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, RECOVER_BUTTON_FONT_SIZE); + LOADIMG::LoadBtnImage(recoverButton_, FLASHLIGHT_IMAGE, IMAGE_CONVERTER_TOOL_RECOVERBUTTON, + IMAGE_CONVERTER_TOOL_RECOVERBUTTON); + recoverButton_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + recoverButton_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED); + container_->Add(recoverButton_); + recoverButton_->SetVisible(true); + + // 设置界面组件回调函数 + container_->SetOnDragListener(this); + recoverButton_->SetOnClickListener(this); + AddViewToPageContainer(container_); +} + +FlashLightSetPage::~FlashLightSetPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightSetPage::~FlashLightSetPage"); + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (setLabel_ != nullptr) { + delete setLabel_; + setLabel_ = nullptr; + } + if (recoverButton_ != nullptr) { + delete recoverButton_; + recoverButton_ = nullptr; + } + if (setItemList_ != nullptr) { + delete setItemList_; + setItemList_ = nullptr; + } + if (setItemAdapter_ != nullptr) { + delete setItemAdapter_; + setItemAdapter_ = nullptr; + } + ImageCacheManager::GetInstance().UnloadSingleRes(FLASHLIGHT_IMAGE); +} + +bool FlashLightSetPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FlashLightColorPage::OnDrag"); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGTH_VIEW); + } + return false; +} + +bool FlashLightSetPage::OnClick(UIView &view, const ClickEvent &event) +{ + uint8_t viewType = view.GetViewType(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FlashLightSetPage::OnClick [%d]", viewType); + if (viewType == UIViewType::UI_VIEW_GROUP) { + FlashLightSetItemView *itemView = static_cast(&view); + std::string viewId = itemView->GetViewId(); + if (viewId == COLOR__BUTTON_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_COLOR_VIEW); + } else if (viewId == BLINK_BUTTON_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_BLINK_VIEW); + } + } else if (viewType == UIViewType::UI_LABEL_BUTTON_EXT && view.GetViewId() == RECOVER_BUTTON_ID) { + NativeAbility::GetInstance().SwitchSlice(VIEW_FLASHLIGHT, FlashLightAllView::FLASH_LIGHT_DEFAULT_VIEW); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "FlashLightSetPage::OnClick [Invalid]"); + } + return false; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartModel.cpp index 852053b9b..43e318f77 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartModel.cpp @@ -1,10 +1,10 @@ -#include "HeartModel.h" +#include "heartrate/HeartModel.h" #include "wearable_log.h" #include "graphic_service.h" -#include "IndoorWalkPreparedView.h" -#include "IndoorWalkPresenter.h" -#include "MainViewSample.h" -#include "HeartRateView.h" +#include "indoorwalk/IndoorWalkPreparedView.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "main/MainViewSample.h" +#include "heartrate/HeartRateView.h" #ifdef __cplusplus extern "C" { @@ -73,7 +73,7 @@ static void Notify(void *args, const Topic topic, Request* request) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Notify] malloc fail"); } - int rets = memcpy_s(heartInfo, sizeof(HeartDatas), (HeartInfo*)request->data, request->len); + int rets = memcpy_s(heartInfo, sizeof(HeartDatas), (HeartDatas*)request->data, request->len); if (rets != EOK) { free(heartInfo); heartInfo = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartRateView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartRateView.cpp index 8c9643544..2c9b2c42e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartRateView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartRateView.cpp @@ -6,10 +6,10 @@ */ #include -#include "HeartRateView.h" +#include "heartrate/HeartRateView.h" #include "common/screen.h" #include "UiConfig.h" -#include "ScreenModels.h" +#include "screensetting/ScreenModels.h" #include "ui_resource_image.h" #include "common/image_cache_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityModel.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityModel.h index 7c694f9f8..388fe95fd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityModel.h @@ -13,7 +13,7 @@ #include #include #include "ohos_types.h" -#include "RtcService.h" +#include "rtcservice/RtcService.h" #include "samgr_lite.h" namespace OHOS { @@ -39,7 +39,7 @@ public: uint32 GetStepCounter(void); void ReviseStepCounter(uint32 &counter); void GetStepData(const StepDataDistribute &type, uint32_t *value); - void SetStepData(uint32_t &value); + void SetStepData(const uint32_t &value); void SaveStepToFile(struct tm *tm_data); int GetWeekToday(void); uint32 GetLastSavedValue(void); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityPresenter.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityPresenter.h index 7ff632eec..073146568 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityPresenter.h @@ -10,7 +10,7 @@ #include #include "Presenter.h" -#include "MainActivityView.h" +#include "activity/MainActivityView.h" namespace OHOS { static constexpr const char *ACTIVITY_WEEK_VIEW = "activityweekview"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityWeekView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityWeekView.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityWeekView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityWeekView.h index 06a8c755b..fa9da0b46 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/ActivityWeekView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/ActivityWeekView.h @@ -17,7 +17,7 @@ #include "UiConfig.h" #include "wearable_log.h" #include "components/ui_card_page.h" -#include "ActivityModel.h" +#include "activity/ActivityModel.h" namespace OHOS { #define DAYS 7 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/MainActivityView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/MainActivityView.h similarity index 81% rename from code/sdk/application/wearable/nativeapp/nativeui/activity/include/MainActivityView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/activity/MainActivityView.h index ff024061d..2d0a6877d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/activity/include/MainActivityView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/activity/MainActivityView.h @@ -19,10 +19,10 @@ #include "font/ui_font_bitmap.h" #include "font/ui_font.h" #include "graphic_config.h" -#include "ModelListenerSample.h" -#include "ActivityModel.h" -#include "ActivityPresenter.h" -#include "ActivityWeekView.h" +#include "main/ModelListenerSample.h" +#include "activity/ActivityModel.h" +#include "activity/ActivityPresenter.h" +#include "activity/ActivityWeekView.h" namespace OHOS { class ActivityPresenter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardAdapter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardAdapter.h index 8f18d42be..a819ed10c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardAdapter.h @@ -17,7 +17,7 @@ #include "components/abstract_adapter.h" #include "UiConfig.h" #include "wearable_log.h" -#include "AddCardItem.h" +#include "add_card/AddCardItem.h" namespace OHOS { class AddCardAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardItem.h b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardItem.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardItem.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardItem.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardModel.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardModel.h index 9bdf0e41d..0ef22336e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardModel.h @@ -12,8 +12,8 @@ #include #include "AppViewIDs.h" #include "UiConfig.h" -#include "AddCardPresenter.h" -#include "MainModel.h" +#include "add_card/AddCardPresenter.h" +#include "main/MainModel.h" namespace OHOS { class AddCardModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardPresenter.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardPresenter.h index f1fd42b33..c0ea8536f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardPresenter.h @@ -11,7 +11,7 @@ #include "Presenter.h" #include "components/ui_list.h" #include "components/ui_view.h" -#include "ModelListenerSample.h" +#include "main/ModelListenerSample.h" #define TOAST_KEEP_TIME 1000 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardView.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardView.h index 12cca7012..952590d8f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/add_card/include/AddCardView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/add_card/AddCardView.h @@ -15,8 +15,8 @@ #include "components/ui_toggle_button.h" #include "ChangeSliceListener.h" #include "UiConfig.h" -#include "AddCardAdapter.h" -#include "AddCardModel.h" +#include "add_card/AddCardAdapter.h" +#include "add_card/AddCardModel.h" namespace OHOS { class AddCardPresenter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmClockModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmClockModel.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmClockModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmClockModel.h index 074df441b..9a742feb5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmClockModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmClockModel.h @@ -9,7 +9,7 @@ #include "ohos_types.h" #include "list.h" -#include "AlmmgrAlarmClockManage.h" +#include "alarmclockmanage/AlmmgrAlarmClockManage.h" #include "player.h" #include "source.h" #include "broadcast_feature.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmCloseRingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmCloseRingView.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmCloseRingView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmCloseRingView.h index f995da7ee..8cd9634b2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmCloseRingView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmCloseRingView.h @@ -14,7 +14,7 @@ #include "components/ui_button.h" #include "components/ui_label_button.h" #include "UiConfig.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmClockModel.h" #include "ChangeSliceListener.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmConfigView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmConfigView.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmConfigView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmConfigView.h index 48c844ca4..77797f368 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmConfigView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmConfigView.h @@ -18,7 +18,7 @@ #include "font/ui_font.h" #include "common/screen.h" #include "gfx_utils/graphic_log.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmClockModel.h" namespace OHOS { class AlarmConfigView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmJudgeView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmJudgeView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmJudgeView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmJudgeView.h index c5a7cd1ba..89c8b0d1b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmJudgeView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmJudgeView.h @@ -20,8 +20,8 @@ #include "layout/grid_layout.h" #include "font/ui_font.h" #include "common/screen.h" -#include "AlarmPresenter.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/AlarmClockModel.h" namespace OHOS { class AlarmJudgeView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmMaxClock.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmMaxClock.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmMaxClock.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmMaxClock.h index f5798f421..e17c63481 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmMaxClock.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmMaxClock.h @@ -20,8 +20,8 @@ #include "layout/grid_layout.h" #include "font/ui_font.h" #include "common/screen.h" -#include "AlarmPresenter.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/AlarmClockModel.h" namespace OHOS { void CancelScanHandle(void); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmNewTimeView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmNewTimeView.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmNewTimeView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmNewTimeView.h index ec6286a05..c163548ec 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmNewTimeView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmNewTimeView.h @@ -13,8 +13,8 @@ #include "components/ui_scroll_view.h" #include "components/ui_time_picker.h" #include "View.h" -#include "AlarmPresenter.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/AlarmClockModel.h" namespace OHOS { class AlarmNewTimeView : public UITimePicker::SelectedListener { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPopUpPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPopUpPresenter.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPopUpPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPopUpPresenter.h index 632c010cc..073294924 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPopUpPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPopUpPresenter.h @@ -13,7 +13,7 @@ #include "Presenter.h" #include "ChangeSliceListener.h" #include "UiConfig.h" -#include "AlarmPopUpView.h" +#include "alarm/AlarmPopUpView.h" #include "components/ui_label.h" #include "common/screen.h" #include "components/ui_label.h" @@ -26,11 +26,11 @@ #include "components/ui_label_button.h" #include "components/ui_digital_clock.h" #include "gfx_utils/graphic_log.h" -#include "ModelListenerSample.h" -#include "AlarmCloseRingView.h" -#include "AlarmRingView.h" -#include "AlarmPopUpView.h" -#include "AlarmClockModel.h" +#include "main/ModelListenerSample.h" +#include "alarm/AlarmCloseRingView.h" +#include "alarm/AlarmRingView.h" +#include "alarm/AlarmPopUpView.h" +#include "alarm/AlarmClockModel.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPopUpView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPopUpView.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPopUpView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPopUpView.h index 107c4a6e4..988dacfff 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPopUpView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPopUpView.h @@ -16,10 +16,10 @@ #include "components/ui_label_button.h" #include "ChangeSliceListener.h" #include "components/ui_digital_clock.h" -#include "AlarmSetTimeView.h" -#include "AlarmCloseRingView.h" -#include "AlarmRingView.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmSetTimeView.h" +#include "alarm/AlarmCloseRingView.h" +#include "alarm/AlarmRingView.h" +#include "alarm/AlarmClockModel.h" #include "UiConfig.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPresenter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPresenter.h index 11ba16cae..c8d98ea2d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmPresenter.h @@ -24,7 +24,7 @@ #include "components/ui_time_picker.h" #include "components/ui_digital_clock.h" #include "gfx_utils/graphic_log.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmClockModel.h" #include "wearable_log.h" #include "color.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmRingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmRingView.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmRingView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmRingView.h index b79eb123b..f6b7ea02d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmRingView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmRingView.h @@ -17,7 +17,7 @@ #include "ChangeSliceListener.h" #include "components/ui_digital_clock.h" #include "UiConfig.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmClockModel.h" #include "ChangeSliceListener.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmSetTimeView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmSetTimeView.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmSetTimeView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmSetTimeView.h index 5c7486ba8..f781fb390 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmSetTimeView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmSetTimeView.h @@ -13,8 +13,8 @@ #include "components/ui_scroll_view.h" #include "components/ui_time_picker.h" #include "View.h" -#include "AlarmPresenter.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/AlarmClockModel.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmSetWeekView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmSetWeekView.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmSetWeekView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmSetWeekView.h index 3f4b8848c..6496a80d0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/AlarmSetWeekView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/AlarmSetWeekView.h @@ -17,8 +17,8 @@ #include "layout/grid_layout.h" #include "components/root_view.h" #include "components/ui_time_picker.h" -#include "AlarmPresenter.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/AlarmClockModel.h" namespace OHOS { class AlarmSetWeekView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/MainAlarmView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/MainAlarmView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/alarm/include/MainAlarmView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarm/MainAlarmView.h index 0982563a6..2969cde9c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarm/include/MainAlarmView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarm/MainAlarmView.h @@ -19,14 +19,14 @@ #include "ChangeSliceListener.h" #include "components/ui_digital_clock.h" #include "components/ui_toggle_button.h" -#include "AlarmPresenter.h" -#include "AlarmSetTimeView.h" -#include "AlarmSetWeekView.h" -#include "AlarmJudgeView.h" -#include "AlarmConfigView.h" -#include "AlarmNewTimeView.h" -#include "AlarmMaxClock.h" -#include "AlarmClockModel.h" +#include "alarm/AlarmPresenter.h" +#include "alarm/AlarmSetTimeView.h" +#include "alarm/AlarmSetWeekView.h" +#include "alarm/AlarmJudgeView.h" +#include "alarm/AlarmConfigView.h" +#include "alarm/AlarmNewTimeView.h" +#include "alarm/AlarmMaxClock.h" +#include "alarm/AlarmClockModel.h" namespace OHOS { constexpr int16_t D_CLOCK_Y = 210; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/include/AlarmClockManage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarmclockmanage/AlarmClockManage.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/include/AlarmClockManage.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarmclockmanage/AlarmClockManage.h index 869857e5e..360a78e74 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/include/AlarmClockManage.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarmclockmanage/AlarmClockManage.h @@ -13,7 +13,7 @@ #include #include "ohos_types.h" -#include "AlarmClockTimerConfig.h" +#include "alarmclocktimerconfig/AlarmClockTimerConfig.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/include/AlmmgrAlarmClockManage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarmclockmanage/AlmmgrAlarmClockManage.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/include/AlmmgrAlarmClockManage.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarmclockmanage/AlmmgrAlarmClockManage.h index 96fc7dd67..a10d45c91 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alarmclockmanage/include/AlmmgrAlarmClockManage.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alarmclockmanage/AlmmgrAlarmClockManage.h @@ -8,7 +8,7 @@ #define ALMMGR_ALARM_CLOCK_MANAGE_H #include "ohos_types.h" -#include "AlarmClockManage.h" +#include "alarmclockmanage/AlarmClockManage.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/include/AlarmClockTimerConfig.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alarmclocktimerconfig/AlarmClockTimerConfig.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/include/AlarmClockTimerConfig.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alarmclocktimerconfig/AlarmClockTimerConfig.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBarCode.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBarCode.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBarCode.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBarCode.h index 12426d62e..d8dfe8fa0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBarCode.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBarCode.h @@ -12,7 +12,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_barcode.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayBarCode : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBind.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBind.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBind.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBind.h index bfe2153e8..80fe2172f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBind.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBind.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "components/ui_qrcode.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBindAni.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBindAni.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBindAni.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBindAni.h index ea2cc5820..28b883d18 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBindAni.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBindAni.h @@ -12,7 +12,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_image_animator.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #define ALIPAY_BIND_SEARCH_IMAGE_NUM 8 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBindRes.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBindRes.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBindRes.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBindRes.h index 5b7f9a6a0..5edfbb339 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayBindRes.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayBindRes.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayBindRes : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayExitBind.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayExitBind.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayExitBind.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayExitBind.h index 4b9321a60..6f28cc489 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayExitBind.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayExitBind.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayExitBind : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayHelp.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayHelp.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayHelp.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayHelp.h index 350da2143..acce7877b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayHelp.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayHelp.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "components/ui_qrcode.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListAdapter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListAdapter.h index c28ddc4be..4f05b9922 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListAdapter.h @@ -17,7 +17,7 @@ #include "components/abstract_adapter.h" #include "wearable_log.h" #include "UiConfig.h" -#include "AlipayListItem.h" +#include "alipay/AlipayList/AlipayListItem.h" namespace OHOS { class AlipayListAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListItem.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListItem.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListItem.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListItem.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListItemView.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListItemView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListItemView.h index 74262222f..43f7a273d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListItemView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListItemView.h @@ -13,8 +13,8 @@ #include "components/ui_image_view.h" #include "UiConfig.h" -#include "AlipayListItem.h" -#include "AlipayListView.h" +#include "alipay/AlipayList/AlipayListItem.h" +#include "alipay/AlipayList/AlipayListView.h" namespace OHOS { class AlipayListItemView : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListView.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListView.h index ef9dd02bf..328632c93 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayList/AlipayListView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayList/AlipayListView.h @@ -16,11 +16,11 @@ #include "components/ui_scroll_view.h" #include "components/ui_list.h" #include "components/icon_adapter.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "AppViewIDs.h" #include "UiConfig.h" -#include "AlipayListAdapter.h" -#include "AlipayListItem.h" +#include "alipay/AlipayList/AlipayListAdapter.h" +#include "alipay/AlipayList/AlipayListItem.h" namespace OHOS { class AlipayListAdapter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayMainView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayMainView.h similarity index 76% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayMainView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayMainView.h index 325c47047..6e07939dd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayMainView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayMainView.h @@ -13,27 +13,27 @@ #include "components/ui_view_group.h" #include "ChangeSliceListener.h" #include "components/ui_swipe_view.h" -#include "AlipayPresenter.h" -#include "AlipayModel.h" -#include "AlipayBind.h" -#include "AlipayExitBind.h" -#include "AlipayBindRes.h" -#include "AlipayBindAni.h" -#include "AlipayListView.h" -#include "AlipayBarCode.h" -#include "AlipayPayCode.h" -#include "AlipaySetting.h" -#include "AlipayHelp.h" -#include "AlipayUnbindFinish.h" -#include "AlipayUnbind.h" +#include "alipay/AlipayPresenter.h" +#include "alipay/AlipayModel.h" +#include "alipay/AlipayBind.h" +#include "alipay/AlipayExitBind.h" +#include "alipay/AlipayBindRes.h" +#include "alipay/AlipayBindAni.h" +#include "alipay/AlipayList/AlipayListView.h" +#include "alipay/AlipayBarCode.h" +#include "alipay/AlipayPayCode.h" +#include "alipay/AlipaySetting.h" +#include "alipay/AlipayHelp.h" +#include "alipay/AlipayUnbindFinish.h" +#include "alipay/AlipayUnbind.h" -#include "AlipayGetTransList.h" -#include "AlipayTransTips.h" -#include "AlipayTransCode.h" -#include "AlipayTransEnable.h" -#include "AlipayTransRes.h" -#include "AlipayTransListView.h" -#include "AlipayTransAni.h" +#include "alipay/AlipayTrans/AlipayGetTransList.h" +#include "alipay/AlipayTrans/AlipayTransTips.h" +#include "alipay/AlipayTrans/AlipayTransCode.h" +#include "alipay/AlipayTrans/AlipayTransEnable.h" +#include "alipay/AlipayTrans/AlipayTransRes.h" +#include "alipay/AlipayTrans/AlipayTransListView.h" +#include "alipay/AlipayTrans/AlipayTransAni.h" namespace OHOS { class AlipayMainView; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayModel.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayModel.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayPayCode.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayPayCode.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayPayCode.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayPayCode.h index 6ef24cb3a..997ff5f32 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayPayCode.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayPayCode.h @@ -12,7 +12,7 @@ #include "components/ui_label_button.h" #include "components/ui_button.h" #include "components/ui_qrcode.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayPayCode : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayPresenter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayPresenter.h index 092ee45eb..f8f96a57d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayPresenter.h @@ -12,7 +12,7 @@ #include "UiConfig.h" #include "wearable_log.h" #include "color.h" -#include "AlipayModel.h" +#include "alipay/AlipayModel.h" namespace OHOS { constexpr char *ALIPAY_LIST_PAY_BUTTON = (char *)"alipaylistpay"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayRefreshBindCode.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayRefreshBindCode.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayRefreshBindCode.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayRefreshBindCode.h index fe03e3035..cc3d25f00 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayRefreshBindCode.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayRefreshBindCode.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "components/ui_qrcode.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipaySetting.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipaySetting.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipaySetting.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipaySetting.h index deb5a2da5..356bd1014 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipaySetting.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipaySetting.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "components/ui_qrcode.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayGetTransList.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayGetTransList.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayGetTransList.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayGetTransList.h index a5c671432..4eae2a652 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayGetTransList.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayGetTransList.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayGetTransList : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransAni.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransAni.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransAni.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransAni.h index fc577b8b8..8f383eddd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransAni.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransAni.h @@ -12,7 +12,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_image_animator.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #define ALIPAY_TRANS_SEARCH_IMAGE_NUM 8 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransCode.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransCode.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransCode.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransCode.h index d4ba75077..d614e800a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransCode.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransCode.h @@ -12,7 +12,7 @@ #include "components/ui_label_button.h" #include "components/ui_button.h" #include "components/ui_qrcode.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayTransCode : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransEnable.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransEnable.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransEnable.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransEnable.h index e2af18b71..8461574ea 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransEnable.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransEnable.h @@ -12,7 +12,7 @@ #include "components/ui_label_button.h" #include "components/ui_button.h" #include "components/ui_qrcode.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayTransEnable : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListAdapter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListAdapter.h index 233193063..9dbdb4e28 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListAdapter.h @@ -17,7 +17,7 @@ #include "components/abstract_adapter.h" #include "wearable_log.h" #include "UiConfig.h" -#include "AlipayTransListItem.h" +#include "alipay/AlipayTrans/AlipayTransListItem.h" namespace OHOS { class AlipayTransListAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListItem.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListItem.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListItem.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListItem.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListItemView.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListItemView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListItemView.h index 6a12a6a42..6cf9a780a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListItemView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListItemView.h @@ -13,8 +13,8 @@ #include "components/ui_image_view.h" #include "UiConfig.h" -#include "AlipayTransListItem.h" -#include "AlipayTransListView.h" +#include "alipay/AlipayTrans/AlipayTransListItem.h" +#include "alipay/AlipayTrans/AlipayTransListView.h" namespace OHOS { class AlipayTransListItemView : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListView.h index 23cb4fe94..443cfa4cd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransListView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransListView.h @@ -17,11 +17,11 @@ #include "components/ui_list.h" #include "components/ui_button.h" #include "components/icon_adapter.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "AppViewIDs.h" #include "UiConfig.h" -#include "AlipayTransListAdapter.h" -#include "AlipayTransListItem.h" +#include "alipay/AlipayTrans/AlipayTransListAdapter.h" +#include "alipay/AlipayTrans/AlipayTransListItem.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransRes.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransRes.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransRes.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransRes.h index 57a93a147..805df6db2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransRes.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransRes.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayTransRes : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransTips.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransTips.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransTips.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransTips.h index 0254ab881..c1fb83438 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayTrans/AlipayTransTips.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayTrans/AlipayTransTips.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayTransTips : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayUnbind.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayUnbind.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayUnbind.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayUnbind.h index 183b8066e..27a192655 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayUnbind.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayUnbind.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" namespace OHOS { class AlipayUnbind : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayUnbindFinish.h b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayUnbindFinish.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayUnbindFinish.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayUnbindFinish.h index 9221d783f..4d2e0dfe6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/alipay/include/AlipayUnbindFinish.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/alipay/AlipayUnbindFinish.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AlipayPresenter.h" +#include "alipay/AlipayPresenter.h" #include "components/ui_qrcode.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodModel.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodModel.h index 69586855d..f55ad1726 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodModel.h @@ -7,8 +7,7 @@ #ifndef AODMODEL_H #define AODMODEL_H -#include "AodView.h" -#include "components/ui_view.h" +#include "main/MainModel.h" namespace OHOS { class AodModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodPresenter.h similarity index 82% rename from code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodPresenter.h index 969fc9c1d..0216f983f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodPresenter.h @@ -8,10 +8,10 @@ #ifndef AODPRESENTER_H #define AODPRESENTER_H #include "Presenter.h" -#include "AodView.h" +#include "aod_view/AodView.h" #include "components/ui_view.h" -#include "KeyInputListener.h" -#include "ModelListenerSample.h" +#include "key/KeyInputListener.h" +#include "main/ModelListenerSample.h" namespace OHOS { class AodView; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodView.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodView.h index 0bcf7afba..e012a460a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/aod_view/include/AodView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/aod_view/AodView.h @@ -8,9 +8,9 @@ #ifndef AODVIEW_H #define AODVIEW_H #include "View.h" -#include "MainModel.h" -#include "SetDialInfo.h" -#include "DialBinTypesV2.h" +#include "main/MainModel.h" +#include "set_dial/SetDialInfo.h" +#include "main/DialBinTypesV2.h" #include "components/ui_view.h" #include "components/ui_card_page.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/AppItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/AppItemView.h similarity index 79% rename from code/sdk/application/wearable/nativeapp/nativeui/applist/include/AppItemView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/applist/AppItemView.h index 077e4c12f..51eb58cfa 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/AppItemView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/AppItemView.h @@ -8,10 +8,10 @@ #ifndef APP_ITEM_VIEW_H #define APP_ITEM_VIEW_H -#include "components/ui_label.h" +#include "components/ui_label_ext.h" #include "components/ui_view_group.h" #include "components/ui_image_view.h" -#include "ApplistModel.h" +#include "applist/ApplistModel.h" #include "UiConfig.h" namespace OHOS { @@ -30,8 +30,8 @@ private: AppItemView &operator = (const AppItemView &); UIImageView icon_; - UILabel label_; - AppItem itemInfo_ = { VIEW_INVALID, nullptr, nullptr, nullptr, nullptr }; + UILabelExt label_; + AppItem itemInfo_; }; class HexagonsItemView : public UIImageView { @@ -44,34 +44,34 @@ public: private: HexagonsItemView(const HexagonsItemView &); HexagonsItemView &operator = (const HexagonsItemView &); - AppItem itemInfo_ = { VIEW_INVALID, nullptr, nullptr, nullptr, nullptr }; + AppItem itemInfo_; }; class FootballItemView : public UIImageView { public: explicit FootballItemView() {} - ~FootballItemView() {} + ~FootballItemView(); void SetItemInfo(const AppItem &itemInfo); AppViewId GetViewId(); const char *GetAppUid(); private: FootballItemView(const FootballItemView &); FootballItemView &operator = (const FootballItemView &); - AppItem itemInfo_ = { VIEW_INVALID, nullptr, nullptr, nullptr, nullptr }; + AppItem itemInfo_; }; class WaterfallItemView : public UIImageView { public: explicit WaterfallItemView() {} - ~WaterfallItemView() {} + ~WaterfallItemView(); void SetItemInfo(const AppItem &itemInfo); AppViewId GetViewId(); const char *GetAppUid(); private: WaterfallItemView(const WaterfallItemView &); WaterfallItemView &operator = (const WaterfallItemView &); - AppItem itemInfo_ = { VIEW_INVALID, nullptr, nullptr, nullptr, nullptr }; + AppItem itemInfo_; }; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistAdapter.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistAdapter.h index 5302fbc5e..811d2b296 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistAdapter.h @@ -17,8 +17,8 @@ #include "components/abstract_adapter.h" #include "UiConfig.h" #include "wearable_log.h" -#include "AppItemView.h" -#include "ApplistModel.h" +#include "applist/AppItemView.h" +#include "applist/ApplistModel.h" namespace OHOS { class ApplistAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistModel.h new file mode 100644 index 000000000..1cd7bd0df --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistModel.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: ApplistModel.h + * Author: + * Create: 2021-09-18 + */ + +#ifndef APPLIST_MODEL_H +#define APPLIST_MODEL_H + +#include "bundle_info.h" +#include "AppViewIDs.h" +#include "ohos_types.h" + +#define APP_MAX_NUM 50 + +namespace OHOS { +static const int INVALID_MASK = 0x0; + +enum UIResourceTextId : uint16_t { + STR_MAX_ID = 0, +}; + +struct AppItem { + uint16_t id = VIEW_INVALID; + const char *iconSmall = nullptr; // 小图标资源路径 + const char *iconHexagon = nullptr; // 六边形图标资源路径 + const char *label = nullptr; // 应用名 + uint32_t resId = INVALID_MASK; // 小图标压缩资源对应的id + uint32_t hexagonId = INVALID_MASK; // 六边形图标压缩资源对应的id + const char *resPath = nullptr; // 小图标压缩资源路径 + const char *hexagonPath = nullptr; // 六边形图标压缩资源路径 + uint16_t labelId = STR_MAX_ID; // 多语言环境下对应的字符id + const char *uid = nullptr; + // resId、resPath和iconSmall互斥, hexagonId、hexagonPath和iconHexagon互斥, labelId和label互斥 + + AppItem() = default; + + // 使用该构造方法初始化,支持多语言注册以及多图标打包功能 + AppItem(uint16_t id, uint32_t resId, uint32_t hexagonId, const char *resPath, + const char *hexagonPath, uint16_t labelId, const char *uid) : + id(id), + resId(resId), + hexagonId(hexagonId), + resPath(resPath), + hexagonPath(hexagonPath), + labelId(labelId), + uid(uid) {} + + // 使用该构造方法初始化,不支持多语言,一个图标使用一个文件 + AppItem(uint16_t id, const char *iconSmall, const char *iconHexagon, + const char *label, const char *uid) : + id(id), + iconSmall(iconSmall), + iconHexagon(iconHexagon), + label(label), + uid(uid) {} +}; + +enum AppListStyle { + APPLIST_STYLE, + HEXAGONS_STYLE, + FOOTBALL_STYLE, + WATERFALL_STYLE +}; + +class ApplistPresenter; +class ApplistModel { +public: + static ApplistModel &GetInstance(void); + + void Init(); + const AppItem *GetApplistItems() const; + uint8 GetAppListNum() const; + void ResolvingJSAppItems(void); + void SetStartIndex(uint16_t index); + uint16_t GetStartIndex(void); + void SetHeadItemY(int index); + int GetHeadItemY(void); + void ApplistUpdate(void); + void SetPresenter(ApplistPresenter *p); + AppListStyle GetCurrentStyle(void); + void SetInitFlag(bool flag); + +private: + ApplistModel(); + ApplistModel(const ApplistModel &); + ApplistModel &operator=(const ApplistModel &); + virtual ~ApplistModel(); + ApplistPresenter *presenter{nullptr}; + + AppItem applist[APP_MAX_NUM]; + BundleInfo *bundleInfos = nullptr; + int32 bundleLen = 0; + uint8 appLen = 0; + + uint16_t startIndex = 0; + int headItemY = 0; + bool initFlag{false}; +}; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistPresenter.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistPresenter.h index 5849d2d63..1275b0a5d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistPresenter.h @@ -10,9 +10,9 @@ #include "Presenter.h" #include "ohos_types.h" -#include "AppItemView.h" -#include "ApplistView.h" -#include "ApplistModel.h" +#include "applist/AppItemView.h" +#include "applist/ApplistView.h" +#include "applist/ApplistModel.h" #include "components/root_view.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistView.h index aedb6381d..ab2ce4adb 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/applist/include/ApplistView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/applist/ApplistView.h @@ -20,7 +20,7 @@ #include "components/ui_icosahedron_view.h" #include "gfx_utils/list.h" #include "ohos_types.h" -#include "ApplistAdapter.h" +#include "applist/ApplistAdapter.h" #include "ChangeSliceListener.h" #include "drag_event.h" #include "UiConfig.h" @@ -113,6 +113,7 @@ public: void OnStart() override; void OnStop() override; + void LoadAppIconImage(UIImageView *view, const uint32_t id, const char *path); void AddAppItemToList(const AppItem &item); void ClearAppItemToList(); void RefreshAppList(void); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodModel.h new file mode 100644 index 000000000..47a2cae25 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodModel.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingModel.h + * Author: + * Create: 2025-03-23 + */ + +#ifndef BLOOD_MODEL_H +#define BLOOD_MODEL_H + +#include +#include +#include "graphic_timer.h" + +namespace OHOS { + class BloodModel { + public: + static BloodModel &GetInstance(void); + bool GetbuttonStatus(); + void SetbuttonStatus(bool status); + std::string GetCurrentTimeString(); + void StartCurrentTimeTimer(); + void PauseCurrentTimeTimer(); + private: + virtual ~BloodModel(); + BloodModel(); + BloodModel(const BloodModel &); + void InitCurrentTimeTimer(); + void DisableCurrentTimeTimer(); + BloodModel &operator=(const BloodModel &); + bool buttonStatus = 0; + GraphicTimer *pCurrentTimeTimer_ = nullptr; + }; +} +#endif // BLOOD_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodPresenter.h new file mode 100644 index 000000000..893d57789 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodPresenter.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingPresenter.h + * Author: + * Create: 2025-03-23 + */ + +#ifndef BLOOD_PRESENTER_H +#define BLOOD_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" + +namespace OHOS { +typedef enum { + BLOOD_START, + BLOOD_TEST, + BLOOD_MORE, + MAX_BLOOD_PAGE, +} PageId; +constexpr short SET_ZERO = 0; +constexpr short SET_ONE = 1; +constexpr short SET_TWO = 2; +constexpr short SET_THREE = 3; +constexpr short SET_FOUR = 4; +constexpr short SET_FIVE = 5; +constexpr short TEMP_SET_SIX = 6; +constexpr short SET_SEVEN = 7; +constexpr short SET_EIGHT = 8; +constexpr short SET_NINE = 9; +constexpr short SET_HUNDRED = 100; +constexpr short SET_INT_MAX = 255; +class BloodView; +class BloodModel; +class BloodPresenter : public Presenter, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + BloodPresenter(); + ~BloodPresenter() override; + static BloodPresenter *GetInstance(); + + void OnResume() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + void OnPause() override; + bool ClickFuncId(const char *buttonName); + +private: + BloodModel *findPhoneModel; +}; +} + +#endif // BLOOD_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodView.h new file mode 100644 index 000000000..f28958afa --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/blood/BloodView.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingView.h + * Author: + * Create: 2025-03-23 + */ + +#ifndef BLOOD_VIEW_H +#define BLOOD_VIEW_H + +#include "View.h" +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_digital_clock.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_image_animator.h" +#include "ChangeSliceListener.h" +#include "test_case_list_adapter.h" +#include "UiConfig.h" +#include "blood/BloodModel.h" +#include "blood/BloodPresenter.h" +#include "layout/grid_layout.h" +#include "ui_test.h" +namespace OHOS { +class BloodPresenter; + +class BloodModel; +class BloodView : public View { +public: + BloodView(); + ~BloodView() override; + + static BloodView *GetInstance(); + + void OnStart() override; + void OnStop() override; + bool ClickButtonChange(bool status); + void SetupCurrentTime(); + void SetupImageAnimator(); + void UpdateCurrentTimeLabel(const char *currentTime); + bool IsCurrentTimeLabelValid(); + void SetUpImageAnimator(); + void SetupButton(); + void InitImageInfo(); + + void InitStart(); + void InitTest(); + void InitMore(); + bool TempInitLabel(void); + bool InitSimilarLabel(int16 num, int16 labelY, const char *labelText); + void ChangeView(int16 hideView, int16 showView); + + void DropView(UIView& view, int type); + bool ClickFunc(int16 interf); + bool ChangeBloodStart(int16_t thisView); + bool ChangeBloodTest(int16_t thisView); + bool ChangeBloodMore(int16_t thisView); +private: + UIView::OnDragListener *dragListener_ = nullptr; + TestCaseListAdapter* adapter_ = nullptr; + BloodModel *findPhoneModel; + UILabel *currentTime_{nullptr}; + GridLayout* layout_ = nullptr; + + UIViewGroup* container[MAX_BLOOD_PAGE] = {nullptr}; + UIViewGroup *group = nullptr; + UIViewGroup *groupTest = nullptr; + UIScrollView *scrollGroup = nullptr; + UILabelButton* button = nullptr; + UILabelButton* buttonMore = nullptr; + UILabel *label1_ = nullptr; + UILabel *label2_ = nullptr; + + ImageInfo* imageInfo1_ = nullptr; + ImageInfo* imageInfo2_ = nullptr; + ImageInfo* imageInfo3_ = nullptr; + ImageAnimatorInfo imageAnimatorImageInfo_[3] = { 0 }; + UIImageAnimatorView* imageAnimator_ = nullptr; + + UILabel *tempTitle{nullptr}; + UILabel *tempLabel[SET_THREE]{nullptr}; +}; +} +#endif // BLOOD_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodBandoffView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodBandoffView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodBandoffView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodBandoffView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenModel.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenModel.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenPresenter.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenPresenter.h index e36393704..70ca55d57 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenPresenter.h @@ -9,7 +9,7 @@ #define BLOOD_OXYGEN_PRESENTER_H #include "Presenter.h" -#include "ModelListenerSample.h" +#include "main/ModelListenerSample.h" #include "components/ui_circle_progress.h" #include "ohos_types.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenView.h index 6ea38268d..059e1d517 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bloodoxygen/include/BloodOxygenView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bloodoxygen/BloodOxygenView.h @@ -17,8 +17,8 @@ #include "components/ui_image_animator.h" #include "components/ui_circle_progress.h" #include "components/ui_view_group.h" -#include "BloodOxygenPresenter.h" -#include "BloodBandoffView.h" +#include "bloodoxygen/BloodOxygenPresenter.h" +#include "bloodoxygen/BloodBandoffView.h" namespace OHOS { class BloodOxygenView : public View { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothCaseListAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothCaseListAdapter.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothCaseListAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothCaseListAdapter.h index 49a590a5b..7cdad65ab 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothCaseListAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothCaseListAdapter.h @@ -11,8 +11,8 @@ #include "components/abstract_adapter.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "PlayersPresenter.h" -#include "BluetoothItemView.h" +#include "player/PlayersPresenter.h" +#include "bluetooth/BluetoothItemView.h" namespace OHOS { class BluetoothCaseListAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothChangeBle.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothChangeBle.h new file mode 100644 index 000000000..fb6b0435b --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothChangeBle.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) @CompanyNameMagicTag 2021-2023. All rights reserved. + * Description: transmit header file + * This file should be changed only infrequently and with great care. + */ +#ifndef BLUETOOTH_CHANGE_BLE_H +#define BLUETOOTH_CHANGE_BLE_H + +#ifdef __cplusplus +extern "C" { +#endif +void ChangeBleConnectToMax(void); +void ChangeBleConnectToDefault(void); +#ifdef __cplusplus +} +#endif +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothDeviceCaseListAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothDeviceCaseListAdapter.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothDeviceCaseListAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothDeviceCaseListAdapter.h index a2b0e2371..bb641b0ec 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothDeviceCaseListAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothDeviceCaseListAdapter.h @@ -11,7 +11,7 @@ #include "components/abstract_adapter.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "BluetoothItemView.h" +#include "bluetooth/BluetoothItemView.h" namespace OHOS { class BluetoothDeviceCaseListAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothDeviceListView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothDeviceListView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothDeviceListView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothDeviceListView.h index 72b9b9871..29b302459 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothDeviceListView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothDeviceListView.h @@ -11,7 +11,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_list.h" -#include "BluetoothDeviceCaseListAdapter.h" +#include "bluetooth/BluetoothDeviceCaseListAdapter.h" namespace OHOS { class BluetoothDeviceCaseListAdapter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothEarListView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothEarListView.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothEarListView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothEarListView.h index 8a0dd9839..298f4d90d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothEarListView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothEarListView.h @@ -12,7 +12,7 @@ #include "components/ui_label_button.h" #include "components/ui_image_animator.h" #include "components/ui_list.h" -#include "BluetoothCaseListAdapter.h" +#include "bluetooth/BluetoothCaseListAdapter.h" namespace OHOS { class BluetoothCaseListAdapter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothEarPhoneView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothEarPhoneView.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothEarPhoneView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothEarPhoneView.h index 3636a1af1..e7f40ecd7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothEarPhoneView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothEarPhoneView.h @@ -14,7 +14,7 @@ #include "components/ui_image_animator.h" #include "ohos_timer.h" #include "graphic_timer.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothModel.h" #define BLUETOOTH_SEARCH_IMAGE_NUM 8 namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothHeadsetEvent.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothHeadsetEvent.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothHeadsetEvent.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothHeadsetEvent.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothItemView.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothItemView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothItemView.h index 563fe825d..ed4847891 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothItemView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothItemView.h @@ -14,7 +14,7 @@ #include "components/ui_label_button.h" #include "components/ui_image_animator.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothModel.h" #include "UiConfig.h" #define BLUETOOTH_CONNECT_IMAGE_NUM 8 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothModel.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothModel.h index 3aef02c0e..632af7b7c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothModel.h @@ -16,6 +16,14 @@ #include "bts_br_gap.h" namespace OHOS { +constexpr uint16_t BLUETOOTH_CONN_HANDLE = 64; +constexpr uint16_t BLUETOOTH_INTERVAL_TOMAX_MIN = 12; +constexpr uint16_t BLUETOOTH_INTERVAL_TOMAX_MAX = 12; +constexpr uint16_t BLUETOOTH_INTERVAL_TODEFAULT_MIN = 24; +constexpr uint16_t BLUETOOTH_INTERVAL_TODEFAULT_MAX = 48; +constexpr uint16_t BLUETOOTH_LATENCY = 0; +constexpr uint16_t BLUETOOTH_TIMEOUT_MUTIPLIER = 500; + typedef enum : uint16_t { CALLERSETTING, CALLERPLAYERS, @@ -81,7 +89,9 @@ public: int ConnectRemoteDevice(const bd_addr_t *addr); bool ConnectRemoteCheck(const bd_addr_t *addr); char* getWatchName(void); - + void ChangeBleConnectToMax(); + void ChangeBleConnectToDefault(); + private: BluetoothModel(); int16_t callerid{0}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothOptionsView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothOptionsView.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothOptionsView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothOptionsView.h index 836df4bcb..0573986f5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothOptionsView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothOptionsView.h @@ -11,7 +11,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_image_animator.h" -#include "BluetoothCaseListAdapter.h" +#include "bluetooth/BluetoothCaseListAdapter.h" namespace OHOS { class BluetoothOptionsView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothPresenter.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothPresenter.h index fa72f28f9..3a70f4dc3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothPresenter.h @@ -8,14 +8,14 @@ #define BLUETOOTH_PRESENTER_H #include "Presenter.h" -#include "BluetoothModel.h" -#include "MainBluetoothView.h" +#include "bluetooth/BluetoothModel.h" +#include "bluetooth/MainBluetoothView.h" #include "components/ui_view.h" #include "components/ui_image_view.h" #include "components/ui_label_button.h" #include "components/ui_view_group.h" -#include "VolumeSettingView.h" -#include "UiViewId.h" +#include "main/VolumeSettingView.h" +#include "main/UiViewId.h" namespace OHOS { enum BluetoothPresenterNum : uint8_t { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothReconnectView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothReconnectView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothReconnectView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothReconnectView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothWrapper.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothWrapper.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/BluetoothWrapper.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/BluetoothWrapper.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/MainBluetoothView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/MainBluetoothView.h similarity index 81% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/MainBluetoothView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/MainBluetoothView.h index e564e2ced..3f04896cb 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/MainBluetoothView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/MainBluetoothView.h @@ -10,17 +10,17 @@ #include "View.h" #include "UiConfig.h" #include "ChangeSliceListener.h" -#include "BluetoothPresenter.h" -#include "BluetoothCaseListAdapter.h" -#include "BluetoothEarListView.h" -#include "BluetoothEarPhoneView.h" -#include "BluetoothOptionsView.h" -#include "BluetoothReconnectView.h" -#include "TipsConnFailMessageView.h" -#include "TipsSuccMessageView.h" -#include "TipsFailMessageView.h" -#include "BluetoothDeviceListView.h" -#include "BluetoothItemView.h" +#include "bluetooth/BluetoothPresenter.h" +#include "bluetooth/BluetoothCaseListAdapter.h" +#include "bluetooth/BluetoothEarListView.h" +#include "bluetooth/BluetoothEarPhoneView.h" +#include "bluetooth/BluetoothOptionsView.h" +#include "bluetooth/BluetoothReconnectView.h" +#include "bluetooth/TipsConnFailMessageView.h" +#include "bluetooth/TipsSuccMessageView.h" +#include "bluetooth/TipsFailMessageView.h" +#include "bluetooth/BluetoothDeviceListView.h" +#include "bluetooth/BluetoothItemView.h" namespace OHOS { constexpr int16_t NUM_CONTAINER = 9; // NUM_CONTAINER :蓝牙耳机连接的9个界面容器 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/TipsConnFailMessageView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/TipsConnFailMessageView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/TipsConnFailMessageView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/TipsConnFailMessageView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/TipsFailMessageView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/TipsFailMessageView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/TipsFailMessageView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/TipsFailMessageView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/TipsSuccMessageView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/TipsSuccMessageView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/bluetooth/include/TipsSuccMessageView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/bluetooth/TipsSuccMessageView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathDurPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathDurPage.h new file mode 100644 index 000000000..0376dbed5 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathDurPage.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathDurPage + * Create: 2025-5-13 + */ +#ifndef BREATH_DUR_PAGE_H +#define BREATH_DUR_PAGE_H + +#include +#include "components/ui_label.h" +#include "components/ui_picker.h" +#include "components/ui_image_view.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label_button.h" +#include "components/ui_toggle_button.h" +#include "View.h" +#include "UiConfig.h" +#include "SlicePage.h" +#include "SlicePageFactory.h" +#include "breath/BreathModel.h" +#include "breath/BreathPresenter.h" + +namespace OHOS { + +class BreathDurPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + BreathDurPage(); + ~BreathDurPage() override; + void OnStart(void* data) override; + void OnStop() override; + void OnResume() override; + void OnPause() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; +private: + UILabel *lableTitle = nullptr; + UIPicker *pickerTime = nullptr; + UIButton *buttonOk = nullptr; + UIViewGroup *group = nullptr; + UIImageView *center = nullptr; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathExerPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathExerPage.h new file mode 100644 index 000000000..3f3513bfa --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathExerPage.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathExerPage + * Create: 2025-5-13 + */ +#ifndef BREATH_EXER_PAGE_H +#define BREATH_EXER_PAGE_H + +#include "layout/grid_layout.h" +#include "components/ui_label.h" +#include "components/ui_digital_clock.h" +#include "components/ui_image_animator.h" +#include "View.h" +#include "SlicePage.h" +#include "graphic_timer.h" +#include "SlicePageFactory.h" +#include "power_display_service.h" +#include "breath/BreathModel.h" +#include "breath/BreathPresenter.h" + +#define ALIPAY_BIND_SEARCH_IMAGE_NUM 80 +#define SPEED_IDX_3 3 + +namespace OHOS { +class BreathExerPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + BreathExerPage(); + ~BreathExerPage() override; + void OnStart(void* data) override; + void OnStop() override; + void OnPause() override; + bool OnDrag(UIView &view, const DragEvent &event) override; + void OnTimer(); + void SetUpImageAnimator(); + void InitImageInfo(); + +private: + UIViewGroup *group = nullptr; + UIImageAnimatorView* imageAnimator_ = nullptr; + ImageInfo* imageInfoOen = nullptr; + ImageInfo* imageInfoTwo = nullptr; + ImageInfo* imageInfoThree = nullptr; + uint32_t palyNumber; + ImageAnimatorInfo imageAnimatorImageInfo[SPEED_IDX_3] = { 0 }; + ImageAnimatorInfo searchImageInfo[ALIPAY_BIND_SEARCH_IMAGE_NUM]; + + class BreathExerPageCallback : public AnimatorCallback { + public: + BreathExerPageCallback(BreathExerPage* page) : BreathExerPage(page) {} + virtual ~BreathExerPageCallback() override {} + void Callback(UIView* view) override; + private: + BreathExerPage* BreathExerPage{nullptr}; + }; + BreathExerPageCallback* animatorCallBack{nullptr}; + Animator *animation = nullptr; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathMainPage.h new file mode 100644 index 000000000..bd06de488 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathMainPage.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathMainPage + * Create: 2025-5-13 + */ +#ifndef BREATH_MAIN_PAGE_H +#define BREATH_MAIN_PAGE_H + +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "components/ui_digital_clock.h" +#include "components/ui_image_animator.h" +#include "View.h" +#include "SlicePageFactory.h" +#include "SlicePage.h" +#include "breath/BreathView.h" +#include "breath/BreathModel.h" +#include "breath/BreathPresenter.h" + +namespace OHOS { + +class BreathMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + BreathMainPage() = default; + ~BreathMainPage() override; + void OnStart(void* data) override; + void OnStop() override; + void OnResume() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + +private: + UILabel *lableBreathing = nullptr; + UIButton *buttonTime = nullptr; + UIButton *buttonSetting = nullptr; + UIButton *buttonStart = nullptr; + UILabel *lableSetting = nullptr; + UILabel *lableTime = nullptr; + UIViewGroup *group = nullptr; + UIImageView *background = nullptr; + UIImageView *center = nullptr; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathModel.h new file mode 100644 index 000000000..701040381 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathModel.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathModel + * Create: 2025-5-13 + */ +#ifndef BREATH_MODEL_H +#define BREATH_MODEL_H + +#include "gfx_utils/graphic_math.h" +namespace OHOS { +#define SPEED_IDX_3 3 +class BreathModel { +public: + static BreathModel &GetInstance(); + virtual ~BreathModel(); + const char **GetDurListData(); + const char **GetRhyListData(); + uint8_t GetDurListSize(); + uint8_t GetRhyListSize(); + char *GetTimeDuration(); + void SetTimeDuration(uint16_t idx); + void SetTimeRhyation(uint16_t idx); + uint8_t GetSelectTime(); + uint8_t GetSelectTempo(); + char *GetDuration(); + char *GetRhythm(); + void SetSaveTime(int32_t idx); + int32_t GetSaveTime(); + uint32_t GetTimeBreathing(); + uint32_t GetStatusRespiratory(); + void SetBeginsTime(int32_t idx); + int32_t GetBeginsTime(); + void SetFrequencyScore(); + uint8_t GetFrequencyScore(); + void SetHeartRate(); + uint8_t GetHeartRate(); + uint32_t GetTheNumberOfPlays(); + +protected: + void DefaultData(); + +private: + BreathModel(); + BreathModel(const BreathModel &); + BreathModel &operator=(const BreathModel &); + const char *durList[SPEED_IDX_3]; + const char *rhyList[SPEED_IDX_3]; + uint32_t durListVal[SPEED_IDX_3]; + uint32_t rhyListVal[SPEED_IDX_3]; + uint16_t data; + uint16_t date; + int32_t saveTime; + int32_t beginsTime; +}; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathPresenter.h new file mode 100644 index 000000000..1b1f6c091 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathPresenter.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathPresenter + * Create: 2025-5-23 + */ + +#ifndef Breath_PRESENTER_H +#define Breath_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { +constexpr int16_t SET_INT_MAX_ = 255; + +class BreathView; +class BreathPresenter : public Presenter {}; +} + +#endif // Breath_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathResultPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathResultPage.h new file mode 100644 index 000000000..0f2b1a471 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathResultPage.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathResult + * Create: 2025-5-13 + */ +#ifndef BREATH_RESULT_PAGE_H +#define BREATH_RESULT_PAGE_H + +#include "components/ui_label.h" +#include "components/ui_picker.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label_button.h" +#include "components/ui_toggle_button.h" +#include "View.h" +#include "UiConfig.h" +#include "SlicePage.h" +#include "SlicePageFactory.h" +#include "breath/BreathModel.h" +#include "breath/BreathPresenter.h" + +namespace OHOS { + +class BreathResultPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + BreathResultPage(); + ~BreathResultPage() override; + void OnStart(void* data) override; + void OnStop() override; + void OnResume() override; + bool OnDrag(UIView &view, const DragEvent &event) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + +private: + UILabel *trainingResults = nullptr; + UILabel *trainingFrequencies = nullptr; + UILabel *trainingHeartRate = nullptr; + UILabel *trainingDuration = nullptr; + UILabel *heartRateScout = nullptr; + UILabel *frequenciesScout = nullptr; + UIImageView *scores = nullptr; + UILabel *descriptionBreathing = nullptr; + UILabel *time = nullptr; + UILabel *timeUnit = nullptr; + UILabel *frequencyTimes = nullptr; + UILabel *heartRateTimes = nullptr; + UIViewGroup *group = nullptr; + uint8_t frequencyScore; + uint8_t heartRate; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathRhyPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathRhyPage.h new file mode 100644 index 000000000..2c9780d5d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathRhyPage.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathRhyPage + * Create: 2025-5-13 + */ +#ifndef BREATH_RHY_PAGE_H +#define BREATH_RHY_PAGE_H + +#include "components/ui_label.h" +#include "components/ui_picker.h" +#include "components/ui_image_view.h" +#include "components/ui_label_button.h" +#include "View.h" +#include "SlicePage.h" +#include "SlicePageFactory.h" +#include "breath/BreathModel.h" +#include "breath/BreathPresenter.h" + +namespace OHOS { + +class BreathRhyPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener, + public UIPicker::SelectedListener { +public: + BreathRhyPage(); + ~BreathRhyPage() override; + void OnStart(void* data) override; + void OnResume() override; + void OnPause() override; + void OnStop() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + +private: + UILabel *lableRhythm = nullptr; + UIPicker *pickerRhythm = nullptr; + UIButton *buttonOk = nullptr; + UIViewGroup *group = nullptr; + UIImageView *center = nullptr; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathStartPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathStartPage.h new file mode 100644 index 000000000..86b1a9f4b --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathStartPage.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathStartPage + * Create: 2025-5-13 + */ +#ifndef BREATH_START_PAGE_H +#define BREATH_START_PAGE_H + +#include "components/ui_label.h" +#include "components/ui_image_view.h" +#include "View.h" +#include "SlicePage.h" +#include "graphic_timer.h" +#include "SlicePageFactory.h" +#include "breath/BreathModel.h" +#include "breath/BreathPresenter.h" + +namespace OHOS { + +class BreathStartPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + BreathStartPage(); + ~BreathStartPage() override; + void OnStart(void* data) override; + void OnStop() override; + void OnTimer(); + bool OnDrag(UIView &view, const DragEvent &event) override; + void OnPause() override; +private: + UILabel *titleLable = nullptr; + UILabel *guideLable = nullptr; + UIImageView *centerImge = nullptr; + UIViewGroup *group = nullptr; + UIImageView *background = nullptr; + + class BreathStartCallback : public AnimatorCallback { + public: + BreathStartCallback(BreathStartPage* page) : BreathStartPage(page) {} + virtual ~BreathStartCallback() override {} + void Callback(UIView* view) override; + private: + BreathStartPage* BreathStartPage{nullptr}; + }; + BreathStartCallback* animatorCallBack{nullptr}; + Animator *animation = nullptr; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathView.h new file mode 100644 index 000000000..0cfa80156 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/breath/BreathView.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: BreathView + * Create: 2025-5-14 + */ + +#ifndef BREATH_VIEW_H +#define BREATH_VIEW_H + +#include "View.h" +namespace OHOS { +enum BrearhView { + BREATH_MAIN_VIEW = 1, + BREATH_DUR_VIEW = 2, + BREATH_EXER_VIEW = 3, + BREATH_RHY_VIEW = 4, + BREATH_START_VIEW = 5, + BREATH_RESULT_VIEW = 6, +}; + +class BreathPresenter; +class BreathView : public View {}; +} +#endif // BREATH_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerItemView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerItemView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerItemView.h index 50f2c345d..907f47d78 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerItemView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerItemView.h @@ -13,9 +13,9 @@ #include "components/ui_image_view.h" #include "components/ui_label_button.h" -#include "CallerLogModel.h" +#include "callerlog/CallerLogModel.h" #include "UiConfig.h" -#include "PhoneService.h" +#include "phoneservice/PhoneService.h" namespace OHOS { class CallerItemView : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogModel.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogModel.h index 22e6b403a..d4d51a414 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogModel.h @@ -8,7 +8,7 @@ #define CALLER_LOG_MODEL_H #include "string" -#include "PhoneService.h" +#include "phoneservice/PhoneService.h" #include "AppViewIDs.h" #include "message.h" #include "msg_center.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogPresenter.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogPresenter.h index d5cde172c..e90602125 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogPresenter.h @@ -10,7 +10,7 @@ #include "Presenter.h" #include "ohos_types.h" -#include "CallerLogModel.h" +#include "callerlog/CallerLogModel.h" #include "graphic_timer.h" #include "sys/time.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogView.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogView.h index 0fbe3a4ce..a9594f02c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/callerlog/include/CallerLogView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/callerlog/CallerLogView.h @@ -9,8 +9,8 @@ #define CALLER_LOG_VIEW_H #include "View.h" -#include "CallerLogPresenter.h" -#include "CallerItemView.h" +#include "callerlog/CallerLogPresenter.h" +#include "callerlog/CallerItemView.h" #include "components/ui_view_group.h" #include "components/ui_image_animator.h" #include "components/ui_scroll_view.h" @@ -18,7 +18,7 @@ #include "components/ui_label_button.h" #include "components/ui_list.h" #include "components/abstract_adapter.h" -#include "PhoneService.h" +#include "phoneservice/PhoneService.h" #include "vector.h" #include "ChangeSliceListener.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraMainPage.h new file mode 100644 index 000000000..01aa7b8de --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraMainPage.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraMainPage + * Created: 2025-06-05 + */ + +#ifndef CAMERA_MAIN_PAGE_H +#define CAMERA_MAIN_PAGE_H + +#include +#include "View.h" +#include "components/root_view.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_digital_clock.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_image_animator.h" +#include "ChangeSliceListener.h" +#include "UiConfig.h" +#include "layout/grid_layout.h" +#include "SlicePageFactory.h" +#include "SlicePage.h" +#include "diag_service.h" +#include "ohos_timer.h" +#include "components/ui_chart.h" +#include "camera/CameraModel.h" +#include "camera/CameraPresenter.h" + +namespace OHOS { + +class CameraPresenter; + +class CameraModel; +class CameraMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + CameraMainPage(); + ~CameraMainPage() override; + + static CameraMainPage *GetInstance(); + + void OnStart(void* data) override; + uint8_t GetConnectStatus(); + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + void OnPause() override; + + bool GetFirstFlag(); + void SetFirstFlag(bool value); + void SetUpButton(); + void InitCameraTimer(); + void InitCameraView(); + void DisableCameraTimer(); + void SetCameraTime(int time); + void StopAnimator(); + void PhotoTaken(); + void Refresh_page(); +private: + UILabel *title = nullptr; + UILabel *cameraFind = nullptr; + UILabel *cameraTitle = nullptr; + UILabel *cameraTime = nullptr; + UIButton *button = nullptr; + bool isFirst; + UIScrollView* container_ = nullptr; + UIImageView *bluetoothDisconnected = nullptr; + +class CameraAnimatorCallback : public AnimatorCallback { +public: + explicit CameraAnimatorCallback(CameraMainPage* page) : page_(page) {} + ~CameraAnimatorCallback() override {} + void Callback(UIView *view) override; + +private: + CameraMainPage* page_{nullptr}; +}; + Animator *animator_ = nullptr; + CameraAnimatorCallback *callBack_ = nullptr; +}; +} +#endif // CAMERA_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraModel.h new file mode 100644 index 000000000..61a9c5ed5 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraModel.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraModel + * Created: 2025-06-05 + */ + +#ifndef CAMERA_MODEL_H +#define CAMERA_MODEL_H + +#include +#include +#include "graphic_timer.h" + +namespace OHOS { +class CameraModel { +public: + static CameraModel &GetInstance(void); +private: + CameraModel(); + CameraModel(const CameraModel &); + CameraModel &operator=(const CameraModel &); + virtual ~CameraModel(); + bool buttonStatus = 0; +}; +} + +#endif // CAMERA_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraPresenter.h new file mode 100644 index 000000000..dced5767c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraPresenter.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraPresenter + * Created: 2025-06-05 + */ + +#ifndef CAMERA_PRESENTER_H +#define CAMERA_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" + +namespace OHOS { + +class CameraView; +class CameraPresenter : public Presenter { +}; +} + +#endif // CAMERA_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraView.h new file mode 100644 index 000000000..d939d9d5e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/camera/CameraView.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: CameraView + * Created: 2025-06-05 + */ + +#ifndef CAMERA_VIEW_H +#define CAMERA_VIEW_H + +#include "View.h" +namespace OHOS { +enum CAMERA_PAGES { + CAMERA_MAIN_PAGE = 1, // 0 is invalid +}; + +class CameraPresenter; +class CameraView : public View { +}; +} +#endif // CAMERA_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/clock/include/AmbientClockView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/clock/AmbientClockView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/clock/include/AmbientClockView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/clock/AmbientClockView.h index 2d02ca41e..bb20b9c1c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/clock/include/AmbientClockView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/clock/AmbientClockView.h @@ -21,8 +21,8 @@ #include "font/ui_font_bitmap.h" #include "font/ui_font.h" #include "graphic_config.h" -#include "HealthModel.h" -#include "ActivityModel.h" +#include "main/HealthModel.h" +#include "activity/ActivityModel.h" #include "UiConfig.h" #include "components/ui_card_page.h" #include "animator/animator_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/clock/include/MainClockView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/clock/MainClockView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/clock/include/MainClockView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/clock/MainClockView.h index 4e4fb8894..c643693d5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/clock/include/MainClockView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/clock/MainClockView.h @@ -21,8 +21,8 @@ #include "font/ui_font_bitmap.h" #include "font/ui_font.h" #include "graphic_config.h" -#include "HealthModel.h" -#include "ActivityModel.h" +#include "main/HealthModel.h" +#include "activity/ActivityModel.h" #include "UiConfig.h" #include "components/ui_card_page.h" #include "animator/animator_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassControlView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassControlView.h new file mode 100644 index 000000000..e2242e1c8 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassControlView.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. + * Description: CompassControlView.h + * Author: + * Create: 2022-04-02 + */ + +#ifndef COMPASS_CONTROL_VIEW_H +#define COMPASS_CONTROL_VIEW_H + +#include "components/ui_card_page.h" +#include "compass/CompassFragment.h" + +namespace OHOS { + +class CompassControlView : public UICardPage { +public: + CompassControlView(); + void PreLoad(void) override; + void UnLoad(void) override; + void OnPause(void) override; + void OnActive(void) override; + void ScrollBegin(bool isActive) override; + void ScrollEnd(bool isActive) override; +private: + CompassFragment *compassFragment_{nullptr}; +}; +} +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassFragment.h b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassFragment.h new file mode 100644 index 000000000..64c6ee054 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassFragment.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: CompassView.h + * Author: + * Create: 2021-12-21 + */ + +#ifndef COMPASS_VIEW_H +#define COMPASS_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_image_view.h" +#include "components/ui_fragment.h" +#include "common/task.h" + +namespace OHOS { +class CompassFragment : public UIFragment, public Task { +public: + void OnCreateView(void* data) override; + void OnResumeView() override; + void OnPauseView() override; + void OnDestroyView() override; + void Callback() override; + +private: + bool InitCompassImage(void); + bool LoadCompassImage(UIImageView *view, uint32_t resId); + UILabel *directionLabel_{nullptr}; + UILabel *angleLabel_{nullptr}; + UIImageView *bgImg_{nullptr}; + UIImageView *fgImg_{nullptr}; + UIImageView *trianImg_{nullptr}; + bool initialized_{false}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassModel.h new file mode 100644 index 000000000..880617419 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/CompassModel.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. + * Description: CompassModel.h + * Author: + * Create: 2022-04-02 + */ + +#ifndef COMPASS_MODEL_H +#define COMPASS_MODEL_H + +#include + +namespace OHOS { +class CompassModel { +public: + static CompassModel *GetInstance(void); + bool OpenCompassSensor(void); + bool CloseCompassSensor(void); + void UpdateAngle(void); + void ResetAngle(void); + int16_t GetAngle(void); + +private: + int16_t angle_{0}; + bool clockwise_{true}; +}; +} + +#endif + diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassPresenter.h new file mode 100644 index 000000000..2588f0a43 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassPresenter.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MainCompassPresenter.h + * Author: + * Create: 2021-12-21 + */ +#ifndef COMPASS_MAINPRESENTER_H +#define COMPASS_MAINPRESENTER_H + +#include "Presenter.h" +#include "compass/MainCompassView.h" +#include "compass/CompassModel.h" + +namespace OHOS { +class MainCompassView; +class MainCompassPresenter : public Presenter, public UIView::OnDragListener { +public: + bool OnDrag(UIView& view, const DragEvent& event) override; + + void OnResume() override; + + void OnPause() override; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassView.h new file mode 100644 index 000000000..4694861fd --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/compass/MainCompassView.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MainCompassView + * Author: + * Create: 2021-12-23 + */ + +#ifndef MAIN_COMPASS_VIEW_H +#define MAIN_COMPASS_VIEW_H + +#include "View.h" +#include "compass/CompassFragment.h" + +namespace OHOS { +class MainCompassPresenter; +class MainCompassView : public View { +public: + MainCompassView() : compassFragment_(nullptr) {} + void OnStart() override; + void OnStop() override; + +private: + friend class MainCompassPresenter; + CompassFragment *compassFragment_; +}; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectOpenView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectOpenView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectOpenView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectOpenView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectPhonePresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectPhonePresenter.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectPhonePresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectPhonePresenter.h index 2bb8fe69c..d55eab049 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectPhonePresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectPhonePresenter.h @@ -8,7 +8,7 @@ #define CONNECT_PHONE_PRESENTER_H #include "Presenter.h" -#include "ConnectOpenView.h" +#include "connectnewphone/ConnectOpenView.h" #include "NativeLauncher.h" #include "NativeAbility.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectPhoneView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectPhoneView.h similarity index 85% rename from code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectPhoneView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectPhoneView.h index d74226c55..1a248987a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectPhoneView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectPhoneView.h @@ -8,9 +8,9 @@ #define CONNECT_PHONE_VIEW_H #include "View.h" -#include "ConnectPhonePresenter.h" -#include "ConnectSelectView.h" -#include "AppGroupView.h" +#include "connectnewphone/ConnectPhonePresenter.h" +#include "connectnewphone/ConnectSelectView.h" +#include "main/AppGroupView.h" namespace OHOS { constexpr int16_t NUM_CONNECT_PHONE_CONTAINER = 2; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectSelectView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectSelectView.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectSelectView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectSelectView.h index 48d9695b5..f73d4faf5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/connectnewphone/include/ConnectSelectView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/connectnewphone/ConnectSelectView.h @@ -8,7 +8,7 @@ #define CONNECT_SELECT_VIEW_H #include "View.h" -#include "ConnectPhonePresenter.h" +#include "connectnewphone/ConnectPhonePresenter.h" #include "components/ui_label.h" #include "components/ui_button.h" #include "components/ui_view_group.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateAdapter.h new file mode 100644 index 000000000..676b8007d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateAdapter.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateAdapter + * Create: 2025-03-23 + */ + +#ifndef DATE_ADAPTER_H +#define DATE_ADAPTER_H + +#include +#include +#include "components/ui_list.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/abstract_adapter.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "date/DateModel.h" +#include "date/DateItemView.h" + +namespace OHOS { +class DateAdapter : public AbstractAdapter { +public: + explicit DateAdapter(); + ~DateAdapter() override; + void SetData(std::list &data); + uint16_t GetCount(void) override; + UIView *GetView(UIView *inView, int16_t index) override; + void AddListItem(const DateItem &item); + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } + void ClearListItem(); + +private: + std::list listData; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonAdapter.h new file mode 100644 index 000000000..da4c0136a --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonAdapter.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateButtonAdapter + * Create: 2025-03-23 + */ + +#ifndef DATE_BUTTON_ADAPTER_H +#define DATE_BUTTON_ADAPTER_H + +#include +#include +#include "components/ui_list.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/abstract_adapter.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "date/DateModel.h" +#include "date/DateButtonItemView.h" + +namespace OHOS { +class DateButtonAdapter : public AbstractAdapter { +public: + explicit DateButtonAdapter(); + ~DateButtonAdapter() override; + + void SetData(std::list &data); + uint16_t GetCount(void) override; + UIView *GetView(UIView *inView, int16_t index) override; + void AddListItem(const DateButtonItem &item); + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } + void ClearListItem(); + +private: + std::list listData; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonItemView.h new file mode 100644 index 000000000..c03c4b284 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateButtonItemView.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateButtonItemView + * Create: 2025-03-23 + */ + +#ifndef DATE_BUTTON_ITEM_VIEW_H +#define DATE_BUTTON_ITEM_VIEW_H + +#include "date/DateModel.h" +#include "UiConfig.h" +#include "components/ui_canvas.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" +#include "main/LoadImg.h" + +namespace OHOS { +class DateButtonItemView : public UIViewGroup { +public: + explicit DateButtonItemView(); + ~DateButtonItemView() override; + virtual void SetItemInfo(const DateButtonItem itemInfo); + virtual void SetUpChild(); + DateButtonItem GetItem(); + +private: + static bool flag; + UILabelButton sLabelButton; + DateButtonItem sItemInfo = {nullptr, 0, false, false}; +}; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateItemView.h new file mode 100644 index 000000000..9f7d97676 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateItemView.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateItemView + * Create: 2025-03-23 + */ + +#ifndef DATE_ITEM_VIEW_H +#define DATE_ITEM_VIEW_H + +#include "date/DateModel.h" +#include "UiConfig.h" +#include "components/ui_canvas.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" + +namespace OHOS { +class DateItemView : public UIViewGroup { +public: + explicit DateItemView(); + ~DateItemView() override; + virtual void SetItemInfo(const DateItem itemInfo); + virtual void SetUpChild(); + const char *GetViewId(); + bool GetVisiable(); + +private: + UILabel sLabel_1; + UIImageView sIcon; + UILabel sLabel_2; + UIImageView sNextImage; + UIImageView Schedule; + UIImageView Signs; + UIImageView BackGround; + DateItem sItemInfo = {nullptr, nullptr, nullptr, false}; +}; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMainPage.h new file mode 100644 index 000000000..9bb45843e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMainPage.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateMainPage + * Create: 2025-03-23 + */ + +#ifndef DATE_MAIN_PAGE_H +#define DATE_MAIN_PAGE_H + +#include +#include +#include +#include +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "date/DateAdapter.h" +#include "date/DateButtonAdapter.h" +#include "date/DatePresenter.h" +#include "SlicePage.h" +#include "UiConfig.h" +#include "date/DateView.h" +#include "components/ui_button.h" + +namespace OHOS { +#define LABEL_COUNT 4 +static constexpr int16_t START_YEAR = 1900; + +class DatePresenter; +class DateMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + DateMainPage(); + ~DateMainPage() override; + void OnStart(void* data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + void InitDownList(); + void UpdateMsg(std::string dateMsg); + void SetDownListAdapter(); + bool InitDateTop(); + std::string GetFutureDate(int days_ahead); + void RefreshButtonListDate(int value); +private: + UIScrollView *uiScrollView = nullptr; + DateAdapter *listAdapter{nullptr}; + UIList *downContentList{nullptr}; + UIImageView *image1{nullptr}; + DateButtonAdapter *buttonAdapter{nullptr}; + UIList *buttonContentList{nullptr}; + UILabel *title{nullptr}; + std::list listTop; + std::string strDate[SET_SEVEN]; + std::string strDay[SET_SEVEN]; +}; +} +#endif // SETTING_MAIN_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMessagePage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMessagePage.h new file mode 100644 index 000000000..8a5e59ca6 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateMessagePage.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateMessagePage + * Create: 2025-03-15 + */ + +#ifndef DATE_MESSAGE_H +#define DATE_MESSAGE_H + +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_swipe_view.h" +#include "ui_swipe_view.h" +#include "date/DatePresenter.h" +#include "date/DateModel.h" +#include "date/DateView.h" +#include "SlicePage.h" +#include "UiConfig.h" + +namespace OHOS { +#define LABEL_COUNT 8 +class DatePresenter; +class DateMessagePage : public SlicePage, + public UIView::OnDragListener { +public: + DateMessagePage(); + ~DateMessagePage() override; + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + +private: + UIViewGroup *group; + UIImageView *image1; + UILabel *labelTitle{nullptr}; + UILabel *labelMessage{nullptr}; + UILabel *labelTime{nullptr}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateModel.h new file mode 100644 index 000000000..b86e3e2e6 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateModel.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateModel + * Create: 2025-03-23 + */ + +#ifndef DATE_MODEL_H +#define DATE_MODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hal_tick.h" +#include "AppViewIDs.h" +#include "UiConfig.h" +#include "cJSON.h" + +namespace OHOS { +static constexpr int16 HOUR_COUNT = 24; +static constexpr uint64_t CENTI_SECOND_UNIT = 100; +static constexpr uint64_t MS_ONE_SECONDS = 1000; +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t NUM_TIME_MIN = 60; +static constexpr uint16_t NUM_TIME_HOUR = 3600; +static constexpr int32_t NUM_TIME_DAY = 86400; +static constexpr int16_t MIN_TO_HOUR = 60; +static constexpr int16_t HOURLY_SYSTEM = 24; +typedef struct { + std::string hour; + std::string eventTitle; + std::string startTime; + std::string week; +} DateMsg; + +typedef struct { + const char *label_1; + const char *label_2; + const char *index; + bool visiable; +} DateItem; + +typedef struct { + const char *button_viewId; + const char *button_day; + int index; + bool isFirst; + bool isSelect; +} DateButtonItem; + +static const uint16_t DATE_ITEM_COUNT = 10; +class DateModel { +public: + static DateModel &GetInstance(void); + virtual ~DateModel(); + bool InitDateVec(std::string dateStr); + bool InitDate(); + + const char *GetViewId(); + std::unordered_map> keyValues; + std::list listDate; + std::string now; + std::string titleName; + std::string messageIndex; + std::string strIndex; + +private: + DateModel(); + DateModel(const DateModel &); + DateModel &operator=(const DateModel &); +}; +} + +#endif // DATE_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DatePresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DatePresenter.h new file mode 100644 index 000000000..813c5ba44 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DatePresenter.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DatePresenter + * Create: 2025-03-23 + */ + +#ifndef DATE_PRESENTER_H +#define DATE_PRESENTER_H + +#include "date/DateModel.h" +#include "Presenter.h" +#include "components/ui_view.h" +namespace OHOS { +constexpr int16 BACKGROUND_IMAGE_WIDTH = 190; +constexpr int16 SET_ZERO = 0; +constexpr int16 SET_ONE = 1; +constexpr int16 SET_TWO = 2; +constexpr int16 SET_THREE = 3; +constexpr int16 SET_FOUR = 4; +constexpr int16 SET_FIVE = 5; +constexpr int16 SET_SIX = 6; +constexpr int16 SET_SEVEN = 7; +constexpr int16 SET_EIGHT = 8; +constexpr int16 SET_NINE = 9; +constexpr int16 SET_TEN = 10; +constexpr int16 SET_TWELVE = 12; +constexpr int16 SET_THIRTEEN = 13; +constexpr int16 SET_FOURTEEN = 14; +constexpr int16 SET_HUNDRED = 100; +constexpr int16 SET_TWO_HUNDRED = 200; + +class DateView; +class DatePresenter : public Presenter {}; +} + +#endif // DATE_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateView.h new file mode 100644 index 000000000..8271b29e0 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/date/DateView.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: DateView + * Create: 2025-03-23 + */ + +#ifndef DATE_VIEW_H +#define DATE_VIEW_H + +#include "View.h" +namespace OHOS { +enum DATE_PAGES { + DATE_MAIN_PAGE = 1, // 0 is invalid + DATE_MESSAGE_PAGE = 2, +}; + +class DatePresenter; +class DateView : public View {}; +} +#endif // Date_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPage.h new file mode 100644 index 000000000..0b497c751 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPage.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: EmptyPage + * Create: 2025-04-24 + */ +#ifndef EMPTY_PAGE_H +#define EMPTY_PAGE_H +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "SlicePage.h" +#include "emptypage/EmptyPresenter.h" + +namespace OHOS { + +class EmptyPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + EmptyPage(){}; + ~EmptyPage(); + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + EmptyPage(const EmptyPage &) = delete; + EmptyPage &operator=(const EmptyPage &) = delete; + EmptyPage(EmptyPage &&) = delete; + EmptyPage &operator=(EmptyPage &&) = delete; + + UIScrollView *container_ = nullptr; + UILabel *memLabel_ = nullptr; + uint32_t used_ = 0; + uint32_t free_ = 0; +}; + +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(_WIN32) +uint32_t test_get_mem_info(uint8_t memType, uint32_t *used, uint32_t *free); +#endif +#ifdef __cplusplus +} +#endif +} // namespace OHOS +#endif /* EMPTY_PAGE_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPresenter.h new file mode 100644 index 000000000..ca245c8d2 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyPresenter.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: EmptyPresenter + * Create: 2025-04-24 + */ + +#ifndef EMPTY_PRESENTER_H +#define EMPTY_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { +class EmptyView; +class EmptyPresenter : public Presenter {}; +} + +#endif // EMPTY_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyView.h new file mode 100644 index 000000000..b17ea9e70 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/emptypage/EmptyView.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: EmptyView + * Create: 2025-04-24 + */ + +#ifndef EMPTY_VIEW_H +#define EMPTY_VIEW_H +#include "View.h" +namespace OHOS { +class EmptyPresenter; +class EmptyView : public View {}; +} +#endif // EMPTY_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneMainPage.h new file mode 100644 index 000000000..39e3b9222 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneMainPage.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhoneMainPage + * Create: 2025-03-23 + */ + +#ifndef FINDPHONE_MAIN_PAGE_H +#define FINDPHONE_MAIN_PAGE_H + +#include +#include "View.h" +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_digital_clock.h" +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_list.h" +#include "components/ui_image_animator.h" +#include "ChangeSliceListener.h" +#include "UiConfig.h" +#include "layout/grid_layout.h" +#include "SlicePageFactory.h" +#include "SlicePage.h" +#include "diag_service.h" +#include "ohos_timer.h" +#include "findphone/FindPhoneModel.h" +#include "findphone/FindPhonePresenter.h" + +#define ALIPAY_BIND_SEARCH_IMAGE_NUM 28 +namespace OHOS { +static int timeCount = 0; +static constexpr uint64_t MS_ONE_SECONDS = 1000; +class FindPhonePresenter; +class FindPhoneModel; +class FindPhoneMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FindPhoneMainPage(); + ~FindPhoneMainPage() override; + static FindPhoneMainPage *GetInstance(); + void OnStart(void* data) override; + void OnStop() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool ClickButtonChange(); + void SetUpImageAnimator(); + void SetupButton(); + void InitImageInfo(); + void ShowReset(); + void DisableFindPhoneTimer(); + void InitFindPhoneTimer(); + bool StopFindPhone(); + uint8_t GetConnectStatus(); + void ChangeToDisConnect(); +private: + UIViewGroup* container_ = nullptr; + UILabel* labelUnder = nullptr; + UILabel* labelFindTitle = nullptr; + UIButton* buttonFind = nullptr; + UIButton* buttonRty = nullptr; + UILabel *labelRing = nullptr; + UIImageView *mainImage = nullptr; + ImageInfo* imageInfo1_ = nullptr; + ImageInfo* imageInfo2_ = nullptr; + ImageInfo* imageInfo3_ = nullptr; + ImageAnimatorInfo imageAnimatorImageInfo_[SET_THREE] = { 0 }; + UIImageAnimatorView* imageAnimator_ = nullptr; + GraphicTimer *g_startCount = nullptr; + ImageAnimatorInfo searchImageInfo[ALIPAY_BIND_SEARCH_IMAGE_NUM]; +}; +} +#endif // FINDPHONE_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneModel.h new file mode 100644 index 000000000..494c171be --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneModel.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhoneModel + * Create: 2025-03-23 + */ + +#ifndef FINDPHONE_MODEL_H +#define FINDPHONE_MODEL_H + +#include +#include +#include +#include "graphic_timer.h" + +namespace OHOS { +constexpr int16_t SET_ZERO = 0; +constexpr int16_t SET_ONE = 1; +constexpr int16_t SET_TWO = 2; +constexpr int16_t SET_THREE = 3; +constexpr int16_t SET_FOUR = 4; +constexpr int16_t SET_FIVE = 5; +constexpr int16_t SET_SIX = 6; +constexpr int16_t SET_SEVEN = 7; +constexpr int16_t SET_EIGHT = 8; +constexpr int16_t SET_NINE = 9; +constexpr int16_t SET_TEN = 10; +constexpr int16_t SET_INT_MAX = 255; + +class FindPhoneModel { +public: + static FindPhoneModel &GetInstance(void); + +private: + FindPhoneModel(); + FindPhoneModel(const FindPhoneModel &); + FindPhoneModel &operator=(const FindPhoneModel &); + virtual ~FindPhoneModel(); + bool buttonStatus = 0; +}; +} + +#endif // FINDPHONE_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhonePresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhonePresenter.h new file mode 100644 index 000000000..6c74c4669 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhonePresenter.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhonePresenter + * Create: 2025-03-23 + */ + +#ifndef FINDPHONE_PRESENTER_H +#define FINDPHONE_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" + +namespace OHOS { +class FindPhoneView; +class FindPhonePresenter : public Presenter {}; +} + +#endif // FINDPHONE_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneView.h new file mode 100644 index 000000000..6cb7de185 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/findphone/FindPhoneView.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FindPhoneView + * Create: 2025-03-23 + */ + +#ifndef FINDPHONE_VIEW_H +#define FINDPHONE_VIEW_H + +#include "View.h" +namespace OHOS { +enum FIND_PHONE_PAGES { + FIND_PHONE_MAIN_PAGE = 1, // 0 is invalid + FIND_PHONE_MESSAGE_PAGE = 2, +}; + +class FindPhonePresenter; +class FindPhoneView : public View {}; +} +#endif // FINDPHONE_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightBlinkPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightBlinkPage.h new file mode 100644 index 000000000..46f4ef937 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightBlinkPage.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightBlinkPage + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_BLINK_PAGE_H +#define FLASHLIGHT_BLINK_PAGE_H +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_label_button_ext.h" +#include "components/ui_scroll_view.h" +#include "SlicePage.h" +#include "flashlight/FlashLightPresenter.h" +#include "components/ui_picker.h" + +namespace OHOS { +class FlashLightBlinkPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FlashLightBlinkPage(){}; + ~FlashLightBlinkPage(); + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + FlashLightBlinkPage(const FlashLightBlinkPage &) = delete; + FlashLightBlinkPage &operator=(const FlashLightBlinkPage &) = delete; + FlashLightBlinkPage(FlashLightBlinkPage &&) = delete; + FlashLightBlinkPage &operator=(FlashLightBlinkPage &&) = delete; + + UIScrollView *container_ = nullptr; + UILabel *blinkLabel_ = nullptr; + UIPicker* blinkPicker_ = nullptr; + UILabelButtonExt* blinkButton_ = nullptr; +}; +} // namespace OHOS +#endif /* FLASHLIGHT_BLINK_PAGE_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightColorPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightColorPage.h new file mode 100644 index 000000000..acbe25c21 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightColorPage.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightColorPage + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_COLOR_PAGE_H +#define FLASHLIGHT_COLOR_PAGE_H +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_label_button_ext.h" +#include "components/ui_scroll_view.h" +#include "SlicePage.h" +#include "flashlight/FlashLightPresenter.h" + +namespace OHOS { +class FlashLightColorPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FlashLightColorPage(){}; + ~FlashLightColorPage(); + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + FlashLightColorPage(const FlashLightColorPage &) = delete; + FlashLightColorPage &operator=(const FlashLightColorPage &) = delete; + FlashLightColorPage(FlashLightColorPage &&) = delete; + FlashLightColorPage &operator=(FlashLightColorPage &&) = delete; + + UIScrollView *container_ = nullptr; + UILabel *colorLabel_ = nullptr; + UILabelButtonExt *color1Button_ = nullptr; + UILabelButtonExt *color2Button_ = nullptr; + UILabelButtonExt *color3Button_ = nullptr; + UILabelButtonExt *color4Button_ = nullptr; + UILabelButtonExt *color5Button_ = nullptr; + UILabelButtonExt *color6Button_ = nullptr; + UILabelButtonExt *color7Button_ = nullptr; + UILabelButtonExt *color8Button_ = nullptr; + UILabelButtonExt *color9Button_ = nullptr; +}; +} // namespace OHOS +#endif /* FLASHLIGHT_COLOR_PAGE_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightDefaultPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightDefaultPage.h new file mode 100644 index 000000000..0314434b6 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightDefaultPage.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightDefaultPage + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_DEFAULT_PAGE_H +#define FLASHLIGHT_DEFAULT_PAGE_H +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_label_button_ext.h" +#include "components/ui_scroll_view.h" +#include "SlicePage.h" +#include "flashlight/FlashLightPresenter.h" + +namespace OHOS { +class FlashLightDefaultPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FlashLightDefaultPage(){}; + ~FlashLightDefaultPage(); + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + FlashLightDefaultPage(const FlashLightDefaultPage &) = delete; + FlashLightDefaultPage &operator=(const FlashLightDefaultPage &) = delete; + FlashLightDefaultPage(FlashLightDefaultPage &&) = delete; + FlashLightDefaultPage &operator=(FlashLightDefaultPage &&) = delete; + + UIScrollView *container_ = nullptr; + UILabel *recoverLabel_ = nullptr; + UILabelButtonExt *cancelButton_ = nullptr; + UILabelButtonExt *confirmButton_ = nullptr; +}; +} // namespace OHOS +#endif /* FLASHLIGHT_DEFAULT_PAGE_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightModel.h new file mode 100644 index 000000000..adf42ce13 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightModel.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightModel + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_MODEL_H +#define FLASHLIGHT_MODEL_H + +#include +#include +#include +#include +#include "AppViewIDs.h" +#include "UiConfig.h" +#include "flashlight/FlashLightPresenter.h" +#include "flashlight/FlashlightUiResourceImage.h" +#ifndef _WIN32 +#include "time64.h" +#endif +namespace OHOS { +enum FlashLightBlinkFrequency { SLOW_BLINK = 0, FAST_BLINK, NOT_BLINK }; + +enum FlashLightColorAttribute { + BLACK_COLOR = 0, + WHITE_COLOR = 1, + RED_COLOR = 2, + ORANGE_COLOR = 3, + YELLOW_COLOR = 4, + GREEN_COLOR = 5, + LIGHT_BLUE_COLOR = 6, + DARK_BLUE_COLOR = 7, + PURPLE_COLOR = 8, + MULTI_COLOR = 9, +}; + +class FlashLightModel { +public: + static FlashLightModel &GetInstance(void); + // 设置手电筒颜色; + FlashLightColorAttribute GetViewColor(); + void SetViewColor(FlashLightColorAttribute color); + // 设置手电筒闪烁频率; + FlashLightBlinkFrequency GetBlinkFrequency(); + void SetBlinkFrequency(FlashLightBlinkFrequency blinkFrequency); + // 恢复默认参数; + void SetDefault(); + // 获取当前时间; + uint32_t GetSysCurrentTime(std::string ¤tTime); + +private: + FlashLightModel(FlashLightColorAttribute color = FlashLightColorAttribute::WHITE_COLOR, + FlashLightBlinkFrequency blinkFrequency = FlashLightBlinkFrequency::NOT_BLINK); + FlashLightModel(const FlashLightModel &); + FlashLightModel &operator=(const FlashLightModel &); + virtual ~FlashLightModel(); + +private: +#ifdef _WIN32 + struct timeval sysTime_ { + 0 + }; +#else + struct timeval64 sysTime_ { + 0 + }; +#endif + FlashLightColorAttribute color_; + FlashLightBlinkFrequency blinkFrequency_; +}; +} + +#endif // FLASHLIGHT_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPage.h new file mode 100644 index 000000000..629a2e871 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPage.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightPage + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_PAGE_H +#define FLASHLIGHT_PAGE_H + +#include +#include "View.h" +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "components/ui_image_view.h" +#include "components/ui_image_view.h" +#include "ChangeSliceListener.h" +#include "UiConfig.h" +#include "SlicePage.h" +#include "flashlight/FlashLightPresenter.h" +#include "animator.h" + +namespace OHOS { +class FlashLightPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FlashLightPage(){}; + ~FlashLightPage(); + + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + class TimeAnimatorCallback : public AnimatorCallback { + public: + TimeAnimatorCallback() {} + virtual ~TimeAnimatorCallback() override {} + void Callback(UIView* view) override; + }; + TimeAnimatorCallback* timeCallback_ = nullptr; + Animator* timeAnimator_ = nullptr; + UILabelButton* flashLightOn_ = nullptr; + UILabel* systemTime_ = nullptr; + UILabel* OnLabel_ = nullptr; + UIImageView* imageArrow_ = nullptr; + UIScrollView *container_ = nullptr; +}; +} +#endif // FLASHLIGHT_PAGE_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPlayPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPlayPage.h new file mode 100644 index 000000000..b7fc36541 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPlayPage.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightPlayPage + * Create: 2025-04-24 + */ +#ifndef FLASHLIGHT_PLAY_PAGE_H +#define FLASHLIGHT_PLAY_PAGE_H +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_image_animator.h" +#include "SlicePage.h" +#include "flashlight/FlashLightPresenter.h" +#include "flashlight/FlashLightModel.h" + +namespace OHOS { +class FlashLightPlayPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FlashLightPlayPage(){}; + ~FlashLightPlayPage(); + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + FlashLightPlayPage(const FlashLightPlayPage &) = delete; + FlashLightPlayPage &operator=(const FlashLightPlayPage &) = delete; + FlashLightPlayPage(FlashLightPlayPage &&) = delete; + FlashLightPlayPage &operator=(FlashLightPlayPage &&) = delete; + + UIScrollView *container_ = nullptr; + UIImageAnimatorView *playImageAnimal = nullptr; + ImageAnimatorInfo playImageInfo[2]; +}; +} // namespace OHOS +#endif /* FLASHLIGHT_PLAY_PAGE_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPresenter.h new file mode 100644 index 000000000..3f356de27 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightPresenter.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightPresenter + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_PRESENTER_H +#define FLASHLIGHT_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { + +class FlashLightView; +class FlashLightPresenter : public Presenter {}; +} + +#endif // FLASHLIGHT_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemAdapter.h new file mode 100644 index 000000000..9aeb158ed --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemAdapter.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightSetItemAdapter + * Create: 2025-11-23 + */ + +#ifndef FLASHLIGHTSET_ITEM_ADAPTER_H +#define FLASHLIGHTSET_ITEM_ADAPTER_H + +#include "flashlight/FlashLightSetItemAdapter.h" +#include "flashlight/FlashLightSetItemView.h" +#include "components/abstract_adapter.h" +#include "gfx_utils/vector.h" + +namespace OHOS { + +class FlashLightSetItemAdapter : public AbstractAdapter { +public: + explicit FlashLightSetItemAdapter(); + ~FlashLightSetItemAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a SettingItem linked list. + * + * @param data Indicates the SettingItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(const Graphic::Vector &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const FlashLightSetItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + Graphic::Vector itemDatas_; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif // FLASHLIGHTSET_ITEM_ADAPTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemView.h new file mode 100644 index 000000000..1704f88ab --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetItemView.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightSetItemView + * Create: 2025-05-18 + */ + +#ifndef FLASHLIGHTSET_ITEM_VIEW_H +#define FLASHLIGHTSET_ITEM_VIEW_H + +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" + +namespace OHOS { +typedef struct { + uint8_t item; + uint32_t resId; + std::string label; + std::string itemLabel; + std::string viewId; +} FlashLightSetItem; + +class FlashLightSetItemView : public UIViewGroup { +public: + FlashLightSetItemView(); + ~FlashLightSetItemView() override; + virtual void SetItemInfo(const FlashLightSetItem itemInfo); + const char *GetViewId() const; + +private: + UIImageView sIcon; + UILabel sLabel; + UILabel itemLabel; + UIImageView sNextImage; + FlashLightSetItem sItemInfo = {0, 0, "", "", ""}; +}; +} +#endif // FLASHLIGHTSET_ITEM_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetPage.h new file mode 100644 index 000000000..d1f1b068b --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightSetPage.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightSetPage + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_SET_PAGE_H +#define FLASHLIGHT_SET_PAGE_H +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_label_button_ext.h" +#include "components/ui_scroll_view.h" +#include "components/ui_list.h" +#include "SlicePage.h" +#include "flashlight/FlashLightPresenter.h" +#include "flashlight/FlashLightSetItemAdapter.h" +#include "flashlight/FlashLightSetItemView.h" +#include "UiConfig.h" +#include "main/LoadImg.h" +#include "flashlight/FlashlightUiResourceImage.h" + +namespace OHOS { +class FlashLightSetPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + FlashLightSetPage(){}; + ~FlashLightSetPage(); + void OnStart(void* data) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + FlashLightSetPage(const FlashLightSetPage &) = delete; + FlashLightSetPage &operator=(const FlashLightSetPage &) = delete; + FlashLightSetPage(FlashLightSetPage &&) = delete; + FlashLightSetPage &operator=(FlashLightSetPage &&) = delete; + + UIScrollView *container_ = nullptr; + UILabel *setLabel_ = nullptr; + UILabelButtonExt *recoverButton_ = nullptr; + + UIList* setItemList_ = nullptr; + FlashLightSetItemAdapter *setItemAdapter_ = nullptr; + FlashLightSetItem colorItem_ = {1, IMAGE_CONVERTER_TOOL_COLORITEM, "灯光颜色"}; + FlashLightSetItem blinkItem_ = {2, IMAGE_CONVERTER_TOOL_BLINKITEM, "闪烁频率"}; +}; +} // namespace OHOS +#endif /* FLASHLIGHT_SET_PAGE_H */ diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightView.h new file mode 100644 index 000000000..463a94e1c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashLightView.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashLightView + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_VIEW_H +#define FLASHLIGHT_VIEW_H +#include "View.h" +namespace OHOS { + +enum FlashLightAllView { + FLASH_LIGTH_VIEW = 1, // 手电筒主界面 + FLASH_LIGHT_PLAY_VIEW, // 手电筒显示播放 + FLASH_LIGHT_SET_VIEW, // 手电筒设置 + FLASH_LIGHT_COLOR_VIEW, // 手电筒颜色 + FLASH_LIGHT_BLINK_VIEW, // 手电筒闪烁 + FLASH_LIGHT_DEFAULT_VIEW, // 手电筒默认 + FLASH_LIGHT_ALL_VIEW, +}; + +class FlashLightPresenter; +class FlashLightView : public View {}; +} +#endif // FLASHLIGHT_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashlightUiResourceImage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashlightUiResourceImage.h new file mode 100644 index 000000000..50238d30b --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/flashlight/FlashlightUiResourceImage.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: FlashlightUiResourceImage + * Create: 2025-04-24 + */ + +#ifndef FLASHLIGHT_UI_RESOURCE_IMAGE_H +#define FLASHLIGHT_UI_RESOURCE_IMAGE_H +#include +namespace OHOS { +static const int IMAGE_CONVERTER_TOOL_BLINKBUTTON = 0x100001; +static const int IMAGE_CONVERTER_TOOL_BLINKITEM = 0x100002; +static const int IMAGE_CONVERTER_TOOL_COLOR1BUTTON = 0x100003; +static const int IMAGE_CONVERTER_TOOL_COLOR1PRESSBUTTON = 0x100004; +static const int IMAGE_CONVERTER_TOOL_COLOR2BUTTON = 0x100005; +static const int IMAGE_CONVERTER_TOOL_COLOR2PRESSBUTTON = 0x100006; +static const int IMAGE_CONVERTER_TOOL_COLOR3BUTTON = 0x100007; +static const int IMAGE_CONVERTER_TOOL_COLOR3PRESSBUTTON = 0x100008; +static const int IMAGE_CONVERTER_TOOL_COLOR4BUTTON = 0x100009; +static const int IMAGE_CONVERTER_TOOL_COLOR4PRESSBUTTON = 0x10000a; +static const int IMAGE_CONVERTER_TOOL_COLOR5BUTTON = 0x10000b; +static const int IMAGE_CONVERTER_TOOL_COLOR5PRESSBUTTON = 0x10000c; +static const int IMAGE_CONVERTER_TOOL_COLOR6BUTTON = 0x10000d; +static const int IMAGE_CONVERTER_TOOL_COLOR6PRESSBUTTON = 0x10000e; +static const int IMAGE_CONVERTER_TOOL_COLOR7BUTTON = 0x10000f; +static const int IMAGE_CONVERTER_TOOL_COLOR7PRESSBUTTON = 0x100010; +static const int IMAGE_CONVERTER_TOOL_COLOR8BUTTON = 0x100011; +static const int IMAGE_CONVERTER_TOOL_COLOR8PRESSBUTTON = 0x100012; +static const int IMAGE_CONVERTER_TOOL_COLOR9BUTTON = 0x100013; +static const int IMAGE_CONVERTER_TOOL_COLOR9PRESSBUTTON = 0x100014; +static const int IMAGE_CONVERTER_TOOL_COLORITEM = 0x100015; +static const int IMAGE_CONVERTER_TOOL_DOWNARROW = 0x100016; +static const int IMAGE_CONVERTER_TOOL_FLASHLIGHTON = 0x100017; +static const int IMAGE_CONVERTER_TOOL_PLAY1PAGE = 0x100018; +static const int IMAGE_CONVERTER_TOOL_PLAY2PAGE = 0x100019; +static const int IMAGE_CONVERTER_TOOL_PLAY3PAGE = 0x10001a; +static const int IMAGE_CONVERTER_TOOL_PLAY4PAGE = 0x10001b; +static const int IMAGE_CONVERTER_TOOL_PLAY5PAGE = 0x10001c; +static const int IMAGE_CONVERTER_TOOL_PLAY6PAGE = 0x10001d; +static const int IMAGE_CONVERTER_TOOL_PLAY7PAGE = 0x10001e; +static const int IMAGE_CONVERTER_TOOL_PLAY8PAGE = 0x10001f; +static const int IMAGE_CONVERTER_TOOL_PLAY9PAGE = 0x100020; +static const int IMAGE_CONVERTER_TOOL_PLAYBLACKPAGE = 0x100021; +static const int IMAGE_CONVERTER_TOOL_RECOVERBUTTON = 0x100022; +static const int IMAGE_CONVERTER_TOOL_RECOVERCANCLE = 0x100023; +static const int IMAGE_CONVERTER_TOOL_RECOVERCONFIRM = 0x100024; +static const int IMAGE_CONVERTER_TOOL_RIGHTARROW = 0x100025; +} // OHOS +#endif // FLASHLIGHT_UI_RESOURCE_IMAGE_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/include/HeartModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/heartrate/HeartModel.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/heartrate/include/HeartModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/heartrate/HeartModel.h index 3891ec79a..20336ca0b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/include/HeartModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/heartrate/HeartModel.h @@ -5,7 +5,7 @@ #include "broadcast_feature.h" #include "broadcast_service.h" #include "samgr_lite.h" -#include "MainClockView.h" +#include "clock/MainClockView.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/include/HeartRateView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/heartrate/HeartRateView.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/heartrate/include/HeartRateView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/heartrate/HeartRateView.h index 1d94d89e5..152b81259 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/heartrate/include/HeartRateView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/heartrate/HeartRateView.h @@ -14,7 +14,7 @@ #include "wearable_log.h" #include "ohos_types.h" #include "components/ui_card_page.h" -#include "HeartModel.h" +#include "heartrate/HeartModel.h" namespace OHOS { #define HEART_AVE_NUM 360 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/CustomizationView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/CustomizationView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/CustomizationView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/CustomizationView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkEndView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkEndView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkEndView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkEndView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkModel.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkModel.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkMotionView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkMotionView.h similarity index 82% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkMotionView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkMotionView.h index 40e0e4502..6619e7093 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkMotionView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkMotionView.h @@ -8,11 +8,11 @@ #define INDOORWALK_MOTION_VIEW_H #include "View.h" -#include "MotionPageFirst.h" -#include "MotionPageSecond.h" -#include "MotionPageThird.h" -#include "MotionPageFourth.h" -#include "MotionPageFifth.h" +#include "indoorwalk/MotionPageFirst.h" +#include "indoorwalk/MotionPageSecond.h" +#include "indoorwalk/MotionPageThird.h" +#include "indoorwalk/MotionPageFourth.h" +#include "indoorwalk/MotionPageFifth.h" #include "components/ui_swipe_view.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkPreparedView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkPreparedView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkPreparedView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkPreparedView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkPresenter.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkPresenter.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkView.h similarity index 82% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkView.h index c89592aa1..c39891ce8 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/IndoorWalkView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/IndoorWalkView.h @@ -7,12 +7,12 @@ #ifndef INDOORWALK_VIEW_H #define INDOORWALK_VIEW_H -#include "IndoorWalkEndView.h" +#include "indoorwalk/IndoorWalkEndView.h" #include "View.h" -#include "IndoorWalkPresenter.h" -#include "IndoorWalkPreparedView.h" -#include "CustomizationView.h" -#include "IndoorWalkMotionView.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkPreparedView.h" +#include "indoorwalk/CustomizationView.h" +#include "indoorwalk/IndoorWalkMotionView.h" #include "components/ui_view_group.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFifth.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFifth.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFifth.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFifth.h index 6acdbbd5c..5d1b8fba7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFifth.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFifth.h @@ -12,7 +12,7 @@ #include "ohos_types.h" #include "components/ui_label.h" #include "components/ui_image_view.h" -#include "AppGroupView.h" +#include "main/AppGroupView.h" namespace OHOS { class MotionPageFifth : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFirst.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFirst.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFirst.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFirst.h index 109325e4a..fb4f42456 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFirst.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFirst.h @@ -12,7 +12,7 @@ #include "ohos_types.h" #include "components/ui_label.h" #include "components/ui_image_view.h" -#include "AppGroupView.h" +#include "main/AppGroupView.h" namespace OHOS { class MotionPageFirst : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFourth.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFourth.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFourth.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFourth.h index eeb81c939..b3237f0ab 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageFourth.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageFourth.h @@ -12,7 +12,7 @@ #include "ohos_types.h" #include "components/ui_label.h" #include "components/ui_image_view.h" -#include "AppGroupView.h" +#include "main/AppGroupView.h" namespace OHOS { class MotionPageFourth : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageSecond.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageSecond.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageSecond.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageSecond.h index 13665cc55..fc44d1825 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageSecond.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageSecond.h @@ -12,7 +12,7 @@ #include "ohos_types.h" #include "components/ui_label.h" #include "components/ui_image_view.h" -#include "AppGroupView.h" +#include "main/AppGroupView.h" namespace OHOS { class MotionPageSecond : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageThird.h b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageThird.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageThird.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageThird.h index 8dc7072f5..0416dcb3a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/include/MotionPageThird.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/indoorwalk/MotionPageThird.h @@ -12,7 +12,7 @@ #include "ohos_types.h" #include "components/ui_label.h" #include "components/ui_image_view.h" -#include "AppGroupView.h" +#include "main/AppGroupView.h" namespace OHOS { class MotionPageThird : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/key/include/KeyInputListener.h b/code/sdk/application/wearable/nativeapp/nativeui/include/key/KeyInputListener.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/key/include/KeyInputListener.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/key/KeyInputListener.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/AppGroupView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/AppGroupView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/AppGroupView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/AppGroupView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParser.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParser.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParser.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParser.h index 362c93050..ac020abe9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParser.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParser.h @@ -14,15 +14,15 @@ */ #ifndef GRAPHIC_LITE_DIAL_BIN_PARSER_H #define GRAPHIC_LITE_DIAL_BIN_PARSER_H -#include "DialBinParserManager.h" -#include "DialBinTypesV2.h" +#include "main/DialBinParserManager.h" +#include "main/DialBinTypesV2.h" #include "components/ui_abstract_progress.h" namespace OHOS { class DialBinParser : public DialBinParserInterface { public: bool UpdateDial(const std::string& file, FILE* fp, DialViewGroup* group, DisplayState state) override; - bool GetDialPreviewInfo(FILE* fp, DialPreviewInfo* info) override; + bool GetDialPreviewInfo(const std::string& file, FILE* fp, DialPreviewInfo* info) override; DialBinParser(); ~DialBinParser() override; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParserManager.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParserManager.h similarity index 81% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParserManager.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParserManager.h index 50a9e4a6f..ae969a32d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParserManager.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParserManager.h @@ -10,14 +10,15 @@ #include #include #include "graphic_types.h" -#include "DialViewGroup.h" -#include "DialBinTypes.h" +#include "main/dial/DialViewGroup.h" +#include "main/DialBinTypes.h" namespace OHOS { class DialBinParserInterface { public: virtual bool UpdateDial(const std::string& file, FILE* fp, DialViewGroup* group, DisplayState state) = 0; - virtual bool GetDialPreviewInfo(FILE* fp, DialPreviewInfo* info) = 0; + virtual bool GetDialPreviewInfo(const std::string& file, FILE* fp, DialPreviewInfo* info) = 0; + virtual void SetEncryptData(uint8_t *data, uint32_t len) {} virtual ~DialBinParserInterface() {} }; // class DialBinParserInterface @@ -25,7 +26,7 @@ class DialBinParserManager { public: static DialBinParserManager *GetInstance(void); bool UpdateDial(const std::string &file, FILE *fp, DialViewGroup *group, DisplayState state); - bool GetDialPreviewInfo(FILE *fp, DialPreviewInfo *info); + bool GetDialPreviewInfo(const std::string& file, FILE *fp, DialPreviewInfo *info, bool isNeedVerify = false); bool RegisterParser(const std::string &version, DialBinParserInterface *parser); uint8_t GetSupportVersionCnt() const @@ -46,6 +47,7 @@ private: DialBinParserManager(); virtual ~DialBinParserManager(); DialBinParserInterface *GetParser(FILE* fp) const; + DialBinParserInterface *GetParser(const std::string &fileName, FILE *fp, bool isNeedVerify = false) const; static constexpr uint8_t PARSER_MAX_NUM = 8; struct Pair { std::string version; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParserV3.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParserV3.h similarity index 82% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParserV3.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParserV3.h index 99d530e89..7e7427a83 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinParserV3.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinParserV3.h @@ -7,12 +7,12 @@ #ifndef GRAPHIC_LITE_DIAL_BIN_PARSER_V3_H #define GRAPHIC_LITE_DIAL_BIN_PARSER_V3_H -#include "DialBinParserManager.h" -#include "DialModelTime.h" +#include "main/DialBinParserManager.h" +#include "main/dial/DialModelTime.h" #include "components/ui_abstract_progress.h" -#include "DialViewContainer.h" -#include "DialDataType.h" -#include "DialOHSliceId.h" +#include "main/dial/DialViewContainer.h" +#include "main/dial/DialDataType.h" +#include "main/dial/DialOHSliceId.h" namespace OHOS { class DialBinParserV3 : public DialBinParserInterface { @@ -20,7 +20,8 @@ public: DialBinParserV3(); ~DialBinParserV3() override; bool UpdateDial(const std::string& file, FILE* fp, DialViewGroup* group, DisplayState state) override; - bool GetDialPreviewInfo(FILE* fp, DialPreviewInfo* info) override; + bool GetDialPreviewInfo(const std::string& file, FILE* fp, DialPreviewInfo* info) override; + void SetEncryptData(uint8_t *data, uint32_t len) override final; protected: bool ParseDialHeader(FILE* file); @@ -58,12 +59,16 @@ private: bool ParseViewType(uint8_t *viewType, uint8_t dialViewCount, FILE *file); bool ParseContainerSubviews(DialViewContainer *container, uint8_t num); bool ParseOptionsSubviews(ContainerInterface &parent); + DialHeader *GetHeader(FILE *fp); + uint8_t *GetVeiwType(FILE *fp, DialHeader *dialHeader); DialViewGroup* dialGroup_ = nullptr; std::string file_; const uint32_t dirId_ = 0xfef << 20; // 20: offset uint32_t imageOffset_ = 0; DisplayState state_ = DisplayState::NORMAL; + uint8_t *encryptedData_ = nullptr; + uint32_t encrpytedLen_ = 0; }; // class DialBinParserV3 } // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinTypes.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinTypes.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinTypes.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinTypes.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinTypesV2.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinTypesV2.h similarity index 99% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinTypesV2.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinTypesV2.h index 837a0a685..d49b354c7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/DialBinTypesV2.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/DialBinTypesV2.h @@ -7,7 +7,7 @@ #ifndef GRAPHIC_LITE_DIAL_BIN_TYPE_V2_H #define GRAPHIC_LITE_DIAL_BIN_TYPE_V2_H -#include "DialBinTypes.h" +#include "main/DialBinTypes.h" namespace OHOS { enum class DisplayState { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/HealthModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/HealthModel.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/HealthModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/HealthModel.h index 9b087ae7e..9b6015779 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/HealthModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/HealthModel.h @@ -18,7 +18,7 @@ #include #include "gfx_utils/list.h" -#include "UiServersMsg.h" +#include "main/UiServersMsg.h" namespace OHOS { #define NUM_1 1 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/main/LoadImg.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/LoadImg.h new file mode 100644 index 000000000..b92e242a7 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/LoadImg.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved. + * Description: LoadImg + * Create: 2025-06-05 + */ +#ifndef LOAD_IMG_H +#define LOAD_IMG_H + +#include +#include "wearable_log.h" +#include "components/ui_button.h" +#include "components/ui_image_view.h" +#include "common/image_cache_manager.h" + +namespace OHOS { +namespace LOADIMG { +// 加载图片资源 +void LoadBtnImage(UIButton *btn, std::string file, uint32_t resId1, uint32_t resId2); + +void LoadImageViewImg(UIImageView *view, std::string file, uint32_t resId); +} +} +#endif // LOAD_IMG_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/MainModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MainModel.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/MainModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/MainModel.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/MainPresenterSample.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MainPresenterSample.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/MainPresenterSample.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/MainPresenterSample.h index aa2f4658e..444436189 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/MainPresenterSample.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MainPresenterSample.h @@ -9,17 +9,17 @@ #define MAIN_PRESENTER_SAMPLE_H #include "Presenter.h" -#include "ModelListenerSample.h" +#include "main/ModelListenerSample.h" #include "components/root_view.h" #include "drag_event.h" -#include "MainViewSample.h" -#include "MainModel.h" +#include "main/MainViewSample.h" +#include "main/MainModel.h" #include "components/ui_swipe_view.h" #include "components/ui_view.h" -#include "MainCompassView.h" -#include "MainCompassPresenter.h" -#include "PlayersView.h" -#include "HeartRateView.h" +#include "compass/MainCompassView.h" +#include "compass/MainCompassPresenter.h" +#include "player/PlayersView.h" +#include "heartrate/HeartRateView.h" #include "swipe_effect/zoom_effect.h" namespace OHOS { @@ -45,7 +45,7 @@ enum class MainPresenterState { class MainViewSample; class MainPresenterSample : public Presenter, public ModelListenerSample, public UIView::OnClickListener, public UISwipeView::OnSwipeListener, - public UIView::OnLongPressListener, public UISwipeView, public CompassPresenter { + public UIView::OnLongPressListener, public UISwipeView { public: MainPresenterSample(); ~MainPresenterSample() override; @@ -75,7 +75,6 @@ public: private: void ProcessDataNotify(void); void SetCircleProgress(void); - void SetCompassRotate(void); uint8_t state_ = UICheckBox::UICheckBoxState::MAX_STATUS_NUM; int64_t playerCurrentTime_{0}; int64_t playerMusicDuration_{0}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/MainViewSample.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MainViewSample.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/MainViewSample.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/MainViewSample.h index 05a667c14..b1be728de 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/MainViewSample.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MainViewSample.h @@ -15,20 +15,20 @@ #include "ChangeSliceListener.h" #include "font/ui_font.h" #include "graphic_config.h" -#include "ModelListenerSample.h" -#include "ScreenModels.h" -#include "ActivityWeekView.h" -#include "CompassControlView.h" -#include "DialViewGroup.h" -#include "MainClockView.h" -#include "PlayersView.h" -#include "MainPresenterSample.h" -#include "HeartRateView.h" +#include "main/ModelListenerSample.h" +#include "screensetting/ScreenModels.h" +#include "activity/ActivityWeekView.h" +#include "compass/CompassControlView.h" +#include "main/dial/DialViewGroup.h" +#include "clock/MainClockView.h" +#include "player/PlayersView.h" +#include "main/MainPresenterSample.h" +#include "heartrate/HeartRateView.h" #include "components/ui_card_page.h" -#include "PullUpDownView.h" +#include "main/PullUpDownView.h" #include "components/ui_cross_view.h" -#include "SetCardModel.h" -#include "VideoCard.h" +#include "set_card/SetCardModel.h" +#include "videocard/VideoCard.h" namespace OHOS { class MainPresenterSample; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageAdapter.h new file mode 100644 index 000000000..a3e52fe35 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageAdapter.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MessageAdapter.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef MESSAGE_ADAPTER_H +#define MESSAGE_ADAPTER_H + +#include +#include +#include "components/ui_list.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/abstract_adapter.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "main/MainModel.h" +#include "main/MessageItemView.h" + +namespace OHOS { +class MessageAdapter : public AbstractAdapter { +public: + explicit MessageAdapter(); + ~MessageAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a WeatherItem linked list. + * + * @param data Indicates the MessageItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(std::list &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const MessageItem &item); + + void ClearListItem(); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + std::list listData; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageItemView.h new file mode 100644 index 000000000..73ec20a55 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageItemView.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: weather/WeatherItemView.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef MESSAGE_ITEM_VIEW_H +#define MESSAGE_ITEM_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_canvas.h" + +#include "UiConfig.h" +#include "main/MessageModel.h" + +namespace OHOS { +class MessageItemView : public UIViewGroup { +public: + explicit MessageItemView(); + ~MessageItemView() override; + virtual void SetItemInfo(const MessageItem itemInfo); + virtual void SetUpChild(); +private: + UILabel sLabel_1; + UIImageView sIcon; + UILabel sLabel_2; + UILabel sLabel_3; + UIImageView sNextImage; + UILabel sback; + MessageItem sItemInfo = { nullptr, nullptr, nullptr, nullptr}; +}; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageMainView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageMainView.h new file mode 100644 index 000000000..79b049adf --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageMainView.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: WeekStep + * Author: + * Create: 2021-09-11 + */ + +#ifndef MESSAGE_MAIN_VIEW_H +#define MESSAGE_MAIN_VIEW_H + +#include "graphic_types.h" +#include "wearable_log.h" +#include "components/ui_card_page.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "main/MessageModel.h" +#include "main/MessageAdapter.h" + +namespace OHOS { +class MessageMainView : public UICardPage { +public: + MessageMainView(); + ~MessageMainView() override; + static MessageMainView *GetInstance(void); + bool InitView(); + void PreLoad(void) override; + void VerticalViewInits(void); + void ConfirmDeletion(void); + void CancelDeletion(void); + void ShowMessageList(void); + void DeletionView(void); + void NoNotify(void); + void NewNotify(void); + void RefreshMessageList(std::vector item); + bool InitScrollData(); + MessageAdapter *listAdapter{nullptr}; + UIList *contentList{nullptr}; // 列表 +private: + UILabel *messageLables{nullptr}; // 无消息 + UILabel *messageLable{nullptr}; // 通知 + UILabel *deletereminder{nullptr}; // 是否删除通知? + UILabelButton *confirm{nullptr}; // 确认 + UILabelButton *cancel{nullptr}; // 取消 + UIImageView *notice{nullptr}; // 删除图标 + UIView::OnClickListener *clickListener{nullptr}; + UIView::OnClickListener *confirmListener{nullptr}; + UIView::OnClickListener *cancelListener{nullptr}; + UIView::OnClickListener *notifyListener{nullptr}; + UIView::OnClickListener *newNotifyListener{nullptr}; +}; +} +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageModel.h new file mode 100644 index 000000000..fd24ca33d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/MessageModel.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MainModel.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef MESSAGE_MODEL_H +#define MESSAGE_MODEL_H + +#include +#include +#include "UiConfig.h" + +namespace OHOS { +typedef struct { + std::string label_1; + std::string icon; + std::string label_2; + std::string label_3; +} MessageItem; + + // static const uint16_t WEATHER_ITEM_COUNT = 10; + class MessageModel { + public: + static MessageModel &GetInstance(void); + void InitMessageItem(); + const std::vector GetMessagelistItems() const; + void ClearListItem(); + void GetMessageInfo(std::string app, std::string contact, std::string information); + void SetViewStatus(bool viewStatus); + bool GetViewStatus(void); + private: + MessageModel(); + MessageModel(const MessageModel &); + MessageModel &operator=(const MessageModel &); + virtual ~MessageModel(); + std::vector vecMsg; + MessageItem mes; + bool viewInitStatus{false}; + }; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/ModelListenerSample.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/ModelListenerSample.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/ModelListenerSample.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/ModelListenerSample.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/PullUpDownView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/PullUpDownView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/PullUpDownView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/PullUpDownView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/UiServersMsg.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/UiServersMsg.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/UiServersMsg.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/UiServersMsg.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/UiViewId.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/UiViewId.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/UiViewId.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/UiViewId.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/VolumeSettingPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/VolumeSettingPresenter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/VolumeSettingPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/VolumeSettingPresenter.h index a303b9052..2e0017072 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/VolumeSettingPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/VolumeSettingPresenter.h @@ -11,8 +11,8 @@ #include "components/ui_label_button.h" #include "components/ui_view_group.h" #include "components/ui_slider.h" -#include "VolumeSettingView.h" -#include "PlayersView.h" +#include "main/VolumeSettingView.h" +#include "player/PlayersView.h" namespace OHOS { #define INCREASE_BUTTON "increaseButton" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/VolumeSettingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/VolumeSettingView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/VolumeSettingView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/VolumeSettingView.h index ac3db835b..b4ccd2239 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/VolumeSettingView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/VolumeSettingView.h @@ -11,9 +11,9 @@ #include "components/ui_button.h" #include "components/ui_view_group.h" #include "components/ui_slider.h" -#include "PlayersView.h" +#include "player/PlayersView.h" #include "wearable_log.h" -#include "VolumeSettingPresenter.h" +#include "main/VolumeSettingPresenter.h" namespace OHOS { #define VOLUME_MIN 0 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialArcLabelView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialArcLabelView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialArcLabelView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialArcLabelView.h index 43d0dd217..899d1de81 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialArcLabelView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialArcLabelView.h @@ -6,7 +6,7 @@ #define DIAL_ARC_LABEL_VIEW_H #include -#include "DialView.h" +#include "main/dial/DialView.h" #include "components/ui_arc_label.h" #include "font/font_global_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialArcProgressView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialArcProgressView.h similarity index 78% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialArcProgressView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialArcProgressView.h index 29675223f..4e4763956 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialArcProgressView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialArcProgressView.h @@ -5,7 +5,7 @@ #ifndef DIAL_ARC_PROGRESS_VIEW_H #define DIAL_ARC_PROGRESS_VIEW_H -#include "DialView.h" +#include "main/dial/DialView.h" #include "components/ui_circle_progress.h" namespace OHOS { @@ -14,6 +14,7 @@ public: DialArcProgressView(); ~DialArcProgressView() override; void HandleFloatData(float data) override; + void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override; private: int32_t value_ = -1; }; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialBaseModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialBaseModel.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialBaseModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialBaseModel.h index ef71b9bb1..d9e6bd0e2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialBaseModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialBaseModel.h @@ -10,7 +10,7 @@ #include #include "heap_base.h" -#include "OnDialDataUpdateListener.h" +#include "main/dial/OnDialDataUpdateListener.h" namespace OHOS { class DialBaseModel : public HeapBase { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialBoxProgressView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialBoxProgressView.h similarity index 78% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialBoxProgressView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialBoxProgressView.h index cc45b4d91..4c8d5e67c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialBoxProgressView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialBoxProgressView.h @@ -5,7 +5,7 @@ #ifndef DIAL_BOX_PROGRESS_VIEW_H #define DIAL_BOX_PROGRESS_VIEW_H -#include "DialView.h" +#include "main/dial/DialView.h" #include "components/ui_box_progress.h" namespace OHOS { @@ -14,6 +14,7 @@ public: DialBoxProgressView(); ~DialBoxProgressView() override; void HandleFloatData(float data) override; + void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override; private: int32_t value_ = -1; }; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDataBase.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDataBase.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDataBase.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDataBase.h index e6d52b7ec..5a0a9bd6e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDataBase.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDataBase.h @@ -7,7 +7,7 @@ #ifndef DIAL_DATA_BASE_H #define DIAL_DATA_BASE_H -#include "DialDataType.h" +#include "main/dial/DialDataType.h" enum class DialOldDataType { DATA_TYPE_FLOAT_BASE = 0, diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDataType.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDataType.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDataType.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDataType.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDigitalImgView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDigitalImgView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDigitalImgView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDigitalImgView.h index 540c491b5..a058c6ff8 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialDigitalImgView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialDigitalImgView.h @@ -6,8 +6,8 @@ #define DIAL_DIGITAL_IMG_VIEW_H #include -#include "DialView.h" -#include "DialModelTime.h" +#include "main/dial/DialView.h" +#include "main/dial/DialModelTime.h" #include "components/ui_image_view.h" #include "gfx_utils/graphic_math.h" #include "components/ui_view_group.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialKaleidoscopeView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialKaleidoscopeView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialKaleidoscopeView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialKaleidoscopeView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialLabelView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialLabelView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialLabelView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialLabelView.h index 6e9f2a830..fb32df0b3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialLabelView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialLabelView.h @@ -6,7 +6,7 @@ #define DIAL_LABEL_VIEW_H #include -#include "DialView.h" +#include "main/dial/DialView.h" #include "components/ui_label.h" #include "font/font_global_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelHeartRate.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelHeartRate.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelHeartRate.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelHeartRate.h index 481f39459..54573de9c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelHeartRate.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelHeartRate.h @@ -8,7 +8,7 @@ #ifndef DIAL_MODEL_HEART_RATE_H #define DIAL_MODEL_HEART_RATE_H -#include "DialBaseModel.h" +#include "main/dial/DialBaseModel.h" namespace OHOS { class DialModelHeartRate : public DialBaseModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelPower.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelPower.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelPower.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelPower.h index cb6a97ce5..a6fc0e084 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelPower.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelPower.h @@ -8,7 +8,7 @@ #ifndef DIAL_MODEL_POWER_H #define DIAL_MODEL_POWER_H -#include "DialBaseModel.h" +#include "main/dial/DialBaseModel.h" namespace OHOS { class DialModelPower : public DialBaseModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelSteps.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelSteps.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelSteps.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelSteps.h index e1e9930dd..af23abd9b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelSteps.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelSteps.h @@ -8,7 +8,7 @@ #ifndef DIAL_MODEL_STEPS_H #define DIAL_MODEL_STEPS_H -#include "DialBaseModel.h" +#include "main/dial/DialBaseModel.h" namespace OHOS { class DialModelSteps : public DialBaseModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelTime.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelTime.h similarity index 97% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelTime.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelTime.h index d71982f5f..2a95eb18b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialModelTime.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialModelTime.h @@ -8,7 +8,7 @@ #ifndef DIAL_MODEL_TIME_H #define DIAL_MODEL_TIME_H -#include "DialBaseModel.h" +#include "main/dial/DialBaseModel.h" #include "gfx_utils/list.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialOHSliceId.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialOHSliceId.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialOHSliceId.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialOHSliceId.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialOptionImgView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialOptionImgView.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialOptionImgView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialOptionImgView.h index 52e4298c2..8feab2815 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialOptionImgView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialOptionImgView.h @@ -6,8 +6,8 @@ #define DIAL_OPTION_IMG_VIEW_H #include -#include "DialView.h" -#include "DialModelTime.h" +#include "main/dial/DialView.h" +#include "main/dial/DialModelTime.h" #include "components/ui_image_view.h" #include "font/font_global_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialRotateImgView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialRotateImgView.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialRotateImgView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialRotateImgView.h index e1fff0ed8..ef46414fa 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialRotateImgView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialRotateImgView.h @@ -6,7 +6,7 @@ #define DIAL_ROTATE_IMG_VIEW_H #include -#include "DialView.h" +#include "main/dial/DialView.h" #include "components/ui_image_view.h" #include "gfx_utils/graphic_math.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialSequenceImgView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialSequenceImgView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialSequenceImgView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialSequenceImgView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialStaticImgView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialStaticImgView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialStaticImgView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialStaticImgView.h index df8f2810c..922517a64 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialStaticImgView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialStaticImgView.h @@ -7,7 +7,7 @@ #include "components/ui_image_view.h" #include "font/font_global_manager.h" -#include "DialModelTime.h" +#include "main/dial/DialModelTime.h" namespace OHOS { class DialStaticImgView : public UIImageView, diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialVideoView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialVideoView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialVideoView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialVideoView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialView.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialView.h index 3155d760a..ceab904ed 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialView.h @@ -7,7 +7,7 @@ #include #include -#include "DialDataType.h" +#include "main/dial/DialDataType.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialViewContainer.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialViewContainer.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialViewContainer.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialViewContainer.h index 0dd421c44..15974b2b6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialViewContainer.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialViewContainer.h @@ -9,8 +9,8 @@ #define DIAL_VIEW_CONTAINER_H #include "components/ui_view_group.h" #include "gfx_utils/list.h" -#include "dial/DialView.h" -#include "dial/DialDataBase.h" +#include "main/dial/DialView.h" +#include "main/dial/DialDataBase.h" namespace OHOS { class ContainerInterface { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialViewGroup.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialViewGroup.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialViewGroup.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialViewGroup.h index a3072703f..347b8ad37 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/DialViewGroup.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/DialViewGroup.h @@ -7,19 +7,19 @@ #include #include -#include "DialDataBase.h" +#include "main/dial/DialDataBase.h" #include "components/ui_view_group.h" #include "components/ui_image_animator.h" #include "components/ui_label.h" -#include "OnDialDataUpdateListener.h" +#include "main/dial/OnDialDataUpdateListener.h" #include "components/ui_card_page.h" #include "components/ui_kaleidoscope_view.h" #include "gfx_utils/list.h" #include "gfx_utils/vector.h" -#include "DialView.h" -#include "DialVideoView.h" -#include "DialBinTypesV2.h" -#include "DialViewContainer.h" +#include "main/dial/DialView.h" +#include "main/dial/DialVideoView.h" +#include "main/DialBinTypesV2.h" +#include "main/dial/DialViewContainer.h" namespace OHOS { class DialViewGroup : public UICardPage, public OnDialDataUpdateListener, public ContainerInterface { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/ModelDialDataFactory.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/ModelDialDataFactory.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/ModelDialDataFactory.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/ModelDialDataFactory.h index 33bedbe49..23c5255fd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/ModelDialDataFactory.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/ModelDialDataFactory.h @@ -9,9 +9,9 @@ #define MODE_DIAL_DATA_FACTORY #include -#include "DialBaseModel.h" -#include "DialDataBase.h" -#include "ModelDialDataFactory.h" +#include "main/dial/DialBaseModel.h" +#include "main/dial/DialDataBase.h" +#include "main/dial/ModelDialDataFactory.h" namespace OHOS { class ModelDialDataFactory : public HeapBase { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/OnDialDataUpdateListener.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/OnDialDataUpdateListener.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/OnDialDataUpdateListener.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/OnDialDataUpdateListener.h index c2af34466..a14c09e44 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/OnDialDataUpdateListener.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/OnDialDataUpdateListener.h @@ -8,7 +8,7 @@ #ifndef ON_DIAL_DATA_UPDATE_LISTENER_H #define ON_DIAL_DATA_UPDATE_LISTENER_H -#include "DialDataBase.h" +#include "main/dial/DialDataBase.h" namespace OHOS { class OnDialDataUpdateListener : public HeapBase { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/RegisterDialModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/RegisterDialModel.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/RegisterDialModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/RegisterDialModel.h index f648a5d37..c0b4cbdde 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/RegisterDialModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/RegisterDialModel.h @@ -8,8 +8,8 @@ #ifndef REGISTER_DIAL_MODEL_H #define REGISTER_DIAL_MODEL_H -#include "DialDataBase.h" -#include "ModelDialDataFactory.h" +#include "main/dial/DialDataBase.h" +#include "main/dial/ModelDialDataFactory.h" namespace OHOS { class RegisterDialModel { public: diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/WatchInterface.h b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/WatchInterface.h similarity index 59% rename from code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/WatchInterface.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/WatchInterface.h index 2938ed4a0..f628bded6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/include/dial/WatchInterface.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/main/dial/WatchInterface.h @@ -16,12 +16,22 @@ extern "C" { /** * @brief Get all watch face information - * @param[out] info Pointer to store the watch face information - * @param[out] num Pointer to store the number of watch faces - * @param[in] maxCnt Maximum number of watch faces to retrieve - * @return bool Returns true if successful, false otherwise + * @param [out] watch_dial_info **info + * A pointer to a pointer where the retrieved watch face information will be stored. + * @param [out] uint8_t *num + * A pointer to the number of watch face information entries retrieved. + * @return bool + * - true: Successfully retrieved watch face information. + * The pointer pointed to by `info` needs to be released + * externally. + * - false: Failed to retrieve watch face information. + * @remarks + * - If the function returns true, + * the memory pointed to by `info` must be freed by the caller to prevent + * memory leaks. + * - If the function returns false, the values of `info` and `num` remain unchanged. */ -bool GetAllWatchFaceInfo(watch_dial_info *info, uint8_t *num, uint8_t maxCnt); +bool GetAllWatchFaceInfo(watch_dial_info **info, uint8_t *num); /** * @brief Get information of a specific watch face by UUID @@ -68,15 +78,20 @@ bool SetCurrentWatchFace(uint32_t uuid); bool UninstallWatch(uint32_t uuid); /** - * @brief Install a watch face from a specified path - * @param[in] path Path to the watch face file - * @param[out] uuid Pointer to store the unique identifier of the installed watch face - * @return bool Returns true if successful, false otherwise - * @note If a watch face with the same UUID already exists, it will be replaced + * @brief Retrieves the unique identifier (UUID) associated with a specified path. + * + * @param[in] path The path to look up. + * @param[out] uuid A pointer to a variable where the UUID will be stored if found. + * + * @return bool + * - true if the UUID is successfully retrieved. + * - false if the path is invalid or the UUID cannot be obtained. + * + * @remarks The caller is responsible for ensuring that the 'uuid' pointer is valid and properly aligned. */ -bool InstallWatch(const char *path, uint32_t *uuid); +bool GetUuidByPath(const char *path, uint32_t *uuid); #ifdef __cplusplus } #endif -#endif // WATCH_INTERFACE_H \ No newline at end of file +#endif // WATCH_INTERFACE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/CallerDisplayView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/CallerDisplayView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/makephone/include/CallerDisplayView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/makephone/CallerDisplayView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/CallingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/CallingView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/makephone/include/CallingView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/makephone/CallingView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/DialingScreenView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/DialingScreenView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/makephone/include/DialingScreenView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/makephone/DialingScreenView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/MainCallingPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/MainCallingPresenter.h similarity index 84% rename from code/sdk/application/wearable/nativeapp/nativeui/makephone/include/MainCallingPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/makephone/MainCallingPresenter.h index a9b800fce..56b231da4 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/MainCallingPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/MainCallingPresenter.h @@ -9,9 +9,9 @@ #include "Presenter.h" #include "ohos_types.h" -#include "CallerLogModel.h" -#include "VolumeSettingView.h" -#include "VolumeSettingPresenter.h" +#include "callerlog/CallerLogModel.h" +#include "main/VolumeSettingView.h" +#include "main/VolumeSettingPresenter.h" namespace OHOS { class MainCallingView; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/MainCallingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/MainCallingView.h similarity index 83% rename from code/sdk/application/wearable/nativeapp/nativeui/makephone/include/MainCallingView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/makephone/MainCallingView.h index e4bf8dd9d..0c7483a94 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/MainCallingView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/MainCallingView.h @@ -10,10 +10,10 @@ #include "View.h" #include "components/ui_view_group.h" #include "ohos_types.h" -#include "CallerDisplayView.h" -#include "CallingView.h" -#include "DialingScreenView.h" -#include "WaitingHintsView.h" +#include "makephone/CallerDisplayView.h" +#include "makephone/CallingView.h" +#include "makephone/DialingScreenView.h" +#include "makephone/WaitingHintsView.h" namespace OHOS { class MainCallingPresenter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/include/WaitingHintsView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/makephone/WaitingHintsView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/makephone/include/WaitingHintsView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/makephone/WaitingHintsView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/MainVocassistView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/MainVocassistView.h similarity index 85% rename from code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/MainVocassistView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/MainVocassistView.h index c039e7981..0ec4a21f3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/MainVocassistView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/MainVocassistView.h @@ -8,8 +8,8 @@ #define MAIN_VOCASSIST_VIEW_H #include "View.h" -#include "VocassistModel.h" -#include "VocassistView.h" +#include "offlinevoice/VocassistModel.h" +#include "offlinevoice/VocassistView.h" namespace OHOS { class VocassistPresenter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistModel.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistModel.h index e17d153fb..8c9e494ac 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistModel.h @@ -9,7 +9,7 @@ #define VOCASSIST_MODEL_H #include "smart_voice_service.h" -#include "VocassistView.h" +#include "offlinevoice/VocassistView.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistPresenter.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistPresenter.h index 5c3abe4f6..bdb49b9e4 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistPresenter.h @@ -10,8 +10,8 @@ #include "Presenter.h" #include "NativeAbility.h" -#include "VocassistView.h" -#include "MainVocassistView.h" +#include "offlinevoice/VocassistView.h" +#include "offlinevoice/MainVocassistView.h" namespace OHOS { class MainVocassistView; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistView.h index 541578ad4..3370008cf 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/include/VocassistView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/offlinevoice/VocassistView.h @@ -15,7 +15,7 @@ #include "UiConfig.h" #include "dfx/event_injector.h" #include "wearable_log.h" -#include "AppGroupView.h" +#include "main/AppGroupView.h" static constexpr const char VOCPHOTO_ID[] = "VOCPIC"; static constexpr const char VOC_ID[] = "VOC"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/include/PhoneAudio.h b/code/sdk/application/wearable/nativeapp/nativeui/include/phoneservice/PhoneAudio.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/phoneservice/include/PhoneAudio.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/phoneservice/PhoneAudio.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/include/PhoneService.h b/code/sdk/application/wearable/nativeapp/nativeui/include/phoneservice/PhoneService.h similarity index 99% rename from code/sdk/application/wearable/nativeapp/nativeui/phoneservice/include/PhoneService.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/phoneservice/PhoneService.h index 7e7dd371a..ebc275911 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/include/PhoneService.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/phoneservice/PhoneService.h @@ -10,7 +10,7 @@ #include "bts_br_gap.h" #include "bts_hfp_hf.h" #include "ohos_types.h" -#include "PhoneAudio.h" +#include "phoneservice/PhoneAudio.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/player/BluetoothView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/player/BluetoothView.h new file mode 100644 index 000000000..a5465e563 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/player/BluetoothView.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: Bluetooth view 设置页面 + * Create: 2021-09-5 + */ + +#ifndef BLUETOOTH_VIEW_H +#define BLUETOOTH_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_image_view.h" +#include "components/ui_radio_button.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" + +namespace OHOS { +class PlayerOnDragListener; +class BluetoothView { +public: + BluetoothView(); + virtual ~BluetoothView(); + UIViewGroup *LoadBluetoothView(void); + static BluetoothView *GetInstance(void); + UIViewGroup *group{nullptr}; + UIRadioButton *GetPhoneButton(void); + UIRadioButton *GetWatchButton(void); + UIButton *GetSettingButton(void); + UILabelButton *GetDeleteButton(void); +private: + UILabel *watchLabel{nullptr}; + UILabel *phoneLabel{nullptr}; + UILabel *bluetoothLabel{nullptr}; + UIImageView *watchImage{nullptr}; + UIImageView *phoneImage{nullptr}; + UIImageView *bluetoothImage{nullptr}; + UIRadioButton *watchButton{nullptr}; + UIRadioButton *phoneButton{nullptr}; + UIButton *settingButton{nullptr}; + UILabelButton *deleteButton{nullptr}; + int LoadRadioButton(); + int LoadButtonView(); + int LoadLabelButton(); + int LoadLabel(); + int LoadImage(); + + void SetUpButton(UILabelButton *btn, const Point& point, int16_t width, int16_t height, + UIView::OnClickListener *listener); +}; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersCaseListAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersCaseListAdapter.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersCaseListAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersCaseListAdapter.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersModel.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersModel.h index 61e90947c..f24dfceb7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersModel.h @@ -10,12 +10,12 @@ #include #include "gfx_utils/list.h" -#include "UiServersMsg.h" +#include "main/UiServersMsg.h" #include "player.h" #include "source.h" #include "audio_manager.h" #include "audio_base_type.h" -#include "PlayersPresenter.h" +#include "player/PlayersPresenter.h" #include "bts_avrcp_controller.h" namespace OHOS { @@ -88,13 +88,14 @@ public: int DecreaseVolume(void); int32_t GetPlayerstatus(); void SetBTMusicPlay(avrcp_key_operation_t notification); - void ConnectBtAndLocalPlay(int32_t connCtState, int32_t connTgState, int32_t playerState); // 蓝牙连接和本地播放 - void ConnectBtAndLocalPause(int32_t connCtState, int32_t connTgState); + int32_t ConnectBtAndLocalPlay(int32_t connCtState, int32_t connTgState, int32_t playerState); // 蓝牙连接和本地播放 + int32_t ConnectBtAndLocalPause(int32_t connCtState, int32_t connTgState); void ConncetBtResetButton(); void ClearActivateAudioInterrupt(void); void GetDuration(int64_t &duration); private: int64_t duration_{0}; + bool isInterruptedPause_{false}; bool audioInitStatus{false}; char *sliceId{nullptr}; List listPlayers; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersPresenter.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersPresenter.h index f955b7142..07d019467 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersPresenter.h @@ -13,19 +13,19 @@ #include "player.h" #include "audio_manager.h" #include "audio_base_type.h" -#include "BluetoothView.h" -#include "VolumeSettingView.h" -#include "VolumeSettingPresenter.h" -#include "BluetoothModel.h" -#include "BluetoothEarPhoneView.h" -#include "BluetoothEarListView.h" -#include "BluetoothOptionsView.h" -#include "BluetoothReconnectView.h" -#include "TipsSuccMessageView.h" -#include "TipsConnFailMessageView.h" -#include "TipsFailMessageView.h" -#include "BluetoothDeviceListView.h" -#include "BluetoothItemView.h" +#include "player/BluetoothView.h" +#include "main/VolumeSettingView.h" +#include "main/VolumeSettingPresenter.h" +#include "bluetooth/BluetoothModel.h" +#include "bluetooth/BluetoothEarPhoneView.h" +#include "bluetooth/BluetoothEarListView.h" +#include "bluetooth/BluetoothOptionsView.h" +#include "bluetooth/BluetoothReconnectView.h" +#include "bluetooth/TipsSuccMessageView.h" +#include "bluetooth/TipsConnFailMessageView.h" +#include "bluetooth/TipsFailMessageView.h" +#include "bluetooth/BluetoothDeviceListView.h" +#include "bluetooth/BluetoothItemView.h" namespace OHOS { using OHOS::Media::Player; @@ -138,6 +138,7 @@ public: bool IsResumed(); bool IsBeginStopped(); bool IsEndStopped(); + bool IsInterruptedPaused(); void OnInterrupt(int32_t type, int32_t hint) override; void PausePlayer(void); void ResumePlayer(void); @@ -151,6 +152,7 @@ private: bool isResumed_{false}; bool isBeginStopped_{false}; bool isEndStopped_{false}; + bool isInterruptedPause_{false}; }; // 滑动手势 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersView.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersView.h index 0dfcd5883..757fff50f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/include/PlayersView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/player/PlayersView.h @@ -23,7 +23,7 @@ #include "font/ui_font.h" #include "graphic_config.h" #include "components/ui_card_page.h" -#include "PlayersPresenter.h" +#include "player/PlayersPresenter.h" namespace OHOS { #define PLAY_PROGRESS_MIN 0 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnModel.h new file mode 100644 index 000000000..9bfab4573 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnModel.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: QrcodeConnModel.h + * Author: + * Create: 2025-04-24 + */ + +#ifndef QRCODE_CONN_MODEL_H +#define QRCODE_CONN_MODEL_H + +#include +#include +#include "AppViewIDs.h" +#include "UiConfig.h" + +namespace OHOS { +class QrcodeConnModel { +public: + static QrcodeConnModel &GetInstance(void); + +private: + QrcodeConnModel(); + QrcodeConnModel(const QrcodeConnModel &); + QrcodeConnModel &operator=(const QrcodeConnModel &); + virtual ~QrcodeConnModel(); + +private: +}; +} + +#endif // QRCODE_CONN_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnPresenter.h new file mode 100644 index 000000000..8914dc9d6 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnPresenter.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: QrcodeConnPresenter.h + * Author: + * Create: 2025-04-24 + */ + +#ifndef QRCODE_CONN_PRESENTER_H +#define QRCODE_CONN_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" +#include "qrcode_conn/QrcodeConnView.h" +#include "qrcode_conn/QrcodeConnModel.h" + +namespace OHOS { + +class QrcodeConnView; +class QrcodeConnModel; +class QrcodeConnPresenter : public Presenter, + public UIView::OnDragListener { +public: + QrcodeConnPresenter(); + ~QrcodeConnPresenter() override; + static QrcodeConnPresenter *GetInstance(); + bool OnDrag(UIView& view, const DragEvent& event) override; +private: +}; +} + +#endif // QRCODE_CONN_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnView.h new file mode 100644 index 000000000..24aaae618 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/qrcode_conn/QrcodeConnView.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: QrcodeConnView.h + * Author: + * Create: 2025-04-24 + */ + +#ifndef QRCODE_CONN_VIEW_H +#define QRCODE_CONN_VIEW_H + +#include +#include "View.h" +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "UiConfig.h" +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "components/ui_image_view.h" +#include "components/ui_qrcode.h" + +namespace OHOS { + +class QrcodeConnPresenter; +class QrcodeConnView : public View { +public: + QrcodeConnView(); + ~QrcodeConnView() override; + + static QrcodeConnView *GetInstance(); + + void OnStart() override; + void OnStop() override; + void InitView(); + void DeInit(); + +private: + UIScrollView *group_ = nullptr; + UIQrcode *qrcode_ = nullptr; +}; +} +#endif // QRCODE_CONN_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootDeviceView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootDeviceView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootDeviceView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootDeviceView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootModel.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootModel.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootPresenter.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootPresenter.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootView.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootView.h index 8627b6232..7ea1ed32f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/RebootView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/RebootView.h @@ -7,8 +7,8 @@ #define REBOOT_VIEW_H #include "View.h" -#include "ShutdownDeviceView.h" -#include "RebootDeviceView.h" +#include "rebootdevice/ShutdownDeviceView.h" +#include "rebootdevice/RebootDeviceView.h" #include "components/ui_view_group.h" #include "components/ui_label.h" #include "components/ui_button.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/ShutdownDeviceView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/ShutdownDeviceView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/include/ShutdownDeviceView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/rebootdevice/ShutdownDeviceView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppPresenter.h new file mode 100644 index 000000000..ccc47e1be --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppPresenter.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 CompanyNameMagicTag. + * 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. + */ + +#ifndef RECENT_APP_PRESENTER_H +#define RECENT_APP_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" + +namespace OHOS { +class RecentAppView; +class RecentAppPresenter : public Presenter, public UIView::OnClickListener { +public: + RecentAppPresenter(); + ~RecentAppPresenter() override; + void OnResume() override; + bool OnClick(UIView &view, const ClickEvent &event) override; +}; +} + +#endif // RECENT_APP_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppView.h new file mode 100644 index 000000000..02dc69422 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/recent_app/RecentAppView.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 CompanyNameMagicTag. + * 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. + */ + +#ifndef RECENT_APP_VIEW_H +#define RECENT_APP_VIEW_H + +#include +#include "recent_app/RecentAppPresenter.h" +#include "View.h" +#include "animator/animator.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_roller_view.h" + +namespace OHOS { +static constexpr const char* RECENT_APP_DELETE_BTN_ID = "RecentAppDeleteBtn"; +static std::string RECENT_ITEM_NATIVE_PREFIX = "NA_"; +static std::string RECENT_ITEM_JS_PREFIX = "JS_"; +static constexpr const uint8_t RECENT_ITEM_PREFIX_LEN = 3; +class RecentAppView : public View { +public: + RecentAppView(); + ~RecentAppView() override; + void OnStart() override; + void LoadContent(); + UIRollerView* GetRollerView() + { + return roller_; + } +private: + class LoadingAnimCb : public AnimatorCallback { + public: + LoadingAnimCb() {} + ~LoadingAnimCb() override {} + void Callback(UIView* view) override; + void SetRecentAppView(RecentAppView* recentAppView) + { + recentAppView_ = recentAppView; + } + private: + RecentAppView* recentAppView_; + }; + + void AddRecentAppToRoller(); + void LoadRecentAppContent(); + void InitRecentApps(); + UIRollerView* roller_ = nullptr; + Animator* loadingAnim_ = nullptr; + UILabel* loadingLabel_ = nullptr; + UILabel* noRecentAppLabel_ = nullptr; + UILabelButton* delBtn_ = nullptr; + LoadingAnimCb loadingAnimCb_; + bool viewiInitStatus_ = false; +}; +} // namespace OHOS +#endif // RECENT_APP_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreDefaultsPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreDefaultsPresenter.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreDefaultsPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreDefaultsPresenter.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreDefaultsView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreDefaultsView.h similarity index 84% rename from code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreDefaultsView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreDefaultsView.h index 18ac59105..bdfd4e1c3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreDefaultsView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreDefaultsView.h @@ -8,9 +8,9 @@ #define RESTORE_DEFAULTS_VIEW_H #include "View.h" -#include "RestoreDefaultsPresenter.h" -#include "RestoreSelectView.h" -#include "AppGroupView.h" +#include "restoredefaults/RestoreDefaultsPresenter.h" +#include "restoredefaults/RestoreSelectView.h" +#include "main/AppGroupView.h" namespace OHOS { constexpr int16_t NUM_RESTORE_DEFAULTS_CONTAINER = 1; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreSelectView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreSelectView.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreSelectView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreSelectView.h index 85861750a..4eb08e437 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/include/RestoreSelectView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/restoredefaults/RestoreSelectView.h @@ -8,7 +8,7 @@ #define RESTORE_SELECT_VIEW_H #include "View.h" -#include "RestoreDefaultsPresenter.h" +#include "restoredefaults/RestoreDefaultsPresenter.h" #include "components/ui_label.h" #include "components/ui_button.h" #include "components/ui_view_group.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rtcservice/include/RtcService.h b/code/sdk/application/wearable/nativeapp/nativeui/include/rtcservice/RtcService.h similarity index 86% rename from code/sdk/application/wearable/nativeapp/nativeui/rtcservice/include/RtcService.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/rtcservice/RtcService.h index bbda60eb4..3ebf69730 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rtcservice/include/RtcService.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/rtcservice/RtcService.h @@ -10,7 +10,7 @@ #include "service.h" #include "iunknown.h" #include "broadcast_feature.h" -#include "AlarmClockManage.h" +#include "alarmclockmanage/AlarmClockManage.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/screennotify/include/ui_screennotify.h b/code/sdk/application/wearable/nativeapp/nativeui/include/screennotify/ui_screennotify.h similarity index 67% rename from code/sdk/application/wearable/nativeapp/nativeui/screennotify/include/ui_screennotify.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/screennotify/ui_screennotify.h index 39399a4f4..d06c8d7c0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/screennotify/include/ui_screennotify.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/screennotify/ui_screennotify.h @@ -41,6 +41,20 @@ void set_back_to_home_interval(uint32_t time_sec); */ uint32_t get_back_to_home_interval(void); +/** + * @brief 设置进入AOD后返回上一个应用的可返回时间间隔,需要在slice对应的Presentor的OnStart方法中调用 + * 默认可返回时间间隔是5秒,进入AOD超过5秒后再次亮屏会跳回主界面 + * @param time_sec 设置的可返回时间间隔 + */ +void set_back_to_pre_slice_interval(uint32_t time_sec); + +/** + * @brief 获取进入AOD后返回上一个应用的可返回时间间隔,需要在slice对应的Presentor的OnStart方法中调用 + * 默认可返回时间间隔是5秒,进入AOD超过5秒后再次亮屏会跳回主界面 + * @param time_sec 获取的可返回时间间隔 + */ +uint32_t get_back_to_pre_slice_interval(void); + #ifdef __cplusplus } #endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/screensetting/include/ScreenModels.h b/code/sdk/application/wearable/nativeapp/nativeui/include/screensetting/ScreenModels.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/screensetting/include/ScreenModels.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/screensetting/ScreenModels.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardAdapter.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardAdapter.h index 75b9ba8d0..50ca27d1e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardAdapter.h @@ -17,7 +17,7 @@ #include "components/abstract_adapter.h" #include "UiConfig.h" #include "wearable_log.h" -#include "SetCardItem.h" +#include "set_card/SetCardItem.h" namespace OHOS { class SetCardAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardDeleteView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardDeleteView.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardDeleteView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardDeleteView.h index 6abfe4ee1..14fd9e307 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardDeleteView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardDeleteView.h @@ -9,7 +9,7 @@ #define SET_CARD_DELETE_VIEW_H #include "components/ui_label_button.h" -#include "SetCardPresenter.h" +#include "set_card/SetCardPresenter.h" namespace OHOS { class SetCardDeleteView : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardItem.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardItem.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardItem.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardItem.h index 3926d9357..1d545c1bb 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardItem.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardItem.h @@ -13,7 +13,7 @@ #include "components/ui_view.h" #include "components/ui_view_group.h" #include "components/ui_image_view.h" -#include "MainModel.h" +#include "main/MainModel.h" #include "UiConfig.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardModel.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardModel.h index 43ed70b26..74ca5bd2d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardModel.h @@ -12,8 +12,8 @@ #include #include "AppViewIDs.h" #include "UiConfig.h" -#include "SetCardPresenter.h" -#include "SetCardItem.h" +#include "set_card/SetCardPresenter.h" +#include "set_card/SetCardItem.h" namespace OHOS { class SetCardModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardNoCardView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardNoCardView.h similarity index 88% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardNoCardView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardNoCardView.h index dc8ee1226..711648810 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardNoCardView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardNoCardView.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "SetCardPresenter.h" +#include "set_card/SetCardPresenter.h" namespace OHOS { class SetCardNoCardView : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardPresenter.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardPresenter.h index fb73852ce..8af598cdd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardPresenter.h @@ -11,7 +11,7 @@ #include "Presenter.h" #include "components/ui_list.h" #include "components/ui_view.h" -#include "ModelListenerSample.h" +#include "main/ModelListenerSample.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardView.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardView.h index 22e95d899..fb5c224ee 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/include/SetCardView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_card/SetCardView.h @@ -15,10 +15,10 @@ #include "components/ui_toggle_button.h" #include "ChangeSliceListener.h" #include "UiConfig.h" -#include "SetCardAdapter.h" -#include "SetCardModel.h" -#include "SetCardDeleteView.h" -#include "SetCardNoCardView.h" +#include "set_card/SetCardAdapter.h" +#include "set_card/SetCardModel.h" +#include "set_card/SetCardDeleteView.h" +#include "set_card/SetCardNoCardView.h" namespace OHOS { class SetCardPresenter; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialInfo.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialInfo.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialInfo.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialInfo.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialModel.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialModel.h index ff3787b17..546e89d86 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialModel.h @@ -9,7 +9,7 @@ #define SET_DIAL_MODEL_H #include "AppViewIDs.h" #include "UiConfig.h" -#include "SetDialInfo.h" +#include "set_dial/SetDialInfo.h" namespace OHOS { class SetDialModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialPresenter.h similarity index 75% rename from code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialPresenter.h index 80fc743b0..a50ffdada 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialPresenter.h @@ -7,13 +7,15 @@ #ifndef SET_DIAL_PRESENTER_H #define SET_DIAL_PRESENTER_H -#include "SetDialInfo.h" -#include "SetDialModel.h" +#include "set_dial/SetDialInfo.h" +#include "set_dial/SetDialModel.h" #include "Presenter.h" #include "components/ui_view.h" #include "components/ui_roller_view.h" -#include "KeyInputListener.h" -#include "ModelListenerSample.h" +#include "key/KeyInputListener.h" +#include "main/ModelListenerSample.h" +#include "components/ui_coverflow_view.h" +#include "main/MainModel.h" namespace OHOS { @@ -28,6 +30,8 @@ class SetDialPresenter : public Presenter, public: SetDialPresenter(); ~SetDialPresenter() override; + static SetDialPresenter *GetCurrentInstance(); + void SpecifyDialSetting(const DialSetting &setting); size_t GetDialCount(void); std::vector& GetDialInfo(void); uint8_t GetPageIndex(void); @@ -42,6 +46,8 @@ private: void OnClickAction(void); SetDialModel *model{nullptr}; uint64_t startTime{0}; + bool isSpecific = false; + DialSetting specificSetting; }; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/set_dial/include/SetDialView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_dial/SetDialView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/include/SetDialStyleModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial_style/SetDialStyleModel.h similarity index 96% rename from code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/include/SetDialStyleModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_dial_style/SetDialStyleModel.h index c27e3007a..7ed274df2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/include/SetDialStyleModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial_style/SetDialStyleModel.h @@ -7,7 +7,7 @@ #ifndef SET_DIAL_STYLE_MODEL_H #define SET_DIAL_STYLE_MODEL_H -#include "SetDialView.h" +#include "set_dial/SetDialView.h" #include "components/ui_view.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/include/SetDialStylePresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial_style/SetDialStylePresenter.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/include/SetDialStylePresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/set_dial_style/SetDialStylePresenter.h index fda918ece..d867280af 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/include/SetDialStylePresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_dial_style/SetDialStylePresenter.h @@ -7,7 +7,7 @@ #ifndef SET_DIAL_STYLE_PRESENTER_H #define SET_DIAL_STYLE_PRESENTER_H -#include "SetDialView.h" +#include "set_dial/SetDialView.h" #include "components/ui_view.h" #include "Presenter.h" @@ -19,7 +19,7 @@ class SetDialStylePresenter : public Presenter +namespace OHOS { + +enum class TaskType { UpdateInfo, LocalUpdate, Unknown }; + +struct LocalUpdateData { + uint32_t fileSize; +}; + +class OTAPresenter; +class OTAModel : public Model { +public: + OTAModel(); + ~OTAModel(); + +public: + bool ModelRunTask(TaskType type, void *data); + +protected: + void SwitchTask(); + void UpdateInfo(void *data); + void LocalUpdate(void *data); + +protected: + void DelayRebootFor5S(); + void UpdatePercentCallback(uint32_t percent); + +protected: + static int OSALKthreadCallback(void *data); + static int WaitCondition(const void *data); + +protected: + static void OtaUpdatePercentCallback(uint32_t percent); + +private: + osal_task *task = nullptr; + osal_wait wait; + std::atomic_bool isIdel; + TaskType type = TaskType::Unknown; + void *data = nullptr; +}; + +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAPresenter.h new file mode 100644 index 000000000..8c37384eb --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAPresenter.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: ota local update + * Author: wangle + * Create: 2025-5-6 + */ +#ifndef OTA_PRESENTER_H +#define OTA_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" +#include "set_ota/OTAModel.h" + +namespace OHOS { + +class OTAView; +class OTAPresenter : public Presenter, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + void OnStart() override; + void OnStop() override; + +public: + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; +public: + // Model调用 + void SetPackageInfo(const char* filePath, uint32_t fileSize); + void SetUpdateProgress(const char* message, uint8_t progress); + void SetErrorMessage(const char* message); + void SetMessage(const char* message); +protected: + void SaveSystemScreen(); + void BackSystemScreen(); +private: + bool updateEnable = true; + const char* updateFilePath = nullptr; + uint32_t updateFileSize = 0; + uint32_t briScrStatus = 0; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAView.h new file mode 100644 index 000000000..1beee87c4 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/set_ota/OTAView.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: ota local update + * Author: wangle + * Create: 2025-5-6 + */ +#ifndef OTA_VIEW_H +#define OTA_VIEW_H + +#include "View.h" +#include "Presenter.h" +#include "components/ui_label.h" +#include "components/ui_box_progress.h" +#include "components/ui_label_button.h" + +namespace OHOS { +class OTAPresenter; +class OTAView : public View { +public: + OTAView(){}; + ~OTAView(){}; + void OnStart() override; + void OnStop() override; + void InitMessageCtrl(); + void InitProgressCtrl(); + void InitUpdateCtrl(); + void AddCtrlToView(); + void DeInitMessageCtrl(); + void DeInitProgressCtrl(); + void DeInitUpdateCtrl(); + +public: + void SetUpdateEnable(); + void SetUpdateDisable(); + void SetMessage(const char *msg); + void SetProgress(uint8_t progress); + +private: + UILabel *message = nullptr; + UIBoxProgress *progress = nullptr; + UILabelButton *update = nullptr; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SetDesktopModel.h similarity index 58% rename from code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/settings/SetDesktopModel.h index 723a0c30d..2866da667 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SetDesktopModel.h @@ -1,8 +1,8 @@ /* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SetDesktopModel.h - * Author: - * Create: 2021-11-23 + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SetDesktopModel + * Author: Hisi Graphic Team + * Created: 2025-4 */ #ifndef SET_DESKTOP_MODEL_H @@ -27,10 +27,8 @@ namespace OHOS { DesktopStyle GetDesktopStyle(void); void SetDesktopStyle(DesktopStyle style); private: - SetDesktopModel(); - SetDesktopModel(const SetDesktopModel &); - SetDesktopModel &operator=(const SetDesktopModel &); - virtual ~SetDesktopModel(); + SetDesktopModel() = default; + virtual ~SetDesktopModel() = default; }; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingAdapter.h similarity index 94% rename from code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingAdapter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingAdapter.h index d89fe3ee0..a3c5f69ca 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingAdapter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingAdapter.h @@ -17,8 +17,8 @@ #include "components/abstract_adapter.h" #include "wearable_log.h" #include "UiConfig.h" -#include "SettingModel.h" -#include "SettingItemView.h" +#include "settings/SettingModel.h" +#include "settings/SettingItemView.h" namespace OHOS { class SettingAdapter : public AbstractAdapter { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingDesktopPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingDesktopPage.h new file mode 100644 index 000000000..8e8dd1e6d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingDesktopPage.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingDesktopPage + * Author: Hisi Graphic Team + * Created: 2025-4 + */ + +#ifndef SETTING_DESKTOP_PAGE_H +#define SETTING_DESKTOP_PAGE_H + +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_image_view.h" +#include "components/ui_toggle_button.h" +#include "SlicePage.h" +#include "UiConfig.h" +#include "settings/SetDesktopModel.h" +#include "settings/SettingPresenter.h" + +namespace OHOS { +class SettingDesktopPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + SettingDesktopPage(); + ~SettingDesktopPage() override; + void OnStart(void* data) override; + void UpdateSelectedStyle(DesktopStyle selectedStyle); + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + +private: + void InitFootballItem(); + void InitWaterfallItem(); + UIScrollView *scrollview{nullptr}; + UILabel titleText; + UIToggleButton hexagonsBtn; + UIToggleButton listBtn; + UIToggleButton footballBtn_; + UIToggleButton waterfallBtn_; + UIImageView hexagonsImage; + UIImageView listImage; + UIImageView footballImage_; + UIImageView waterfallImage_; + UILabel listText; + UILabel hexagonsText; + UILabel footballText_; + UILabel waterfallText_; +}; +} +#endif // SETTING_DESKTOP_PAGE_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingItem.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingItem.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingItem.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingItem.h index 0031350f1..c45c20469 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingItem.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingItem.h @@ -12,7 +12,7 @@ namespace OHOS { typedef struct { - AppViewId viewId; + uint32_t targetId; const char *icon; const char *label; bool hasSecondMenu; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingItemView.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingItemView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingItemView.h index f045d1cbe..11ba9444e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingItemView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingItemView.h @@ -13,7 +13,7 @@ #include "components/ui_image_view.h" #include "UiConfig.h" -#include "SettingModel.h" +#include "settings/SettingModel.h" namespace OHOS { class SettingItemView : public UIViewGroup { @@ -26,7 +26,7 @@ public: { return sItemInfo.enableSlideBack; } - AppViewId GetViewId(); + uint32_t GetTargetId(); const char* GetIconId(); private: UIImageView sIcon; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingMainPage.h new file mode 100644 index 000000000..5d3a8c47d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingMainPage.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingMainPage + * Author: Hisi Graphic Team + * Created: 2025-4 + */ + +#ifndef SETTING_MAIN_PAGE_H +#define SETTING_MAIN_PAGE_H + +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "SlicePage.h" +#include "settings/SettingAdapter.h" +#include "settings/SettingPresenter.h" + +namespace OHOS { +class SettingPresenter; +class SettingMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + SettingMainPage() = default; + ~SettingMainPage() override; + + void OnStart(void* data) override; + void RefreshSettingsList(const SettingItem* item, uint8_t count); + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; +private: + SettingAdapter *listAdapter{nullptr}; + UIScrollView *scrollView{nullptr}; + UIList *contentList{nullptr}; + UILabel *title{nullptr}; +}; +} +#endif // SETTING_MAIN_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingModel.h similarity index 93% rename from code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingModel.h index 6a50ebfc8..191a64913 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingModel.h @@ -12,8 +12,8 @@ #include #include "AppViewIDs.h" #include "UiConfig.h" -#include "SettingItem.h" -#include "SettingPresenter.h" +#include "settings/SettingItem.h" +#include "settings/SettingPresenter.h" namespace OHOS { static const uint16_t SETTING_ITEM_COUNT = 10; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingPresenter.h new file mode 100644 index 000000000..16595d225 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingPresenter.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: SettingPresenter.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef SETTING_PRESENTER_H +#define SETTING_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { +class SettingView; +class SettingPresenter : public Presenter { +}; +} + +#endif // SETTING_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingView.h new file mode 100644 index 000000000..2f79acf50 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/settings/SettingView.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025. All rights reserved. + * Description: SettingPage.h + * Author: + * Create: 2025-04-14 + */ + +#ifndef SETTING_VIEW_H +#define SETTING_VIEW_H + +#include "View.h" +namespace OHOS { +enum SETTING_PAGES { + SETTING_MAIN_PAGE = 1, // 0 is invalid + SETTING_DESKTOP_PAGE = 2, +}; + +class SettingPresenter; +class SettingView : public View { +}; +} +#endif // SETTING_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingDetailsPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingDetailsPage.h new file mode 100644 index 000000000..34cb969fd --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingDetailsPage.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingDetailsPage + * Created: 2025-06-05 + */ +#ifndef SLEEPING_DETAILS_PAGE_H +#define SLEEPING_DETAILS_PAGE_H + +#include "View.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "components/ui_image_animator.h" +#include "components/ui_circle_progress.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "SlicePage.h" +#include "main/LoadImg.h" +#include "ui_resource_sleep.h" +#include "sleep/SleepingPresenter.h" +#include "sleep/SleepingView.h" +#include "sleep/SleepingModel.h" + +namespace OHOS { +class SleepingPresenter; +class SleepingDetailsPage : public SlicePage, + public UIView::OnDragListener { +public: + SleepingDetailsPage(); + ~SleepingDetailsPage() override; + + void OnStart(void* data) override; + void InitPage(); + void InitNoDeatilPage(); + void InitDetailPage(); + + void InitSoberingTime(); + void InitRapidEyeMovement(); + void InitLightSleepTime(); + void InitDeepSleepTime(); + bool OnDrag(UIView &view, const DragEvent &event) override; + bool GetRecord(); + std::string SetTimeText(std::tuple timeTuple); + void InitActualSleepTime(std::tuple timeTuple); + void IoadDeatilActualSleepTime(); +private: + + UIScrollView *group{nullptr}; + UIImageView *detailsSleepView{nullptr}; + UILabel *sleep{nullptr}; + UILabel *actualSleepTime{nullptr}; + UILabel *actualSleepTimeHours{nullptr}; + UILabel *actualSleepTimeHoursText{nullptr}; + UILabel *actualSleepTimeMinutes{nullptr}; + UILabel *actualSleepTimeMinutesText{nullptr}; + UIImageView *grayBg{nullptr}; + + UIImageView *image1{nullptr}; + UILabel *soberingTime_{nullptr}; + UILabel *soberingTimeText{nullptr}; + UIImageView *image2{nullptr}; + UILabel *rapidEyeMovement_ {nullptr}; + UILabel *rapidEyeMovementText{nullptr}; + UIImageView *image3{nullptr}; + UILabel *lightSleepTime_{nullptr}; + UILabel *lightSleepTimeText{nullptr}; + UIImageView *image4{nullptr}; + UILabel *deepSleepTime_{nullptr}; + UILabel *deepSleepTimeText{nullptr}; +}; +} + +#endif // SLEEPING_DETAILS_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingMainPage.h new file mode 100644 index 000000000..72492303e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingMainPage.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingMainPage + * Created: 2025-06-05 + */ +#ifndef SLEEPING_MAIN_PAGE_H +#define SLEEPING_MAIN_PAGE_H + +#include "View.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "components/ui_image_animator.h" +#include "components/ui_circle_progress.h" +#include "components/ui_view_group.h" +#include "components/ui_circle_progress.h" +#include "components/ui_scroll_view.h" +#include "ui_resource_sleep.h" +#include "main/LoadImg.h" +#include "sleep/TargetSleepTime.h" +#include "sleep/SleepingPresenter.h" +#include "sleep/SleepingView.h" +#include "sleep/SleepingModel.h" + + +namespace OHOS { +class SleepingPresenter; +class SleepingMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + SleepingMainPage(); + ~SleepingMainPage() override; + + void OnStart(void* data) override; + void InitNoRecordPage(); + void InitRecordPage(); + void IoadActualSleepTime(std::tuple timeTuple); + void IoadTargetTimeButton(std::tuple timeTuple); + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + void CircleProgress(); + void TargetTimeButton(); + uint32_t GetSleepingScores(); + void InitSleepTimeLabel(); + void ScoreDisplay(); + bool GetRecord(); + void InitScoreDisplayPicture(); +private: + + UIImageView *imageViewMain{nullptr}; + UILabel *sleep{nullptr}; + UIImageView *moonNoRecord{nullptr}; + UIImageView *moon{nullptr}; + UILabel *noRecord{nullptr}; + UILabel *tips{nullptr}; + + UILabel *sleepScores_{nullptr}; + UILabel *scoreText{nullptr}; + UILabel *sleepScore{nullptr}; + + UIImageView *scoreDisplayPicture1{nullptr}; + UIImageView *scoreDisplayPicture2{nullptr}; + UIImageView *scoreDisplayPicture3{nullptr}; + UIImageView *scoreDisplayPicture4{nullptr}; + UIImageView *scoreDisplayPicture5{nullptr}; + UIImageView *setting{nullptr}; + UILabel *actualSleepTimeHours{nullptr}; + UILabel *actualSleepTimeHoursText{nullptr}; + UILabel *actualSleepTimeMinutes{nullptr}; + UILabel *actualSleepTimeMinutesText{nullptr}; + + UILabelButton *targetTimeButton{nullptr}; + UILabel *targetTimeText{nullptr}; + UICircleProgress* circleProgress{nullptr}; + + UIScrollView *group{nullptr}; +}; +} + +#endif // SLEEPING_MAIN_PAGE_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingModel.h new file mode 100644 index 000000000..08965502e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingModel.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingModel + * Created: 2025-06-05 + */ +#ifndef SLEEPING_MODEL_H +#define SLEEPING_MODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include "AppViewIDs.h" +#include "UiConfig.h" +#include "graphic_timer.h" +#include "ohos_timer.h" +#include "wearable_log.h" +#include "diag_service.h" +#include "msg_center_device.h" +#include "diag_common.h" +#include "sleep/SleepingPresenter.h" + +namespace OHOS { + static const uint16_t SLEEP_DATA_DATE_RANGE = 20; + static const uint16_t SLEEP_DATA_START_DATA_RANGE = 24; + + #pragma pack(1) + typedef struct { + bool isSend; + char date[SLEEP_DATA_DATE_RANGE]; + uint8_t type; // 睡眠类别 深睡 浅睡 快速动眼 清醒 + char start[SLEEP_DATA_START_DATA_RANGE]; + char end[SLEEP_DATA_START_DATA_RANGE]; + char sleepStart[SLEEP_DATA_START_DATA_RANGE]; + char sleepEnd[SLEEP_DATA_START_DATA_RANGE]; + } SleepData; + #pragma pack() + + + class SleepingModel { + public: + static SleepingModel &GetInstance(void); + void SendData(); + uint8_t* SerializeSleepData(const SleepData* sleepData, size_t* outSize); + void SetSleepData(); + void SetTime(uint32_t minute); + std::tuple GetTime(); + void SetData(); + std::tuple GetSoberingTime(); + std::tuple GetRapidEyeMovementTime(); + std::tuple GetLightSleepTime(); + std::tuple GetDeepSleepTime(); + std::tuple GetSleepTime(); + void SetSoberingTime(); + void SetRapidEyeMovementTime(); + void SetLightSleepTime(); + void SetDeepSleepTime(); + bool GetRecord(); + uint32_t GetSleepTimeHours(); + uint32_t GetSleepTimeMinutes(); + std::tuple MinutesToHours(uint32_t minutes); + uint32_t TimeDiffInMinutes(const std::string& timeStr1, const std::string& timeStr2); + uint32_t GetDetailData(int type); + uint32_t GetTotalSleepTime(); + + private: + SleepingModel(); + void PrintSleepData(const SleepData *data); + virtual ~SleepingModel(); + uint32_t sleepTarget = 0; + std::vector sleepDataVector; + uint32_t soberingTime; + uint32_t eyeMoveTime; + uint32_t lightTime; + uint32_t deepTime; + }; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingPresenter.h new file mode 100644 index 000000000..2e0fdfa4d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingPresenter.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingPresenter + * Created: 2025-06-05 + */ + +#ifndef SETTING_PRESENTER_H +#define SETTING_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { +class SleepingView; +class SleepingPresenter : public Presenter { +}; +} + +#endif // SETTING_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingView.h new file mode 100644 index 000000000..67325adf9 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/SleepingView.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingView + * Created: 2025-06-05 + */ + +#ifndef SLEEPING_VIEW_H +#define SLEEPING_VIEW_H + +#include "View.h" +namespace OHOS { +enum SLEEPING_PAGES { + SLEEPING_MAIN_PAGE = 1, // 0 is invalid + SLEEPING_DEATIL_PAGE = 2, + SLEEPING_TARGET_PAGE = 3, +}; + +class SleepingPresenter; +class SleepingView : public View { +}; +} +#endif // SLEEPING_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/TargetSleepTime.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/TargetSleepTime.h new file mode 100644 index 000000000..2aa0f8be1 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sleep/TargetSleepTime.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetSleepTime + * Created: 2025-06-05 + */ + +#ifndef TARGET_SLEEP_TIME_H +#define TARGET_SLEEP_TIME_H + +#include "View.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "components/ui_image_animator.h" +#include "components/ui_circle_progress.h" +#include "components/ui_view_group.h" +#include "components/ui_picker.h" +#include "components/ui_scroll_view.h" +#include "main/LoadImg.h" +#include "sleep/SleepingPresenter.h" +#include "sleep/SleepingView.h" +namespace OHOS { +class TargetSleepTime : public SlicePage, + public UIPicker::SelectedListener, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + TargetSleepTime() = default; + ~TargetSleepTime() override; + + void OnStart(void* data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + void OnPickerStoped(UIPicker& picker) override; + void TargetTimeButton(); + void CreatePicker(); + void CreateLabel(); + void SetPickerTime(); +private: + UILabel* setTraget{nullptr}; + UILabel* timerLabel{nullptr}; + UILabelButton *startButton{nullptr}; + UIImageView *backgroundImage{nullptr}; + UIScrollView *group{nullptr}; + UIPicker* timerPicker[2]{nullptr}; +}; +} +#endif // TARGET_SLEEP_TIME_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsModel.h new file mode 100644 index 000000000..8b7b56a1f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsModel.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Sports Model + * Create: 2025-04-28 + */ + +#ifndef SPORTS_MODEL_H +#define SPORTS_MODEL_H +#include "graphic_timer.h" + +namespace OHOS { + +typedef struct sport_data { + uint32_t step; + uint32_t distance; + int32_t lat; + int32_t lng; + uint32_t speed; + uint16_t heartrate; +} sport_data_t; + +class SportsModel { +public: + ~SportsModel(); + static SportsModel *GetInstance(void); + void Init(); + bool StartSportsTimer(); + void StopSportsTimer(bool isDelete); + void IncrSportsTime(); + std::string CountingSportsTime(); + bool IsActive(); + sport_data_t *GetSportsData(); + void ResetSportsData(); + uint32_t CalculateSpeed(uint32_t distance); + +private: + SportsModel(); + void InitSportsTimer(); + uint32_t uiSportTime_ = 0; + bool isActive_{false}; + GraphicTimer *pGraphicTimer_{nullptr}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsPresenter.h new file mode 100644 index 000000000..6ff4a6985 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsPresenter.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: sports Presenter + * Create: 2025-04-28 + */ + +#ifndef SPORTS_PRESENTER_H +#define SPORTS_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { + +class SportsView; +class SportsPresenter : public Presenter, + public UIView::OnDragListener { +public: + SportsPresenter(); + ~SportsPresenter(); + static SportsPresenter *GetInstance(); + bool OnDrag(UIView& view, const DragEvent& event) override; +private: +}; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsView.h new file mode 100644 index 000000000..aeca78761 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/sports/SportsView.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: sports View + * Create: 2025-04-28 + */ +#ifndef SPORTS_VIEW_H +#define SPORTS_VIEW_H + +#include "View.h" +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_image_view.h" + +namespace OHOS { + +enum SportDataType { + SPORT_TIME = 0, + SPORT_SETP, + SPORT_DISTANCE, + SPORT_HEARTRATE, + SPORT_SPEED, + SPORT_MAX, +}; + +class SportsPresenter; +class SportsView : public View { +public: + SportsView(); + ~SportsView() override; + static SportsView *GetInstance(); + void OnStart() override; + void SetStep(uint32_t step); + void SetHeartRate(uint16_t heartrate); + void SetDistance(uint32_t distance); + void SetTime(const char *time); + void SetSpeed(uint32_t speed); + +private: + bool InitView(); + bool InitLableView(int index, const char *text, uint16_t x, uint16_t y1, uint16_t w, uint16_t y2); + void InitSportDataLabel(); + UILabel TitleLabel[SPORT_MAX]; + UILabel ContentLabel[SPORT_MAX]; + UIViewGroup *group{nullptr}; + UIImageView *backGround{nullptr}; +}; +} // namespace OHOS +#endif // SPORTS_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchAdapter.h new file mode 100644 index 000000000..bd160d86e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchAdapter.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchAdapter + * Create: 2025-06-06 + */ + +#ifndef STOPWATCH_ADAPTER_H +#define STOPWATCH_ADAPTER_H + +#include "gfx_utils/list.h" +#include "components/abstract_adapter.h" +#include "stopwatch/StopwatchItemView.h" + +namespace OHOS { + +class StopwatchAdapter : public AbstractAdapter { +public: + explicit StopwatchAdapter(); + ~StopwatchAdapter() override; + + void SetData(const List &data); + + uint16_t GetCount(void) override; + UIView *GetView(UIView *inView, int16_t index) override; + +private: + List listData_; +}; +} + +#endif // STOPWATCH_ADAPTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchItemView.h new file mode 100644 index 000000000..b4a48db38 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchItemView.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchItemView + * Create: 2025-06-06 + */ + +#ifndef STOPWATCH_ITEM_VIEW_H +#define STOPWATCH_ITEM_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" + +namespace OHOS { +typedef struct { + std::string record; + bool isLatest; +} StopwatchItem; + +class StopwatchItemView : public UIViewGroup { +public: + explicit StopwatchItemView(); + virtual ~StopwatchItemView() override; + void SetItemInfo(int16_t index, const StopwatchItem &itemInfo); + +private: + UILabel nameLabel_; + UILabel recordLabel_; + UILabelButton itemBg_; +}; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchModel.h new file mode 100644 index 000000000..41c75f093 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchModel.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchModel + * Create: 2025-06-06 + */ + +#ifndef STOPWATCH_MODEL_H +#define STOPWATCH_MODEL_H + +#include "stopwatch/StopwatchItemView.h" +#include "gfx_utils/list.h" +#ifndef _WIN32 +#include "time64.h" +#endif + +namespace OHOS { +class StopwatchModel { +public: + ~StopwatchModel(); + static StopwatchModel &GetInstance(void); + + void SetStartTime(); + void SaveElapsedTime(); + uint64_t GetElapsedTime(); + uint64_t UpdateElapsedTime(); + void ResetCounter(); + bool GetActiveState(); + void SetActiveState(); + void SetInactiveState(); + List &GetRecordsList(); + void AddRecordToList(const StopwatchItem &record); + void ClearData(); + bool IsInRecordView(); + void SetRecordViewState(bool state); + bool GetOverflowState() + { + return isOverflow_; + } + void SetOverflowState(bool state) + { + isOverflow_ = state; + } + +private: + StopwatchModel(); + StopwatchModel(const StopwatchModel &); + StopwatchModel &operator=(const StopwatchModel &); +#ifdef _WIN32 + struct timeval startTime_ {0}; +#else + struct timeval64 startTime_ {0}; +#endif + bool isOverflow_{false}; + uint64_t uiElapsedTime_{0}; + uint64_t uiSavedElapsedTime_{0}; + bool bIsActive_{false}; + bool bIsRecordView_{false}; + List records_; +}; +} + +#endif // STOPWATCH_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPage.h new file mode 100644 index 000000000..9568a306c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPage.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchPage + * Create: 2025-06-06 + */ + +#ifndef STOPWATCH_PAGE_H +#define STOPWATCH_PAGE_H + +#include "UiConfig.h" +#include "SlicePage.h" +#include "stopwatch/StopwatchPresenter.h" +#include "stopwatch/StopwatchAdapter.h" +#include "NativeRegisterManager.h" +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_label_button.h" +#include "components/ui_image_view.h" +#include "components/ui_sweep_clock.h" +#include "animator/animator.h" + +namespace OHOS { + +#define STOPWATCH_APP_NAME "秒表" + +class StopwatchPresenter; +class StopwatchPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + StopwatchPage(); + ~StopwatchPage() override; + + void OnStart(void* data) override; + void OnStop() override; + void OnPause() override; + void OnResume() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + void Overflowing(void); + UISweepClock* GetSweepClock(){return sweepClock_;} + UILabel* GetElapsedTimeLabel(){return elapsedTime_;} +private: + void DrawButtonStatusView(bool isActive); + void DrawContainRecordListView(bool isContainRecordList); + void RefreshRecordsList(void); + class StopwatchAnimatorCallback : public AnimatorCallback { + public: + StopwatchAnimatorCallback(StopwatchPage* page) : stopwatchPage(page) {} + virtual ~StopwatchAnimatorCallback() override {} + void Callback(UIView* view) override; + private: + StopwatchPage* stopwatchPage{nullptr}; + }; + class TimeAnimatorCallback : public AnimatorCallback { + public: + TimeAnimatorCallback() {} + virtual ~TimeAnimatorCallback() override {} + void Callback(UIView* view) override; + }; + Animator* animator_{nullptr}; + StopwatchAnimatorCallback* animatorCallback_{nullptr}; + TimeAnimatorCallback* timeCallback_{nullptr}; + Animator* timeAnimator_{nullptr}; + UISweepClock *sweepClock_{nullptr}; + Image *secondHand_{nullptr}; + UILabel *currentTime_{nullptr}; + UILabel *appName_{nullptr}; + UILabel *elapsedTime_{nullptr}; + UIList *recordsList_{nullptr}; + StopwatchAdapter *listAdapter_{nullptr}; + UILabelButton *startButton_{nullptr}; + UILabelButton *resetButton_{nullptr}; + UIImageView *backGround_{nullptr}; + UIImageView *imgScale_{nullptr}; +}; +} +#endif // STOPWATCH_PAGE_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPresenter.h new file mode 100644 index 000000000..76492cac2 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchPresenter.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchPresenter + * Create: 2025-06-06 + */ + +#ifndef STOPWATCH_PRESENTER_H +#define STOPWATCH_PRESENTER_H + +#include "Presenter.h" + +namespace OHOS { +class StopwatchView; +class StopwatchPresenter : public Presenter {}; +} + +#endif // STOPWATCH_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchView.h new file mode 100644 index 000000000..c35a5709c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/stopwatch/StopwatchView.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchView + * Create: 2025-06-06 + */ + +#ifndef STOPWATCH_VIEW_H +#define STOPWATCH_VIEW_H + +#include "View.h" +namespace OHOS { +enum STOPWATCH_PAGES { + STOPWATCH_MAIN_PAGE = 1, // 0 is invalid +}; + +class StopwatchPresenter; +class StopwatchView : public View {}; +} +#endif // STOPWATCH_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempClickMea.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempClickMea.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempClickMea.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempClickMea.h index 7756ff74e..06485e007 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempClickMea.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempClickMea.h @@ -11,7 +11,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempClickMea : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempContinueWarn.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempContinueWarn.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempContinueWarn.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempContinueWarn.h index c6aca9ea1..0d0ac1a38 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempContinueWarn.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempContinueWarn.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_view_group.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempContinueWarn : public UIViewGroup { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempExitInter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempExitInter.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempExitInter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempExitInter.h index 81df8141b..3b8e93eee 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempExitInter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempExitInter.h @@ -10,8 +10,8 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" -#include "AppGroupView.h" -#include "TempPresenter.h" +#include "main/AppGroupView.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempExitInter : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempExitPrompt.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempExitPrompt.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempExitPrompt.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempExitPrompt.h index 63543772d..f0395f07f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempExitPrompt.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempExitPrompt.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempExitPrompt : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempInitInter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempInitInter.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempInitInter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempInitInter.h index 6de798213..41bb91f1a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempInitInter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempInitInter.h @@ -11,8 +11,8 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AppGroupView.h" -#include "TempPresenter.h" +#include "main/AppGroupView.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempInitInter : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempJoinStudy.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempJoinStudy.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempJoinStudy.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempJoinStudy.h index 6aec60c0b..6d66ddd42 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempJoinStudy.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempJoinStudy.h @@ -11,7 +11,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempJoinStudy : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempLittleTip.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempLittleTip.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempLittleTip.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempLittleTip.h index 49320fcff..344e6331d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempLittleTip.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempLittleTip.h @@ -10,7 +10,7 @@ #include "components/ui_label.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempLittleTip : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMainView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMainView.h similarity index 76% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMainView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMainView.h index 2b3448138..6ae132c00 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMainView.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMainView.h @@ -13,22 +13,22 @@ #include "components/ui_view_group.h" #include "ChangeSliceListener.h" #include "components/ui_swipe_view.h" -#include "TempPresenter.h" -#include "TempJoinStudy.h" -#include "TempMeasure.h" -#include "TempExitInter.h" -#include "TempPromptWear.h" -#include "TempClickMea.h" -#include "TempRemindWear.h" -#include "TempMeaProcess.h" -#include "TempInitInter.h" -#include "TempWarn.h" -#include "TempLittleTip.h" -#include "TempModel.h" -#include "TempStudyAbout.h" -#include "TempExitPrompt.h" -#include "TempContinueWarn.h" -#include "TempReport.h" +#include "temperature/TempPresenter.h" +#include "temperature/TempJoinStudy.h" +#include "temperature/TempMeasure.h" +#include "temperature/TempExitInter.h" +#include "temperature/TempPromptWear.h" +#include "temperature/TempClickMea.h" +#include "temperature/TempRemindWear.h" +#include "temperature/TempMeaProcess.h" +#include "temperature/TempInitInter.h" +#include "temperature/TempWarn.h" +#include "temperature/TempLittleTip.h" +#include "temperature/TempModel.h" +#include "temperature/TempStudyAbout.h" +#include "temperature/TempExitPrompt.h" +#include "temperature/TempContinueWarn.h" +#include "temperature/TempReport.h" namespace OHOS { class TempMainView; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMeaProcess.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMeaProcess.h similarity index 92% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMeaProcess.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMeaProcess.h index ebd0ee48a..3264e72cd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMeaProcess.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMeaProcess.h @@ -12,7 +12,7 @@ #include "components/ui_label.h" #include "components/ui_scroll_view.h" #include "components/ui_circle_progress.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempMeaProcess : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMeasure.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMeasure.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMeasure.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMeasure.h index de6aa31c0..972e64e10 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempMeasure.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempMeasure.h @@ -11,8 +11,8 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_label_button.h" -#include "AppGroupView.h" -#include "TempPresenter.h" +#include "main/AppGroupView.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempMeasure : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempModel.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempModel.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempPresenter.h similarity index 95% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempPresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempPresenter.h index f9b3520e1..2b1321c89 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempPresenter.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempPresenter.h @@ -14,7 +14,7 @@ #include "components/ui_swipe_view.h" #include "wearable_log.h" #include "color.h" -#include "ModelListenerSample.h" +#include "main/ModelListenerSample.h" namespace OHOS { constexpr char* TEMP_JOIN_STUDY = (char*)"tempjoinstudy"; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempPromptWear.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempPromptWear.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempPromptWear.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempPromptWear.h index 5f590e00f..2b3793cfa 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempPromptWear.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempPromptWear.h @@ -12,7 +12,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempPromptWear : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempRemindWear.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempRemindWear.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempRemindWear.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempRemindWear.h index 24f10ed90..9375bf154 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempRemindWear.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempRemindWear.h @@ -11,7 +11,7 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempRemindWear : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempReport.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempReport.h similarity index 87% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempReport.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempReport.h index 3faadd519..649afb5cf 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempReport.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempReport.h @@ -10,8 +10,8 @@ #include "components/ui_image_view.h" #include "components/ui_label.h" -#include "AppGroupView.h" -#include "TempPresenter.h" +#include "main/AppGroupView.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempReport : public AppGroupView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempStudyAbout.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempStudyAbout.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempStudyAbout.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempStudyAbout.h index 3d0deee4a..754c3912d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempStudyAbout.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempStudyAbout.h @@ -10,7 +10,7 @@ #include "components/ui_label.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempStudyAbout : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempWarn.h b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempWarn.h similarity index 90% rename from code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempWarn.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempWarn.h index 821b4a4bb..1fbc6ebf3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/include/TempWarn.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/temperature/TempWarn.h @@ -12,7 +12,7 @@ #include "components/ui_label.h" #include "components/ui_label_button.h" #include "components/ui_scroll_view.h" -#include "TempPresenter.h" +#include "temperature/TempPresenter.h" namespace OHOS { class TempWarn : public UIScrollView { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerMainPage.h new file mode 100644 index 000000000..417b92b68 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerMainPage.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerMainPage + * Create: 2025-06-09 + */ + +#ifndef TIMER_MAIN_PAGE_H +#define TIMER_MAIN_PAGE_H + +#include +#include "View.h" +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "UiConfig.h" +#include "ChangeSliceListener.h" +#include "components/ui_image_view.h" +#include "timers/TimerPresenter.h" +#include "timers/TimerModel.h" +#include "SlicePage.h" +#include "common/image_cache_manager.h" +#include "ui_resource_timer.h" + +namespace OHOS { + class TimerMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { + public: + TimerMainPage() = default; + ~TimerMainPage() override; + + void OnStart(void *data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + void LabelTitle(); + void CreateButton(); + void InitView(); + + private: + UIScrollView *group{nullptr}; + UIImageView *selectMin[4]{nullptr}; // 分钟计时 + UIImageView *addButton{nullptr}; // 自定义按钮 + UILabel *title{nullptr}; // 计时器 + UIImageView *backround{nullptr}; + }; +} +#endif // TIMER_MAIN_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerModel.h new file mode 100644 index 000000000..fee8cd676 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerModel.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerModel + * Create: 2025-06-09 + */ + +#ifndef TIMER_MODEL_H +#define TIMER_MODEL_H + +#include +#include +#include +#include +#include "AppViewIDs.h" +#include "UiConfig.h" +#include "timers/TimerPresenter.h" +#include "graphic_timer.h" +#include "ohos_timer.h" + +namespace OHOS { + class TimerModel { + public: + static TimerModel &GetInstance(void); + + void SetDurationTime(uint32_t time); // 设置计时器的总时间 + uint32_t GetDurationTime(); // 获取计时器的总时间 + bool GetIsTiming() { return isTiming; } + void SetIsTiming(bool value) { isTiming = value; } + bool GetIsPause() { return isPause; } + void SetIsPause(bool value) { isPause = value; } + uint32_t GetStartTime() { return start_time; }; + void SetStartTime(uint32_t value) { start_time = value; }; + uint32_t GetSaveTime(); + void SetSaveTime(bool falg, uint32_t value); + + void InitTimer(); + void DisableTimer(); + bool GetExistTimer() { return haveTimer; }; + void SetExistTimer(bool value) { haveTimer = value; }; + + private: + TimerModel(); + virtual ~TimerModel(); + TimerModel(const TimerModel &) = delete; + TimerModel &operator=(const TimerModel &) = delete; + uint32_t start_time; + uint32_t save_time; + uint32_t durationTime = 0; + GraphicTimer *g_startCounting = nullptr; // 定时器 + bool haveTimer = false; + bool isTiming = false; + bool isPause = false; + }; +} + +#endif // TIMER_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerPresenter.h new file mode 100644 index 000000000..e2d42aef7 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerPresenter.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerPresenter + * Create: 2025-06-09 + */ + +#ifndef TIMER_PRESENTER_H +#define TIMER_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" + +namespace OHOS { + +#define SETTING_TIMER "setting_timer" +#define STOPWATCH_RESET "stopwatch_reset" +#define ONE_MIN "onemine" +#define THREE_MIN "threemine" +#define FIFTY_MIN "fiftymine" +#define THIRTY_MIN "thirtymine" +#define BACK_TIMER "backtimer" +#define RESET "reset" +#define START_PAUSE "start_pause" +#define START_TIMING "start_timing" + + class TimerView; + class TimerPresenter : public Presenter { + }; +} + +#endif // TIMER_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerSettingPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerSettingPage.h new file mode 100644 index 000000000..1ede0c7ea --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerSettingPage.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerSettingPage + * Create: 2025-06-09 + */ + +#ifndef TIMER_SETTING_PAGE_H +#define TIMER_SETTING_PAGE_H + +#include "View.h" +#include "components/ui_button.h" +#include "components/ui_label.h" +#include "components/ui_time_picker.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "UiConfig.h" +#include "timers/TimerPresenter.h" +#include "timers/TimerModel.h" +#include "SlicePage.h" +#include "ChangeSliceListener.h" +#include "ui_resource_timer.h" + +namespace OHOS { + class TimerSettingPage : public UIPicker::SelectedListener, + public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { + public: + TimerSettingPage() = default; + ~TimerSettingPage() override; + + void OnStart(void *data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + + void CreateLabel(void); + void CreateStartButton(void); + void CreatePicker(); + UIScrollView *InitTimerSetView(); + void OnPickerStoped(UIPicker& picker) override; + + private: + UIScrollView *group{nullptr}; + UIButton *back{nullptr}; + UILabel *title{nullptr}; + UIImageView *start{nullptr}; + + UILabel *timerLabel{nullptr}; + UIPicker *timerPicker[3]{nullptr}; + ImageInfo *image1 = nullptr; + ImageInfo *image2 = nullptr; + }; +} +#endif // TIMER_SETTING_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerTimingPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerTimingPage.h new file mode 100644 index 000000000..a64450a42 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerTimingPage.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerTimingPage + * Create: 2025-06-09 + */ + +#ifndef TIMER_TIMING_PAGE_H +#define TIMER_TIMING_PAGE_H + +#include +#include "View.h" +#include "components/ui_button.h" +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "components/ui_digital_clock.h" +#include "components/ui_image_view.h" +#include "components/ui_circle_progress.h" +#include "UiConfig.h" +#include "timers/TimerModel.h" +#include "timers/TimerPresenter.h" +#include "SlicePage.h" +#include "ChangeSliceListener.h" +#include "components/ui_sweep_clock.h" +#include "ui_resource_timer.h" + +namespace OHOS { + class TimerTimingPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { + public: + TimerTimingPage() = default; + ~TimerTimingPage() override; + void OnStart(void *data) override; + void OnResume() override; + void OnPause() override; + + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + void CreateButton(); + void CreateTimerTime(); + void CircleProgress(); + void SetTimerTime(uint32_t durationTime); + void SetupAnimator(); + void SetAnimatorStatus(bool status); + + private: + class TimeAnimatorCallback : public AnimatorCallback { + public: + TimeAnimatorCallback() {} + virtual ~TimeAnimatorCallback() override {} + void Callback(UIView *view) override; + }; + + class TimerTimingCallback : public AnimatorCallback { + public: + explicit TimerTimingCallback(TimerTimingPage *page) : page_(page) {} + ~TimerTimingCallback() override {} + void Callback(UIView *view) override; + + private: + TimerTimingPage *page_{nullptr}; + }; + + UIScrollView *group{nullptr}; + UISweepClock *sweepClock_{nullptr}; + UIDigitalClock *dClock{nullptr}; + UILabel *title{nullptr}; + UIDigitalClock *timerTime{nullptr}; + UIImageView *reset{nullptr}; + UIImageView *start{nullptr}; + UICircleProgress *circleProgress{nullptr}; + UILabel *currentTime_{nullptr}; + TimeAnimatorCallback *timeCallback_{nullptr}; + Animator *timeAnimator_{nullptr}; + TimerTimingCallback *callBack_ = nullptr; + Animator *animator_ = nullptr; + Image *secondHand_{nullptr}; + UIImageView *backround{nullptr}; + }; +} +#endif // TIMER_TIMING_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerView.h new file mode 100644 index 000000000..2849c441e --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/timers/TimerView.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerView + * Create: 2025-06-09 + */ + +#ifndef TIMER_VIEW_H +#define TIMER_VIEW_H + +#include "View.h" + +namespace OHOS { + enum TIMER_PAGES { + TIMER_MAIN_PAGE = 1, // 主页面 + TIMER_SETTING_PAGE, // 自定义页面 + TIMER_TIMING_PAGE, // 显示计时页面 + TIMER_ALL_VIEW, + }; + + class TimerPresenter; + class TimerView : public View { + }; +} +#endif // TIMER_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/DataView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/DataView.h new file mode 100644 index 000000000..d22cc5576 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/DataView.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Data View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_DATA_VIEW_H +#define TRAINING_DATA_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_canvas.h" +#include "components/ui_image_view.h" +#include "components/ui_view_group.h" + +namespace OHOS { +class DataView { +public: + DataView(); + ~DataView(); + static DataView *GetInstance(); + UIViewGroup *InitShowUpView(void); + void UpdateDataViewByType(); + +private: + void ShowupBackgroup(); + void ShowupTopView(); + void ShowupLeftView(); + void ShowupRightView(); + void ShowupBottomView(); + void ShowupSepLine(); + UIImageView *backGround{nullptr}; + UIImageView *heartrate{nullptr}; + UICanvas *sepLine{nullptr}; + UILabel *topValueLabel{nullptr}; + UILabel *topUnitLabel{nullptr}; + UILabel *leftValueLabel{nullptr}; + UILabel *leftUnitLabel{nullptr}; + UILabel *rightValueLabel{nullptr}; + UILabel *rightUnitLabel{nullptr}; + UILabel *bottomValueLabel{nullptr}; + UILabel *bottomUnitLabel{nullptr}; + UIViewGroup *group{nullptr}; +}; +} // namespace OHOS +#endif // TRAINING_DATA_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/MenuView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/MenuView.h new file mode 100644 index 000000000..02bd72eb0 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/MenuView.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Menu View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_MENU_VIEW_H +#define TRAINING_MENU_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_view_group.h" +#include "training/TrainingItemView.h" +#include "training/TrainingAdapter.h" +#include "UiConfig.h" +namespace OHOS { +enum TrainingTypes : uint8_t { + TRAINING_TYPE_OUTDOOR_RUNNING = 0, + TRAINING_TYPE_INDOOR_RUNNING, + TRAINING_TYPE_CYCLING, + TRAINING_TYPE_CLIMBING, + TRAINING_TYPE_INDOOR_SWIMMING, + TRAINING_TYPE_OUTDOOR_SWIMMING, + TRAINING_TYPE_MAX, +}; + +#define TRAINING_ITEM_OUTDOOR_RUNNING "trainingItemOutdoorRunning" +#define TRAINING_ITEM_INDOOR_RUNNING "trainingItemIndoorRunning" +#define TRAINING_ITEM_CYCLING "trainingItemCycling" +#define TRAINING_ITEM_CLIMBING "trainingItemClimbing" +#define TRAINING_ITEM_INDOOR_SWIMMING "trainingItemIndoorSwimming" +#define TRAINING_ITEM_OUTDOOR_SWIMMING "trainingItemOutdoorSwimming" + +class MenuView { +public: + MenuView(); + ~MenuView(); + static MenuView *GetInstance(); + UIViewGroup *InitShowUpView(void); + +private: + void CreateUILabel(void); + void CreateUIList(void); + UILabel *titleLabel{nullptr}; + UIList *trainingList{nullptr}; + TrainingAdapter *listAdapter_{nullptr}; + UIViewGroup *group{nullptr}; + TrainingItem trainings[TRAINING_TYPE_MAX] = { + {TRAINING_TYPE_OUTDOOR_RUNNING, PNG_APPLIST_WALK_IMAGE, "户外跑步", TRAINING_ITEM_OUTDOOR_RUNNING}, + {TRAINING_TYPE_INDOOR_RUNNING, PNG_APPLIST_WALK_IMAGE, "室内跑步", TRAINING_ITEM_INDOOR_RUNNING}, + {TRAINING_TYPE_CYCLING, PNG_APPLIST_WALK_IMAGE, "骑行", TRAINING_ITEM_CYCLING}, + {TRAINING_TYPE_CLIMBING, PNG_APPLIST_WALK_IMAGE, "登山", TRAINING_ITEM_CLIMBING}, + {TRAINING_TYPE_INDOOR_SWIMMING, PNG_APPLIST_WALK_IMAGE, "室内游泳", TRAINING_ITEM_INDOOR_SWIMMING}, + {TRAINING_TYPE_OUTDOOR_SWIMMING, PNG_APPLIST_WALK_IMAGE, "户外游泳", TRAINING_ITEM_OUTDOOR_SWIMMING}}; +}; +} // namespace OHOS +#endif // TRAINING_MENU_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/PauseView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/PauseView.h new file mode 100644 index 000000000..cde8714b7 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/PauseView.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Pause View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_PAUSE_VIEW_H +#define TRAINING_PAUSE_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" + +namespace OHOS { +#define TRAINING_PAUSE_CONTINUE_BUTTON "trainingPauseContinueButton" +#define TRAINING_PAUSE_FINISH_BUTTON "trainingPauseFinishButton" + +class PauseView { +public: + PauseView(); + ~PauseView(); + static PauseView *GetInstance(); + UIViewGroup *InitShowUpView(void); + +private: + void CreateUILabel(void); + void CreateUIButton(void); + UILabel *timeLabel{nullptr}; + UILabel *textLabel{nullptr}; + UILabelButton *continueButton{nullptr}; + UILabelButton *finishButton{nullptr}; + UIViewGroup *group{nullptr}; +}; +} // namespace OHOS +#endif // TRAINING_PAUSE_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/PrepareView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/PrepareView.h new file mode 100644 index 000000000..1805406ac --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/PrepareView.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Prepare View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_PREPARE_VIEW_H +#define TRAINING_PREPARE_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_image_view.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" + +namespace OHOS { +#define TRAINING_PREPARE_START_BUTTON "trainingPrepareStartButton" +class PrepareView { +public: + PrepareView(); + ~PrepareView(); + static PrepareView *GetInstance(); + UIViewGroup *InitShowUpView(void); + void UpdateViewByTrainingType(uint8_t trainingType); + +private: + bool InitBatteryView(); + bool InitHeartbeatView(); + bool InitTimeLableVIew(); + bool InitLocatingLableVIew(); + bool InitCenterView(); + bool InitGPSView(); + bool InitHeartrateView(); + bool InitStartButtonView(); + UILabel *timeLabel{nullptr}; + UIImageView *battery{nullptr}; + UILabel *batteryLabel{nullptr}; + UIImageView *gpsImageView{nullptr}; + UILabel *gpsLabel{nullptr}; + UIImageView *heartRateImageView{nullptr}; + UILabel *heartRateLabel{nullptr}; + UILabel *locatingLabel{nullptr}; + UILabelButton *startButton{nullptr}; + UIButton *iconImageView{nullptr}; + UIViewGroup *group{nullptr}; +}; +} // namespace OHOS +#endif // TRAINING_PREPARE_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/PromptView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/PromptView.h new file mode 100644 index 000000000..7a1d38f0f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/PromptView.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Prompt View + * Create: 2025-03-22 + */ + +#ifndef PROMPT_VIEW_H +#define PROMPT_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_button.h" +#include "components/ui_view_group.h" + +namespace OHOS { +#define TRAINING_PROMPT_CANCEL_BUTTON "trainingPromptCancelButton" +#define TRAINING_PROMPT_CONFIRM_BUTTON "trainingPromptConfirmButton" + +class PromptView { +public: + PromptView(); + ~PromptView(); + static PromptView *GetInstance(); + UIViewGroup *InitShowUpView(void); + +private: + void CreateUILabel(void); + void CreateUIButton(void); + UILabel *titleLabel{nullptr}; + UIButton *cancelButton{nullptr}; + UIButton *confirmButton{nullptr}; + UIViewGroup *group{nullptr}; +}; +} // namespace OHOS +#endif // PROMPT_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetAdapter.h new file mode 100644 index 000000000..74045cd7f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetAdapter.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetAdapter.h + * Author: + * Create: 2025-11-23 + */ + +#ifndef TARGET_ADAPTER_H +#define TARGET_ADAPTER_H + +#include +#include "training/TargetItemView.h" +#include "components/abstract_adapter.h" + +namespace OHOS { + +class TargetAdapter : public AbstractAdapter { +public: + explicit TargetAdapter(); + ~TargetAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a SettingItem linked list. + * + * @param data Indicates the SettingItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(const std::list &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const TargetItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + std::list listData_; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif // TARGET_ADAPTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetItemView.h new file mode 100644 index 000000000..13c211fbe --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetItemView.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetItemView + * Author: + * Create: 2025-02-15 + */ + +#ifndef TARGET_ITEM_H +#define TARGET_ITEM_H + +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" + +namespace OHOS { +typedef struct { + uint8_t type; + const char *icon; + const char *label; + const char *viewId; +} TargetItem; + +class TargetItemView : public UIViewGroup { +public: + TargetItemView(); + ~TargetItemView() override; + + virtual void SetItemInfo(const TargetItem itemInfo); + +private: + bool InitView(); + UIImageView sIcon; + UILabel sLabel; + UIImageView sNextImage; + TargetItem sItemInfo = {0, nullptr, nullptr, nullptr}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetSettingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetSettingView.h new file mode 100644 index 000000000..69ed6f1e4 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetSettingView.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetSetting View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_TARGET_SETTING_VIEW_H +#define TRAINING_TARGET_SETTING_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_view_group.h" +#include "components/ui_picker.h" + +namespace OHOS { +#define TARGET_SETTING_CONFIRM_BUTTON "targetSettingConfirmButton" + +class TargetSettingView { +public: + TargetSettingView(); + ~TargetSettingView(); + static TargetSettingView *GetInstance(); + UIViewGroup *InitShowUpView(void); + void UpdateViewByTargetType(uint8_t targetType); + +private: + void CreateUILabel(void); + void CreateUIPicker(void); + void CreateUIButton(void); + UILabel *titleLabel{nullptr}; + UIPicker *picker{nullptr}; + UILabelButton *confirmButton{nullptr}; + UIViewGroup *group{nullptr}; +}; +} // namespace OHOS +#endif // TRAINING_TARGET_SETTING_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetView.h new file mode 100644 index 000000000..14e71ed63 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TargetView.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Target View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_TARGET_VIEW_H +#define TRAINING_TARGET_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_view_group.h" +#include "training/TargetItemView.h" +#include "training/TargetAdapter.h" +#include "UiConfig.h" +namespace OHOS { +enum TrainingTargets : uint8_t { + TRAINING_TARGET_DISTANCE = 0, + TRAINING_TARGET_TIME, + TRAINING_TARGET_CALORIE, + TRAINING_TARGET_MAX, +}; + +#define TRAINING_TARGET_ITEM_DISTANCE "trainingTargetItemDistance" +#define TRAINING_TARGET_ITEM_TIME "trainingTargetItemTime" +#define TRAINING_TARGET_ITEM_CALORIE "trainingTargetItemCalorie" + +class TargetView { +public: + TargetView(); + ~TargetView(); + static TargetView *GetInstance(); + UIViewGroup *InitShowUpView(void); + +private: + void CreateUILabel(void); + void CreateUIList(void); + UILabel *titleLabel{nullptr}; + UIList *targetList{nullptr}; + TargetAdapter *listAdapter_{nullptr}; + UIViewGroup *group{nullptr}; + TargetItem targets[TRAINING_TARGET_MAX] = { + {TRAINING_TARGET_DISTANCE, PNG_PHONE_IMAGE, "距离", TRAINING_TARGET_ITEM_DISTANCE}, + {TRAINING_TARGET_TIME, PNG_WATCH_IMAGE, "时间", TRAINING_TARGET_ITEM_TIME}, + {TRAINING_TARGET_CALORIE, PNG_BLUETOOTH_IMAGE, "热量", TRAINING_TARGET_ITEM_CALORIE}}; +}; +} // namespace OHOS +#endif // TRAINING_TARGET_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingAdapter.h new file mode 100644 index 000000000..19b747c49 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingAdapter.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingAdapter.h + * Author: + * Create: 2025-11-23 + */ + +#ifndef TRAINING_ADAPTER_H +#define TRAINING_ADAPTER_H + +#include +#include "training/TrainingItemView.h" +#include "components/abstract_adapter.h" + +namespace OHOS { + +class TrainingAdapter : public AbstractAdapter { +public: + explicit TrainingAdapter(); + ~TrainingAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a SettingItem linked list. + * + * @param data Indicates the SettingItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(const std::list &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const TrainingItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + std::list listData_; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif // TRAINING_ADAPTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingItemView.h new file mode 100644 index 000000000..7b863f997 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingItemView.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingItemView + * Author: + * Create: 2025-02-15 + */ + +#ifndef TRAINING_ITEM_H +#define TRAINING_ITEM_H + +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" + +namespace OHOS { +typedef struct { + uint8_t type; + const char *icon; + const char *label; + const char *viewId; +} TrainingItem; + +class TrainingItemView : public UIViewGroup { +public: + TrainingItemView(); + ~TrainingItemView() override; + + virtual void SetItemInfo(const TrainingItem itemInfo); + +private: + bool InitView(); + UIImageView sIcon; + UILabel sLabel; + UIImageView sSettingImage; + TrainingItem sItemInfo = {0, nullptr, nullptr, nullptr}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingModel.h new file mode 100644 index 000000000..32b122ce3 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingModel.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingModel.h + * Author: + * Create: 2025-11-23 + */ + +#ifndef TRAINING_MODEL_H +#define TRAINING_MODEL_H + +#include +namespace OHOS { +class TrainingModel { +public: + static TrainingModel &GetInstance(void); + void SetCurView(int16_t viewNum); + int16_t GetCurView(void); + void SetCurTrainingType(int8_t trainingType); + int8_t GetCurTrainingType(void); + +private: + TrainingModel(); + TrainingModel(const TrainingModel &); + TrainingModel &operator=(const TrainingModel &); + virtual ~TrainingModel(); + int16_t curView_{0}; + uint8_t trainingType_{0}; +}; +} + +#endif // TRAINING_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingPresenter.h new file mode 100644 index 000000000..b23bfcb35 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingPresenter.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingPresenter.h + * Author: + * Create: 2025-11-23 + */ + +#ifndef TRAINING_PRESENTER_H +#define TRAINING_PRESENTER_H + +#include "Presenter.h" +#include "training/TrainingView.h" +#include "training/TrainingModel.h" +#include "components/ui_view.h" + +namespace OHOS { +class TrainingView; +class TrainingPresenter : public Presenter, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + TrainingPresenter(); + ~TrainingPresenter() override; + static TrainingPresenter *GetInstance(); + + void OnResume() override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + void OnPause() override; +private: + void ClickStartButton(void); + void ClickCountineButton(void); + void ClickFinishButton(void); + void ClickCancelButton(void); + void ClickConfirmButton(void); + void TrainingSetting(uint8_t trainingType); + void StartTraining(uint8_t trainingType); + void SettingTarget(uint8_t targetType); + void EnterTarget(void); + void ConfirmTargetSetting(void); + TrainingModel *trainingModel_{nullptr}; +}; +} + +#endif // TRAINING_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingAdapter.h new file mode 100644 index 000000000..b0c1d823f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingAdapter.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingSettingAdapter.h + * Author: + * Create: 2025-11-23 + */ + +#ifndef TRAINING_SETTING_ADAPTER_H +#define TRAINING_SETTING_ADAPTER_H + +#include +#include "training/TrainingSettingItemView.h" +#include "components/abstract_adapter.h" + +namespace OHOS { + +class TrainingSettingAdapter : public AbstractAdapter { +public: + explicit TrainingSettingAdapter(); + ~TrainingSettingAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a SettingItem linked list. + * + * @param data Indicates the SettingItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(const std::list &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const TrainingSettingItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + std::list listData_; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif // TRAINING_SETTING_ADAPTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingItemView.h new file mode 100644 index 000000000..26a644259 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingItemView.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingSettingItemView.h + * Author: + * Create: 2025-11-23 + */ + +#ifndef TRAINING_SETTING_ITEM_H +#define TRAINING_SETTING_ITEM_H + +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" + +namespace OHOS { +typedef struct { + uint8_t type; + const char *icon; + const char *label; + const char *viewId; +} TrainingSettingItem; + +class TrainingSettingItemView : public UIViewGroup { +public: + TrainingSettingItemView(); + ~TrainingSettingItemView() override; + + virtual void SetItemInfo(const TrainingSettingItem itemInfo); + +private: + bool InitView(); + UIImageView sIcon; + UILabel sLabel; + UIImageView sNextImage; + TrainingSettingItem sItemInfo = {0, nullptr, nullptr, nullptr}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingView.h new file mode 100644 index 000000000..deba904f9 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingSettingView.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingSetting View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_SETTING_VIEW_H +#define TRAINING_SETTING_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "components/ui_view_group.h" +#include "training/TrainingSettingItemView.h" +#include "training/TrainingSettingAdapter.h" +#include "UiConfig.h" + +namespace OHOS { +enum TrainingSettings : uint8_t { + TRAINING_SETTING_TARGET = 0, + TRAINING_SETTING_REMIND, + TRAINING_SETTING_MISTOUCH, + TRAINING_SETTING_DATA_DISPLAY, + TRAINING_SETTING_METRONOME, + TRAINING_SETTING_REMOVE, + TRAINING_SETTING_MAX, +}; + +#define TRAINING_SETTING_ITEM_TARGET "trainingSettingItemTarget" +#define TRAINING_SETTING_ITEM_REMIND "trainingSettingItemTargetRemind" +#define TRAINING_SETTING_ITEM_MISTOUCH "trainingSettingItemTargetMistouch" +#define TRAINING_SETTING_ITEM_DATA_DISPLAY "trainingSettingItemTargetDataDisplay" +#define TRAINING_SETTING_ITEM_METRONOME "trainingSettingItemTargetMetronome" +#define TRAINING_SETTING_ITEM_REMOVE "trainingSettingItemTargetRemove" + +class TrainingSettingView { +public: + TrainingSettingView(); + ~TrainingSettingView(); + static TrainingSettingView *GetInstance(); + UIViewGroup *InitShowUpView(void); + +private: + void CreateUILabel(void); + void CreateUIList(void); + UILabel *titleLabel{nullptr}; + UIList *settingList{nullptr}; + TrainingSettingAdapter *listAdapter_{nullptr}; + UIViewGroup *group{nullptr}; + TrainingSettingItem settings[TRAINING_SETTING_MAX] = { + {TRAINING_SETTING_TARGET, PNG_BLUETOOTH_IMAGE, "目标", TRAINING_SETTING_ITEM_TARGET}, + {TRAINING_SETTING_REMIND, PNG_WATCH_IMAGE, "提醒", TRAINING_SETTING_ITEM_REMIND}, + {TRAINING_SETTING_MISTOUCH, PNG_PHONE_IMAGE, "防误触", TRAINING_SETTING_ITEM_MISTOUCH}, + {TRAINING_SETTING_DATA_DISPLAY, PNG_BLUETOOTH_IMAGE, "数据显示", TRAINING_SETTING_ITEM_DATA_DISPLAY}, + {TRAINING_SETTING_METRONOME, PNG_WATCH_IMAGE, "节拍器", TRAINING_SETTING_ITEM_METRONOME}, + {TRAINING_SETTING_REMOVE, PNG_PHONE_IMAGE, "移除此运动", TRAINING_SETTING_ITEM_REMOVE}}; +}; +} // namespace OHOS +#endif // SETTING_SETTING_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingView.h new file mode 100644 index 000000000..8c1bbd9ba --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/training/TrainingView.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingViews View + * Create: 2025-03-22 + */ + +#ifndef TRAINING_VIEW_H +#define TRAINING_VIEW_H + +#include "View.h" +#include "components/ui_view_group.h" +#include "training/MenuView.h" +#include "training/PrepareView.h" +#include "training/DataView.h" +#include "training/PauseView.h" +#include "training/PromptView.h" +#include "training/TrainingSettingView.h" +#include "training/TargetView.h" +#include "training/TargetSettingView.h" + +namespace OHOS { +enum TrainingViews : uint8_t { + TRAINING_VIEW_MENU, + TRAINING_VIEW_PREPARE, + TRAINING_VIEW_DATA, + TRAINING_VIEW_PAUSE, + TRAINING_VIEW_PROMPT, + TRAINING_VIEW_SETTING, + TRAINING_VIEW_TARGET, + TRAINING_VIEW_TARGET_SETTING, + TRAINING_VIEW_MAX, +}; + +constexpr const char *MENU_VIEW_ID = "MenuViewID"; +constexpr const char *PREPARE_VIEW_ID = "PrepareViewID"; +constexpr const char *DATA_VIEW_ID = "DataViewID"; +constexpr const char *PAUSE_VIEW_ID = "PauseViewID"; +constexpr const char *PROMPT_VIEW_ID = "PromptViewID"; +constexpr const char *SETTING_VIEW_ID = "SettingViewID"; +constexpr const char *TARGET_VIEW_ID = "TargetViewID"; +constexpr const char *TARGET_SETTING_VIEW_ID = "TargetSettingViewID"; + +class TrainingPresenter; +class TrainingView : public View { +public: + TrainingView(); + ~TrainingView() override; + static TrainingView *GetInstance(); + + void OnStart() override; + void OnStop() override; + void ChangeView(int16_t hideView, int16_t showView); + +private: + UIViewGroup *container[TRAINING_VIEW_MAX]{nullptr}; + typedef bool (TrainingView::*PreprosssChangeView)(int16_t hideView, int16_t thisView); + PreprosssChangeView preProcessView[TRAINING_VIEW_MAX]; + bool CheckViewParam(int16_t hideView, int16_t showView); + MenuView *menuView{nullptr}; + PrepareView *prepareView{nullptr}; + DataView *dataView{nullptr}; + PauseView *pauseView{nullptr}; + PromptView *promptView{nullptr}; + TrainingSettingView *settingView{nullptr}; + TargetView *targetView{nullptr}; + TargetSettingView *targetSettingView{nullptr}; + bool ChangeMenuView(int16_t hideView, int16_t thisView); + bool ChangePrepareView(int16_t hideView, int16_t thisView); + bool ChangeDataView(int16_t hideView, int16_t thisView); + bool ChangePauseView(int16_t hideView, int16_t thisView); + bool ChangePromptView(int16_t hideView, int16_t thisView); + bool ChangeSettingView(int16_t hideView, int16_t thisView); + bool ChangeTargetView(int16_t hideView, int16_t thisView); + bool ChangeTargetSettingView(int16_t hideView, int16_t thisView); +}; +} +#endif // TRAINING_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISampleModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISampleModel.h similarity index 89% rename from code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISampleModel.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISampleModel.h index 45028caf6..ea285b540 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISampleModel.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISampleModel.h @@ -12,7 +12,7 @@ #include #include "AppViewIDs.h" #include "UiConfig.h" -#include "UISamplePresenter.h" +#include "uisample/UISamplePresenter.h" namespace OHOS { class UISampleModel { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISamplePresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISamplePresenter.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISamplePresenter.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISamplePresenter.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISampleView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISampleView.h similarity index 100% rename from code/sdk/application/wearable/nativeapp/nativeui/uisample/include/UISampleView.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/uisample/UISampleView.h diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_language.h b/code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_language.h new file mode 100644 index 000000000..4595d1013 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_language.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#ifndef UI_MANAGER_H +#define UI_MANAGER_H +#include +#include "main/AppGroupView.h" + +namespace OHOS { +class UILanguage { +public: + static const char* GetText(uint16_t textId); + static void SetLanguage(uint8_t id); + static void UpdateLanguage(); +private: + static bool RegisterGlobalManager(); +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uiservice/include/ui_service.h b/code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_service.h similarity index 97% rename from code/sdk/application/wearable/nativeapp/nativeui/uiservice/include/ui_service.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_service.h index a36e63d60..c4a0410d8 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uiservice/include/ui_service.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/uiservice/ui_service.h @@ -46,7 +46,9 @@ typedef enum { BT_DISCONNECTED_TO_UI, UI_ADD_SLEEP_VETO, UI_RM_SLEEP_VETO, + UI_UPDATE_LANGUAGE, CONNECT_NEW_PHONE, + UI_OTA_UPDATE, } UiServiceMsgId; #define BUNDLE_NAME_LEN 128 diff --git a/code/sdk/application/wearable/nativeapp/nativeui/videocard/include/VideoCard.h b/code/sdk/application/wearable/nativeapp/nativeui/include/videocard/VideoCard.h similarity index 91% rename from code/sdk/application/wearable/nativeapp/nativeui/videocard/include/VideoCard.h rename to code/sdk/application/wearable/nativeapp/nativeui/include/videocard/VideoCard.h index f717fc502..a119391a9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/videocard/include/VideoCard.h +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/videocard/VideoCard.h @@ -6,13 +6,13 @@ #define VIDEO_CARD_H #include -#include "DialDataBase.h" +#include "main/dial/DialDataBase.h" #include "components/ui_view_group.h" -#include "OnDialDataUpdateListener.h" +#include "main/dial/OnDialDataUpdateListener.h" #include "components/ui_card_page.h" #include "components/ui_lite_surface_view.h" #include "video_play_wrapper.h" -#include "DialView.h" +#include "main/dial/DialView.h" namespace OHOS { class VideoCard : public UICardPage { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherAdapter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherAdapter.h new file mode 100644 index 000000000..c94553bfa --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherAdapter.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: weather/WeatherAdapter.h + * Create: 2025-03-23 + */ + +#ifndef WEATHER_ADAPTER_H +#define WEATHER_ADAPTER_H + +#include +#include +#include "components/ui_list.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/abstract_adapter.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "weather/WeatherModel.h" +#include "weather/WeatherItemView.h" + +namespace OHOS { +class WeatherAdapter : public AbstractAdapter { +public: + explicit WeatherAdapter(); + ~WeatherAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a WeatherItem linked list. + * + * @param data Indicates the WeatherItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(std::list &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const WeatherItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + std::list listData; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherItemView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherItemView.h new file mode 100644 index 000000000..13c19fa16 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherItemView.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherItemView + * Create: 2025-03-23 + */ + +#ifndef WEATHER_ITEM_VIEW_H +#define WEATHER_ITEM_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/ui_canvas.h" + +#include "UiConfig.h" +#include "weather/WeatherModel.h" + +namespace OHOS { +class WeatherItemView : public UIViewGroup { +public: + explicit WeatherItemView(); + ~WeatherItemView() override; + virtual void SetItemInfo(const WeatherItem itemInfo); + virtual void SetUpChild(); + +private: + UILabel sLabel_1; + UIImageView sIcon; + UILabel sLabel_2; + UICanvas chartLine; + UIImageView sNextImage; + WeatherItem sItemInfo = {nullptr, nullptr, nullptr, false}; +}; +} + +#endif diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherMainPage.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherMainPage.h new file mode 100644 index 000000000..31a9ea0a5 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherMainPage.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherMainPage + * Created: 2025-4 + */ + +#ifndef WEATHER_MAIN_PAGE_H +#define WEATHER_MAIN_PAGE_H + +#include +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_list.h" +#include "weather/WeatherAdapter.h" +#include "weather/WeatherPresenter.h" +#include "SlicePage.h" +#include "UiConfig.h" +#include "weather/WeatherView.h" +namespace OHOS { +static constexpr int16_t LABEL_COUNT = 6; +class WeatherPresenter; +class WeatherMainPage : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + WeatherMainPage(); + ~WeatherMainPage() override; + + void OnStart(void* data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + std::string FormatTime(bool falg, const std::string& inputStr); + void InitLabel(); + void InitImage(); + void InitWeatherImage(); +private: + bool flag = false; + int curWeather_code = 0; + CurWeather cur{nullptr}; + UIViewGroup *group = nullptr; + WeatherModel *weatherModel = nullptr; + UILabel *title[LABEL_COUNT]{nullptr}; + UILabel *labelTitle{nullptr}; + UIImageView *mainImg{nullptr}; + UIImageView *addressImg{nullptr}; + UIImageView *aroundImg = nullptr; + UIImageView *weatherImg{nullptr}; + UIImageView *ImageAir{nullptr}; + UIImageView *ImageHumidity{nullptr}; + UIImageView *ImagePageKey{nullptr}; +}; +} +#endif // SETTING_MAIN_PAGE_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherModel.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherModel.h new file mode 100644 index 000000000..55d135a42 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherModel.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherModel + * Create: 2025-03-23 + */ + +#ifndef WEATHER_MODEL_H +#define WEATHER_MODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "AppViewIDs.h" +#include "UiConfig.h" +#include "cJSON.h" +#include "components/ui_image_view.h" +#include "common/image_cache_manager.h" +#include "main/LoadImg.h" +#include "ui_resource_weather.h" +#ifndef _WIN32 +#include "time64.h" +#endif +namespace OHOS { +static constexpr int16_t MIN_TO_HOUR = 60; +static constexpr int16_t HOURLY_SYSTEM = 24; +static constexpr int16_t WEATHER_COUNT = 24; +static constexpr int16_t WEATHER_HOUR = 12; +static constexpr int16_t SET_ZERO = 0; +static constexpr int16_t SET_ONE = 1; +static constexpr int16_t SET_TWO = 2; +static constexpr int16_t SET_THREE = 3; +static constexpr int16_t SET_FOUR = 4; +static constexpr int16_t SET_FIVE = 5; +static constexpr int16_t SET_SIX = 6; +static constexpr int16_t SET_SEVEN = 7; +static constexpr int16_t SET_EIGHT = 8; +static constexpr int16_t SET_NINE = 9; +static constexpr int16_t SET_TEN = 10; +static constexpr int16_t SET_TWELVE = 12; +static constexpr int16_t SET_FOURTEEN = 14; +static constexpr int16_t SET_HUNDRED = 100; +static constexpr int16_t START_YEAR = 1900; +static constexpr int16_t ARRAY_SIZE = 31; +static const uint16_t WEATHER_ITEM_COUNT = 10; + +const int bigWeatherImage[ARRAY_SIZE] = { + IMAGE_CONVERTER_TOOL_WEATHER00, // 0 + IMAGE_CONVERTER_TOOL_WEATHER01, // 1 + IMAGE_CONVERTER_TOOL_WEATHER02, // 2 + IMAGE_CONVERTER_TOOL_WEATHER03, // 3 + IMAGE_CONVERTER_TOOL_WEATHER04, // 4 + IMAGE_CONVERTER_TOOL_WEATHER05, // 5 + IMAGE_CONVERTER_TOOL_WEATHER06, // 6 + IMAGE_CONVERTER_TOOL_WEATHER07, // 7 + IMAGE_CONVERTER_TOOL_WEATHER08, // 8 + IMAGE_CONVERTER_TOOL_WEATHER09, // 9 + IMAGE_CONVERTER_TOOL_WEATHER10, // 10 + IMAGE_CONVERTER_TOOL_WEATHER11, // 11 + IMAGE_CONVERTER_TOOL_WEATHER12, // 12 + IMAGE_CONVERTER_TOOL_WEATHER13, // 13 + IMAGE_CONVERTER_TOOL_WEATHER14, // 14 + IMAGE_CONVERTER_TOOL_WEATHER15, // 15 + IMAGE_CONVERTER_TOOL_WEATHER16, // 16 + IMAGE_CONVERTER_TOOL_WEATHER17, // 17 + IMAGE_CONVERTER_TOOL_WEATHER18, // 18 + IMAGE_CONVERTER_TOOL_WEATHER19, // 19 + IMAGE_CONVERTER_TOOL_WEATHER20, // 20 + IMAGE_CONVERTER_TOOL_WEATHER21, // 21 + IMAGE_CONVERTER_TOOL_WEATHER22, // 22 + IMAGE_CONVERTER_TOOL_WEATHER23, // 23 + IMAGE_CONVERTER_TOOL_WEATHER24, // 24 + IMAGE_CONVERTER_TOOL_WEATHER25, // 25 + IMAGE_CONVERTER_TOOL_WEATHER26, // 26 + IMAGE_CONVERTER_TOOL_WEATHER27, // 27 + IMAGE_CONVERTER_TOOL_WEATHER28, // 28 + IMAGE_CONVERTER_TOOL_WEATHER29, // 29 + IMAGE_CONVERTER_TOOL_WEATHER31 // 30 +}; + +const int smallWeatherImage[ARRAY_SIZE] = { + IMAGE_CONVERTER_TOOL_WEATHER32, // 32 + IMAGE_CONVERTER_TOOL_WEATHER33, // 33 + IMAGE_CONVERTER_TOOL_WEATHER34, // 34 + IMAGE_CONVERTER_TOOL_WEATHER35, // 35 + IMAGE_CONVERTER_TOOL_WEATHER36, // 36 + IMAGE_CONVERTER_TOOL_WEATHER37, // 37 + IMAGE_CONVERTER_TOOL_WEATHER38, // 38 + IMAGE_CONVERTER_TOOL_WEATHER39, // 39 + IMAGE_CONVERTER_TOOL_WEATHER40, // 40 + IMAGE_CONVERTER_TOOL_WEATHER41, // 41 + IMAGE_CONVERTER_TOOL_WEATHER42, // 42 + IMAGE_CONVERTER_TOOL_WEATHER43, // 43 + IMAGE_CONVERTER_TOOL_WEATHER44, // 44 + IMAGE_CONVERTER_TOOL_WEATHER45, // 45 + IMAGE_CONVERTER_TOOL_WEATHER46, // 46 + IMAGE_CONVERTER_TOOL_WEATHER47, // 47 + IMAGE_CONVERTER_TOOL_WEATHER48, // 48 + IMAGE_CONVERTER_TOOL_WEATHER49, // 49 + IMAGE_CONVERTER_TOOL_WEATHER50, // 50 + IMAGE_CONVERTER_TOOL_WEATHER51, // 51 + IMAGE_CONVERTER_TOOL_WEATHER52, // 52 + IMAGE_CONVERTER_TOOL_WEATHER53, // 53 + IMAGE_CONVERTER_TOOL_WEATHER54, // 54 + IMAGE_CONVERTER_TOOL_WEATHER55, // 55 + IMAGE_CONVERTER_TOOL_WEATHER56, // 56 + IMAGE_CONVERTER_TOOL_WEATHER57, // 57 + IMAGE_CONVERTER_TOOL_WEATHER58, // 58 + IMAGE_CONVERTER_TOOL_WEATHER59, // 59 + IMAGE_CONVERTER_TOOL_WEATHER60, // 60 + IMAGE_CONVERTER_TOOL_WEATHER61, // 61 + IMAGE_CONVERTER_TOOL_WEATHER62 // 62 +}; + +typedef struct { + const char *label_1; + const ImageInfo *icon; + const char *label_2; + bool hasSecondMenu; +} WeatherItem; + +typedef struct { + const char *min_degree; + const char *max_degree; + const char *address; + const char *weather_code; + const char *degree; + const char *updateTime; + const char *humidity; + std::string sunSet; + std::string sunRise; +} CurWeather; + +typedef struct { + const char *hour; + const char *degree; + const char *weather; +} HourWeather; +class WeatherModel { +public: + static WeatherModel &GetInstance(void); + bool InitWeatherItem(); + WeatherItem *GetWeatherlistItems(); + uint8_t GetWeatherListNum(); + CurWeather GetCurWeather(); + std::vector GetHourWeather(); + void InitFirstPageData(); + void InitSecondPageData(); + void InitThirdPageData(); + void UpdateTemp(); + bool InitVecForecast(cJSON *root); + bool InitVecObserve(cJSON *root); + bool InitVecRise(cJSON *root); + bool InitVecWeek(cJSON *root); + bool InitVecAddress(cJSON *root); + virtual ~WeatherModel(); + void SetDayStatus(const std::string &timeRise, const std::string &timeSet); + bool GetDayStatus(); + +private: + WeatherModel(); + WeatherModel(const WeatherModel &); + WeatherModel &operator=(const WeatherModel &); + int usedLen{0}; + int tempMinArray[WEATHER_ITEM_COUNT] = {0}; + int tempMaxArray[WEATHER_ITEM_COUNT] = {0}; + bool isDay; + CurWeather curWeather{nullptr}; + std::vector houWeather; + WeatherItem weather[WEATHER_ITEM_COUNT] = {nullptr, nullptr, nullptr, false}; + std::vector> vec_forecast_1h; + std::vector> vec_forecast_24h; + std::vector> vec_rise; + std::map map_observe; + std::map map_address; +}; +} + +#endif // Weather_MODEL_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageSecond.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageSecond.h new file mode 100644 index 000000000..85638351d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageSecond.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherPageSecond + * Create: 2025-03-15 + */ + +#ifndef WEATHER_PAGESECOND_H +#define WEATHER_PAGESECOND_H + +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_swipe_view.h" +#include "ui_swipe_view.h" +#include "weather/WeatherPresenter.h" +#include "weather/WeatherView.h" +#include "SlicePage.h" +#include "UiConfig.h" +namespace OHOS { +class WeatherPresenter; +class WeatherPageSecond : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener, + public UISwipeView::OnSwipeListener { +public: + WeatherPageSecond(); + ~WeatherPageSecond() override; + void OnStart(void* data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + void OnSwipe(UISwipeView &view) override; + void WeatherInit(UIViewGroup *group); + void InitLabel(UIViewGroup *group, int count); + void InitImage(UIViewGroup *group, int count); + bool SetSwipeInter(); + void InitVecWeather(); +private: + WeatherModel *weatherModel = nullptr; + std::vector houWeather; + UISwipeView *weatherSwipeGroup = nullptr; + UIViewGroup *swipeGroup[SET_THREE]{nullptr}; + UIImageView *imgBack[SET_EIGHT]{nullptr}; + UILabel *labelTime[SET_EIGHT]{nullptr}; + UILabel *labelTemp[SET_EIGHT]{nullptr}; + UIImageView *imgWeather[SET_EIGHT]{nullptr}; + UIImageView *mainImg{nullptr}; + UIImageView *ImagePageKey{nullptr}; + int index = 0; // 记录当前是第几个swipe +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageThird.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageThird.h new file mode 100644 index 000000000..a7f72f9e7 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPageThird.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherPageThird + * Create: 2025-03-15 + */ + +#ifndef WEATHER_PAGETHIRD_H +#define WEATHER_PAGETHIRD_H + +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "components/ui_swipe_view.h" +#include "main/AppGroupView.h" +#include "weather/WeatherPresenter.h" +#include "weather/WeatherAdapter.h" +#include "SlicePage.h" +#include "UiConfig.h" +namespace OHOS { +class WeatherPageThird : public SlicePage, + public UIView::OnClickListener, + public UIView::OnDragListener, + public UISwipeView::OnSwipeListener { +public: + WeatherPageThird(); + ~WeatherPageThird() override; + void OnStart(void* data) override; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + void OnSwipe(UISwipeView &view) override; + void InitScrollView(); + bool InitScrollData(); + void RefreshWeathersList(const WeatherItem *item, uint8_t count); +private: + WeatherModel *weatherModel = nullptr; + UIViewGroup *group = nullptr; + UIList *contentList{nullptr}; + UILabel *title{nullptr}; + WeatherAdapter *listAdapter{nullptr}; + UIImageView *mainImg{nullptr}; + UIImageView *ImagePageKey{nullptr}; +}; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPresenter.h new file mode 100644 index 000000000..6cb6bf1ad --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherPresenter.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherPresenter + * Create: 2025-11-23 + */ + +#ifndef WEATHER_PRESENTER_H +#define WEATHER_PRESENTER_H + +#include "Presenter.h" +#include "components/ui_view.h" +#include "weather/WeatherModel.h" +namespace OHOS { +class WeatherView; +class WeatherPresenter : public Presenter {}; +} + +#endif // Weather_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherView.h b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherView.h new file mode 100644 index 000000000..4c2e46906 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/include/weather/WeatherView.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherView + * Create: 2025-11-23 + */ + +#ifndef WEATHER_VIEW_H +#define WEATHER_VIEW_H + +#include "View.h" +namespace OHOS { +enum WEATHER_PAGES { + WEATHER_MAIN_PAGE = 1, // 0 is invalid + WEATHER_SECOND_PAGE = 2, + WEATHER_THIRD_PAGE = 3, +}; + +class WeatherPresenter; +class WeatherView : public View {}; +} +#endif // Weather_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/CustomizationView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/CustomizationView.cpp index 4e3e637ea..0546bb8c0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/CustomizationView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/CustomizationView.cpp @@ -4,8 +4,8 @@ * Create: 2022-03-02 */ -#include "CustomizationView.h" -#include "IndoorWalkPresenter.h" +#include "indoorwalk/CustomizationView.h" +#include "indoorwalk/IndoorWalkPresenter.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkEndView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkEndView.cpp index bcaa1e761..cbb22c343 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkEndView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkEndView.cpp @@ -4,8 +4,8 @@ * Create: 2022-03-02 */ -#include "IndoorWalkEndView.h" -#include "IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkEndView.h" +#include "indoorwalk/IndoorWalkPresenter.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkModel.cpp index 4afd157fd..42786d830 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkModel.cpp @@ -4,8 +4,8 @@ * Create: 2022-03-02 */ -#include "IndoorWalkModel.h" -#include "IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkModel.h" +#include "indoorwalk/IndoorWalkPresenter.h" #include "ohos_timer.h" #include "graphic_timer.h" @@ -293,7 +293,7 @@ void InitIndoorWalkTimer() WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "IndoorWalkModel::IndoorWalkTimer already exists!!"); return; } - uint32 tick = GetOSTick(MS_ONE_SECONDS); + uint32_t tick = GetOSTick(MS_ONE_SECONDS); g_startCounting = new GraphicTimer(tick, IndoorWalkTimerCallback, nullptr, true); if (g_startCounting == nullptr) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "IndoorWalkModel::IndoorWalkTimer new GraphicTimer failed!!"); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkMotionView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkMotionView.cpp index a3350f28e..4e88d67e0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkMotionView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkMotionView.cpp @@ -4,13 +4,13 @@ * Create: 2022-03-02 */ -#include "IndoorWalkMotionView.h" -#include "IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkMotionView.h" +#include "indoorwalk/IndoorWalkPresenter.h" #include "wearable_log.h" #include "UiConfig.h" -#include "ScreenModels.h" -#include "ActivityModel.h" -#include "IndoorWalkModel.h" +#include "screensetting/ScreenModels.h" +#include "activity/ActivityModel.h" +#include "indoorwalk/IndoorWalkModel.h" #include namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPreparedView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPreparedView.cpp index 6f3efcd2b..709ab2845 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPreparedView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPreparedView.cpp @@ -4,9 +4,9 @@ * Create: 2022-03-02 */ -#include "IndoorWalkPreparedView.h" -#include "IndoorWalkPresenter.h" -#include "ScreenModels.h" +#include "indoorwalk/IndoorWalkPreparedView.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "screensetting/ScreenModels.h" #include "ui_resource_image.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPresenter.cpp index 9ea8f6055..fcffcc433 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkPresenter.cpp @@ -4,14 +4,14 @@ * Create: 2022-03-02 */ -#include "IndoorWalkPresenter.h" -#include "IndoorWalkView.h" -#include "IndoorWalkModel.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkView.h" +#include "indoorwalk/IndoorWalkModel.h" #include "drag_event.h" #include "UiConfig.h" #include "wearable_log.h" #include -#include "ActivityModel.h" +#include "activity/ActivityModel.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkView.cpp index 0308e9864..4cbdb8eb5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/IndoorWalkView.cpp @@ -4,8 +4,8 @@ * Create: 2022-03-02 */ -#include "IndoorWalkView.h" -#include "IndoorWalkModel.h" +#include "indoorwalk/IndoorWalkView.h" +#include "indoorwalk/IndoorWalkModel.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFifth.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFifth.cpp index a3da2bbde..7c41f0fa2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFifth.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFifth.cpp @@ -3,7 +3,7 @@ * Description: Motion PageFifth View * Create: 2022-03-02 */ -#include "MotionPageFifth.h" +#include "indoorwalk/MotionPageFifth.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFirst.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFirst.cpp index c16b941d5..0975cbedb 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFirst.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFirst.cpp @@ -4,9 +4,9 @@ * Create: 2022-03-02 */ -#include "MotionPageFirst.h" -#include "IndoorWalkPresenter.h" -#include "IndoorWalkModel.h" +#include "indoorwalk/MotionPageFirst.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkModel.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFourth.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFourth.cpp index a43ab8ff6..8ea8febb0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFourth.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageFourth.cpp @@ -3,9 +3,9 @@ * Description: Motion PageFourth View * Create: 2022-03-02 */ -#include "MotionPageFourth.h" -#include "IndoorWalkPresenter.h" -#include "IndoorWalkModel.h" +#include "indoorwalk/MotionPageFourth.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkModel.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageSecond.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageSecond.cpp index 34e136df5..33fc94f8c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageSecond.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageSecond.cpp @@ -3,9 +3,9 @@ * Description: Motion PageSecond View * Create: 2022-03-02 */ -#include "MotionPageSecond.h" -#include "IndoorWalkPresenter.h" -#include "IndoorWalkModel.h" +#include "indoorwalk/MotionPageSecond.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkModel.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageThird.cpp b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageThird.cpp index 668d78cd4..d6730e95b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageThird.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/indoorwalk/src/MotionPageThird.cpp @@ -3,9 +3,9 @@ * Description: Motion PageThird View * Create: 2022-03-02 */ -#include "MotionPageThird.h" -#include "IndoorWalkPresenter.h" -#include "IndoorWalkModel.h" +#include "indoorwalk/MotionPageThird.h" +#include "indoorwalk/IndoorWalkPresenter.h" +#include "indoorwalk/IndoorWalkModel.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/key/src/KeyInputListener.cpp b/code/sdk/application/wearable/nativeapp/nativeui/key/src/KeyInputListener.cpp index 871138f01..9f8ecd313 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/key/src/KeyInputListener.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/key/src/KeyInputListener.cpp @@ -5,19 +5,19 @@ * Create: 2021-09-18 */ -#include "KeyInputListener.h" +#include "key/KeyInputListener.h" #include "common/key_code.h" #include "AppViewIDs.h" #include "View.h" -#include "MainViewSample.h" +#include "main/MainViewSample.h" #include "wearable_log.h" #include "UiConfig.h" #include "dock/input_device.h" #include "notification_manager.h" -#include "AlarmPopUpPresenter.h" -#include "CallerLogModel.h" -#include "MainCallingPresenter.h" -#include "ApplistModel.h" +#include "alarm/AlarmPopUpPresenter.h" +#include "callerlog/CallerLogModel.h" +#include "makephone/MainCallingPresenter.h" +#include "applist/ApplistModel.h" namespace OHOS { static bool IsNotifyCallStatus() @@ -137,8 +137,8 @@ void KeyInputListener::OnKeyRelease(const KeyEvent& event) NotificationManager::GetInstance()->GetWatchCallStatus()) { // 音量卡片 // 音量- CallVolumeDipSwitchControl(VOLUMEDOWN); - } else { - // 切换到用户配置的快捷卡片 + } else if (currentViewId != VIEW_RECENT_APP) { + NativeAbility::GetInstance().ChangeSlice(VIEW_RECENT_APP); } } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/HealthModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/HealthModel.cpp index d61182de7..5f0b22d3a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/HealthModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/HealthModel.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "HealthModel.h" +#include "main/HealthModel.h" #include #include #include diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/LoadImg.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/LoadImg.cpp new file mode 100644 index 000000000..5586182b5 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/LoadImg.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: LoadImg + * Author: + * Create: 2025-06-05 + */ + +#include "main/LoadImg.h" + +namespace OHOS { +namespace LOADIMG { + +// 加载图片资源 +void LoadBtnImage(UIButton *btn, std::string file, uint32_t resId1, uint32_t resId2) +{ + ImageInfo *image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId1, file); + if (image1 == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "LoadBtnImage resId1 fail"); + return; + } + ImageInfo *image2 = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId2, file); + if (image2 == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "LoadBtnImage resId2 fail"); + return; + } + btn->SetImageSrc(image1, image2); +} + +void LoadImageViewImg(UIImageView *view, std::string file, uint32_t resId) +{ + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId, file); + if (image == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "LoadImageViewImg %x fail", resId); + return; + } + view->SetSrc(image); + return; +} +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainModel.cpp index dc5b9e350..a84d1d7d5 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainModel.cpp @@ -6,11 +6,11 @@ */ #include "unistd.h" -#include "MainModel.h" +#include "main/MainModel.h" #include "kv_store.h" #include "securec.h" #include "wearable_log.h" -#include "DialBinTypesV2.h" +#include "main/DialBinTypesV2.h" #include "power_display_service.h" namespace OHOS { @@ -198,6 +198,9 @@ namespace OHOS { return; } + if (dialSetting.dialFlag == 0) { + return; + } setValue = strtok_s(nullptr, ",", &setBuffer); if (setValue != nullptr) { dialSetting.dialFullName = setValue; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainPresenterSample.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainPresenterSample.cpp index ca40fa472..434c85e11 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainPresenterSample.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainPresenterSample.cpp @@ -5,15 +5,13 @@ * Create: 2021-10-18 */ -#include "MainPresenterSample.h" +#include "main/MainPresenterSample.h" #include "common/task_manager.h" -#include "HeartRateView.h" -#include "PlayersModel.h" -#include "PlayersPresenter.h" -#include "MainCompassPresenter.h" +#include "heartrate/HeartRateView.h" +#include "player/PlayersModel.h" +#include "player/PlayersPresenter.h" #include "NativeRegisterManager.h" -#include "CompassModel.h" -#include "CompassCalibrationView.h" +#include "compass/CompassModel.h" #include "drag_event.h" #include "graphic_service.h" #include "wearable_log.h" @@ -21,10 +19,10 @@ #include "ui_resource_image.h" #include #include -#include "ModelDialDataFactory.h" -#include "DialModelTime.h" -#include "DialViewGroup.h" -#include "ui_service.h" +#include "main/dial/ModelDialDataFactory.h" +#include "main/dial/DialModelTime.h" +#include "main/dial/DialViewGroup.h" +#include "uiservice/ui_service.h" #include "PageTransitionMgr.h" namespace OHOS { @@ -73,7 +71,6 @@ void MainPresenterSample::OnStart() void MainPresenterSample::OnPause() { - Presenter::OnPause(); // Save watchface content for slide back UIView* watchFace = view_->GetViewById(WATCH_FACE)->GetParent(); uint8_t opaScale = watchFace->GetOpaScale(); @@ -91,7 +88,6 @@ void MainPresenterSample::OnPause() void MainPresenterSample::OnResume(void) { - Presenter::OnResume(); mainPresenterState_ = MainPresenterState::RESUME; // Set current page again to invoke OnActive method. uint8_t curCardId = view_->GetHorCurrentCard(); @@ -263,21 +259,10 @@ void MainPresenterSample::SetCircleProgress() } } -void MainPresenterSample::SetCompassRotate() -{ - bool status = CompassModel::GetInstance()->GetCalibrationStatus(); - dynamic_cast(view_->GetViewById(COMPASS))->SetCalibrationView(status); - if (!status) { - DetermineToRotate(); - } -} - void MainPresenterSample::Notify(void) { CardId cardId = view_->GetHorCurrentCard(); - if (cardId == COMPASS) { - SetCompassRotate(); - } else if (cardId == MUSIC_PLAYER) { + if (cardId == MUSIC_PLAYER) { SetCircleProgress(); } else if (cardId == WATCH_FACE) { DialSetting &setting = GetDialSetting(); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainViewSample.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainViewSample.cpp index b6c882643..0133239e3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainViewSample.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MainViewSample.cpp @@ -5,9 +5,10 @@ * Create: 2021-10-18 */ #include "wearable_log.h" -#include "MainViewSample.h" +#include "main/MainViewSample.h" #include "graphic_service.h" #include "common/image_cache_manager.h" +#include "UICardPageFactory.h" namespace OHOS { static MainViewSample *g_pMainView = nullptr; @@ -271,12 +272,7 @@ UICardPage *MainViewSample::InitWatchOffDial(DialSetting &setting) UICardPage *MainViewSample::InitWatchDial(DialSetting &setting) { - switch (setting.dialId) { - case DIAL_CLOCK: - return new MainClockView(); - default: - return nullptr; - } + return UICardPageFactory::GetInstance().CreateWatchDial(DIAL_DISPLAY_MODE_MAIN, setting.dialId); } UICardPage *MainViewSample::InitWatchFacePage(void) diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageAdapter.cpp new file mode 100644 index 000000000..8d5748cec --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageAdapter.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MessageAdapter.cpp + * Author: + * Create: 2021-11-23 + */ + +#include "main/MessageAdapter.h" + +namespace OHOS { +MessageAdapter::MessageAdapter() {} + +MessageAdapter::~MessageAdapter() +{ + listData.clear(); +} + +uint16_t MessageAdapter::GetCount(void) +{ + return listData.size(); +} + +void MessageAdapter::SetData(std::list &data) +{ + if (!listData.empty()) { + listData.clear(); + } + std::list::iterator it; + for (it = data.begin(); it != data.end(); it++) { + listData.push_back(*it); + } +} + +UIView *MessageAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData.size()) { + return nullptr; + } + + std::list::iterator it = listData.begin(); + for (int i = 0; i < index; i++) { + it++; + } + MessageItem itemData = *it; + MessageItemView *item = nullptr; + if (inView == nullptr) { + item = new MessageItemView(); + } else { + item = static_cast(inView); + } + + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void MessageAdapter::AddListItem(const MessageItem &item) +{ + listData.push_back(item); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "listData == %d-------zsy", listData.size()); + for (const auto& item : listData) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageItem.App == %s-------zsy", item.label_1.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageItem.Content == %s-------zsy", item.label_2.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageItem.Info == %s-------zsy", item.label_3.c_str()); + } +} + +void MessageAdapter::ClearListItem() +{ + listData.clear(); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageItemView.cpp new file mode 100644 index 000000000..db7e81e5d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageItemView.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MessageItemView.cpp + * Author: + * Create: 2021-11-23 + */ + +#include "wearable_log.h" +#include "main/MessageItemView.h" + +namespace OHOS { + static constexpr int16 SETTING_ICON_X = 20; + static constexpr int16 NUM_22 = 22; + static constexpr int16_t SETTING_ITEM_BUTTON_HEIGHT = 80; + static constexpr int16_t SETTING_ITEM_LABEL_WIDTH = 155; + static constexpr int16_t SETTING_ITEM_LABEL_HEIGHT = 100; + static constexpr int16 SETTING_ITEM_FONT_SIZE = 35; + static constexpr int16_t SETTINGS_RESIZE_SIZE = 100; + static constexpr int16_t SETTING_SICON_Y = 15; + static constexpr int16 NUMS_2 = 2; + static constexpr int16 NUMS_50 = 50; + + MessageItemView::MessageItemView() + { + SetPosition(0, 0, HORIZONTAL_RESOLUTION, 200); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + SetTouchable(true); + SetUpChild(); + + Add(&sback); + Add(&sLabel_1); + Add(&sIcon); + Add(&sLabel_2); + Add(&sLabel_3); + } + + MessageItemView::~MessageItemView() + { + Remove(&sIcon); + Remove(&sLabel_1); + Remove(&sLabel_2); + Remove(&sLabel_3); + Remove(&sback); + } + + void MessageItemView::SetItemInfo(const MessageItem itemInfo) + { + sItemInfo = itemInfo; + sLabel_1.SetText(itemInfo.label_1.c_str()); + sIcon.SetSrc(itemInfo.icon.c_str()); + sLabel_2.SetText(itemInfo.label_2.c_str()); + sLabel_3.SetText(itemInfo.label_3.c_str()); + } + + void MessageItemView::SetUpChild() + { + sLabel_1.SetPosition(50, 10); + sLabel_1.Resize(SETTING_ITEM_LABEL_WIDTH, 50); + sLabel_1.SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTING_ITEM_FONT_SIZE); + sLabel_1.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + sLabel_1.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_1.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel_1.SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + sLabel_1.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sIcon.SetPosition(15, SETTING_SICON_Y); + sIcon.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + sLabel_2.SetPosition(15, 78); + sLabel_2.Resize(100, 50); + sLabel_2.SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTING_ITEM_FONT_SIZE); + sLabel_2.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + sLabel_2.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_2.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel_2.SetStyle(STYLE_BACKGROUND_COLOR, Color::Orange().full); + sLabel_2.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sLabel_3.SetPosition(150, 78, 100, 50); + sLabel_3.SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTING_ITEM_FONT_SIZE); + sLabel_3.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + sLabel_3.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_3.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel_3.SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + sLabel_3.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sback.SetPosition(0, 0, 450, 180); + sback.SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + sback.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + } + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageMainView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageMainView.cpp new file mode 100644 index 000000000..ed1000dd2 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageMainView.cpp @@ -0,0 +1,374 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: WeekStep + * Author: + * Create: 2021-09-11 + */ + +#include "main/MessageMainView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "common/screen.h" +#include "main/MainPresenterSample.h" +#include "screensetting/ScreenModels.h" +#include "settings/SettingModel.h" +#include "ui_resource_image.h" + +namespace OHOS { + +static MessageMainView *g_pMessageMainView = nullptr; + +constexpr int16_t DISTURB_IMG_X = 117; +constexpr int16_t DISTURB_IMG_Y = 50; +constexpr int16_t SCREEN_IMG_X = 251; +constexpr int16_t SCREEN_IMG_Y = 50; +constexpr int16_t PHONE_IMG_X = 49; +constexpr int16_t PHONE_IMG_Y = 184; +constexpr int16_t ALARM_IMG_X = 184; +constexpr int16_t ALARM_IMG_Y = 184; +constexpr int16_t SETTING_IMG_X = 319; +constexpr int16_t SETTING_IMG_Y = 184; + +constexpr int16_t BLUETOOTH_IMG_X = 145; +constexpr int16_t BLUETOOTH_IMG_Y = 335; +constexpr int16_t BATTERY_IMG_X = 195; +constexpr int16_t BATTERY_IMG_Y = 340; + +constexpr int16_t DISTURB_LABEL_X = 136; +constexpr int16_t DISTURB_LABEL_Y = 145; +constexpr int16_t SCREEN_LABEL_X = 270; +constexpr int16_t SCREEN_LABEL_Y = 145; +constexpr int16_t PHONE_LABEL_X = 68; +constexpr int16_t PHONE_LABEL_Y = 279; +constexpr int16_t ALARM_LABEL_X = 203; +constexpr int16_t ALARM_LABEL_Y = 279; +constexpr int16_t SETTING_LABEL_X = 338; +constexpr int16_t SETTING_LABEL_Y = 279; + +constexpr int16_t BATTERY_LABEL_X = 247; +constexpr int16_t BATTERY_LABEL_Y = 335; +constexpr int16_t DATE_LABEL_X = 173; +constexpr int16_t DATE_LABEL_Y = 374; + +constexpr int16_t FONT_DEFAULT_SIZE = 24; +constexpr int16_t TEXT_WIDTH = 86; +constexpr int16_t TEXT_HEIGHT = 30; + +constexpr int16_t NONOTICE_LABLE_X = 141; +constexpr int16_t NONOTICE_LABLE_Y = 212; + +MessageMainView::MessageMainView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::MessageMainView"); + g_pMessageMainView = this; +} + +MessageMainView::~MessageMainView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::~MessageMainView"); + RemoveAll(); + delete messageLables; + messageLables = nullptr; + delete messageLable; + messageLable = nullptr; + delete deletereminder; + deletereminder = nullptr; + delete confirm; + confirm = nullptr; + delete cancel; + cancel = nullptr; + delete notice; + notice = nullptr; + delete contentList; + contentList = nullptr; + if (listAdapter != nullptr) { + delete listAdapter; + listAdapter = nullptr; + } + g_pMessageMainView = nullptr; + MessageModel::GetInstance().SetViewStatus(false); +} + +MessageMainView *MessageMainView::GetInstance(void) +{ + return g_pMessageMainView; +} + +bool MessageMainView::InitView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::InitView"); + messageLable = new UILabel(); + if (messageLable == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "messageLable new fail"); + return false; + } + messageLable->SetPosition(175, 20, 100, 30); + messageLable->SetText("通知"); + messageLable->SetAlign(TEXT_ALIGNMENT_CENTER); + messageLable->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); + messageLable->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + messageLable->SetViewId("Notify"); + messageLable->SetTouchable(true); + notifyListener = (UIView::OnClickListener *)OHOS::MainPresenterSample::GetInstance(); + messageLable->SetOnClickListener(notifyListener); + // 删除图标 + notice = new UIImageView(); + if (notice == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerTimingView:: new startButton fail"); + return false; + } + notice->SetPosition(175, 330); + notice->Resize(100, 100); + notice->SetSrc(ALARM_TRUE_ADD_PATH); + notice->SetViewId("Delete"); + notice->SetTouchable(true); + clickListener = (UIView::OnClickListener *)OHOS::MainPresenterSample::GetInstance(); + notice->SetOnClickListener(clickListener); + ShowMessageList(); + InitScrollData(); + Add(messageLable); + Add(notice); + return true; +} + +void MessageMainView::PreLoad(void) +{ + if (! MessageModel::GetInstance().GetViewStatus()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::PreLoad,viewiInitStatus == false"); + InitView(); + DeletionView(); + NoNotify(); + const std::vector itemInfo = MessageModel::GetInstance().GetMessagelistItems(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::PreLoad,itemInfo == %d", itemInfo.size()); + if (itemInfo.size() == 0) { + messageLable->SetVisible(false); + notice->SetVisible(false); + contentList->SetVisible(false); + deletereminder->SetVisible(false); + confirm->SetVisible(false); + cancel->SetVisible(false); + messageLables->SetVisible(true); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::PreLoad,itemInfo.size() == 0"); + } else { + messageLable->SetVisible(true); + notice->SetVisible(true); + contentList->SetVisible(true); + deletereminder->SetVisible(false); + confirm->SetVisible(false); + cancel->SetVisible(false); + messageLables->SetVisible(false); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::PreLoad,itemInfo.size() != 0"); + } + MessageModel::GetInstance().SetViewStatus(true); + } +} + +void MessageMainView::ShowMessageList(void) +{ + contentList = new UIList(); + if (contentList == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::ShowMessageList contentList is nullptr"); + return; + } + contentList->SetPosition(32, 70); + contentList->Resize(HORIZONTAL_RESOLUTION, 318); // 364: height + contentList->SetSelectPosition(120); // middle position + contentList->SetDraggable(true); + contentList->SetThrowDrag(true); + contentList->EnableAutoAlign(true); + contentList->SetElastic(true); + Add(contentList); +} + +void MessageMainView::ConfirmDeletion(void) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::ConfirmDeletion"); + if (notice->IsVisible()) { + notice->SetVisible(false); + } + if (messageLable->IsVisible()) { + messageLable->SetVisible(false); + } + if (contentList->IsVisible()) { + contentList->SetVisible(false); + } + if (! deletereminder->IsVisible()) { + deletereminder->SetVisible(true); + } + if (! confirm->IsVisible()) { + confirm->SetVisible(true); + } + if (! cancel->IsVisible()) { + cancel->SetVisible(true); + } +} + +void MessageMainView::NewNotify(void) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::NewNotify"); + if (messageLables->IsVisible()) { + messageLables->SetVisible(false); + } + if (! notice->IsVisible()) { + notice->SetVisible(true); + } + if (! messageLable->IsVisible()) { + messageLable->SetVisible(true); + } + if (! contentList->IsVisible()) { + contentList->SetVisible(true); + } +} + +void MessageMainView::DeletionView(void) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::DeletionView"); + // 标题 + deletereminder = new UILabel(); + if (deletereminder == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deletereminder new fail"); + return; + } + deletereminder->SetPosition(177, 145); // widget's left position and top position + deletereminder->Resize(260, 204); // widget's width and height + deletereminder->SetViewId("deletereminder");// Set style + + // Set additional property + deletereminder->SetText("是否删除通知?"); + deletereminder->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + deletereminder->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + deletereminder->SetRollSpeed(0); + + // 确认按钮 + confirm = new UILabelButton(); + if (confirm == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "confirm new fail"); + return; + } + confirm->SetPosition(88, 255); // widget's left position and top position + confirm->Resize(70, 50); // widget's width and height + confirm->SetViewId("Confirm");// Set style + + // Set additional property + confirm->SetText("确认"); + confirm->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 16); + confirm->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + confirmListener = (UIView::OnClickListener *)OHOS::MainPresenterSample::GetInstance(); + confirm->SetOnClickListener(confirmListener); + + // 取消按钮 + cancel = new UILabelButton(); + if (cancel == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cancel new fail"); + return; + // cancel = new UILabelButton(); + } + cancel->SetPosition(301, 251); // widget's left position and top position + cancel->Resize(70, 50); // widget's width and height + cancel->SetViewId("Cancel");// Set style + + // Set additional property + cancel->SetText("取消"); + cancel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 16); + cancel->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + cancelListener = (UIView::OnClickListener *)OHOS::MainPresenterSample::GetInstance(); + cancel->SetOnClickListener(cancelListener); + Add(deletereminder); + Add(confirm); + Add(cancel); +} + +void MessageMainView::VerticalViewInits(void) +{ + if (deletereminder->IsVisible()) { + deletereminder->SetVisible(false); + } + if (confirm->IsVisible()) { + confirm->SetVisible(false); + } + if (cancel->IsVisible()) { + cancel->SetVisible(false); + } + if (! messageLables->IsVisible()) { + messageLables->SetVisible(true); + } +} + +void MessageMainView::NoNotify(void) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::NoNotify"); + messageLables = new UILabel(); + if (messageLables == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "messageLable new fail"); + return; + } + messageLables->SetPosition(177, 212, 100, 30); + messageLables->SetText("无消息"); + messageLables->SetAlign(TEXT_ALIGNMENT_CENTER); + messageLables->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); + messageLables->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + messageLables->SetViewId("NoNotify"); + messageLables->SetTouchable(true); + newNotifyListener = (UIView::OnClickListener *)OHOS::MainPresenterSample::GetInstance(); + messageLables->SetOnClickListener(newNotifyListener); + Add(messageLables); +} + +void MessageMainView::CancelDeletion(void) +{ + if (deletereminder->IsVisible()) { + deletereminder->SetVisible(false); + } + if (confirm->IsVisible()) { + confirm->SetVisible(false); + } + if (cancel->IsVisible()) { + cancel->SetVisible(false); + } + if (! messageLable->IsVisible()) { + messageLable->SetVisible(true); + } + if (! notice->IsVisible()) { + notice->SetVisible(true); + } + if (! contentList->IsVisible()) { + contentList->SetVisible(true); + } +} + +void MessageMainView::RefreshMessageList(std::vector item) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::RefreshMessageList"); + if (listAdapter == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::RefreshMessageList listAdapter is nullptr"); + listAdapter = new MessageAdapter(); + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::RefreshMessageList"); + if (item.size() == 0) { + return; + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::RefreshMessageList %d", item.size()); + listAdapter->ClearListItem(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "listAdapter->ClearListItem"); + for (size_t i = 0; i < item.size(); ++i) { + listAdapter->AddListItem(item[i]); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "listAdapter->AddListItem"); + } + } + if (contentList == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageMainView::contentList fail"); + return; + } + contentList->ScrollTo(0); + contentList->SetAdapter(listAdapter); + contentList->RefreshList(); +} + +bool MessageMainView::InitScrollData() +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMainView::InitScrollData"); + const std::vector itemInfo = MessageModel::GetInstance().GetMessagelistItems(); + RefreshMessageList(itemInfo); + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageModel.cpp new file mode 100644 index 000000000..8bbdf47f9 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/MessageModel.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: MainModel.cpp + * Author: + * Create: 2021-11-23 + */ + +#include "unistd.h" +#include "main/MessageModel.h" +#include "main/MessageMainView.h" +#include "kv_store.h" +#include "securec.h" +#include "wearable_log.h" +#include "main/DialBinTypesV2.h" +#include "power_display_service.h" +#include +#include +#include +namespace OHOS { + MessageModel::MessageModel() { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::MessageModel"); + } + + MessageModel::~MessageModel() { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::~MessageModel"); + } + + MessageModel &MessageModel::GetInstance() + { + static MessageModel instance; + return instance; + } + + void MessageModel::GetMessageInfo(std::string app, std::string contact, std::string information) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::GetMessageInfo"); + //保存数据 + mes.label_1 = app; // 应用 + mes.label_2 = contact; // 联系人 + mes.label_3 = information; // 内容 + mes.icon = "默认"; + // if (app == 微信) { + // mes1.icon = 微信图标; + // } + // if (app == 信息) { + // mes1.icon = 信息图标; + // } + InitMessageItem(); + if (GetViewStatus()) { + if (! MessageMainView::GetInstance()->contentList->IsVisible()) { + MessageMainView::GetInstance()->NewNotify(); + } + MessageMainView::GetInstance()->InitScrollData(); + } + } + + void MessageModel::InitMessageItem() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem"); + if (vecMsg.size() != 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,vecMsg.size() != 0"); + size_t i = 0; + for (i; i < vecMsg.size(); ++i) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,for()"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,vecMsg[i].label_1 = %s", vecMsg[i].label_1.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,vecMsg[i].label_2 = %s", vecMsg[i].label_2.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,vecMsg[i].label_3 = %s", vecMsg[i].label_3.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,mes.label_1 = %s", mes.label_1.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,mes.label_2 = %s", mes.label_2.c_str()); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,mes.label_3 = %s", mes.label_3.c_str()); + if (vecMsg[i].label_1 == mes.label_1 && vecMsg[i].label_2 == mes.label_2) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,if()"); + vecMsg[i].label_3 = mes.label_3; + break; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,else(break)"); + continue; + } + if (i == vecMsg.size()) { + vecMsg.push_back(mes); + } + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MessageModel::InitMessageItem,else()"); + vecMsg.push_back(mes); + } + } + + const std::vector MessageModel::GetMessagelistItems() const + { + return vecMsg; + } + + void MessageModel::ClearListItem() + { + vecMsg.clear(); + } + + void MessageModel::SetViewStatus(bool viewStatus) + { + viewInitStatus = viewStatus; + } + + bool MessageModel::GetViewStatus(void) + { + return viewInitStatus; + } +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/ModelListenerSample.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/ModelListenerSample.cpp index 26c67fb1f..5971ec477 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/ModelListenerSample.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/ModelListenerSample.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "ModelListenerSample.h" +#include "main/ModelListenerSample.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/PullUpDownView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/PullUpDownView.cpp index 34eb21de7..810d3ab07 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/PullUpDownView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/PullUpDownView.cpp @@ -5,13 +5,13 @@ * Create: 2021-09-11 */ -#include "PullUpDownView.h" +#include "main/PullUpDownView.h" #include "wearable_log.h" #include "UiConfig.h" #include "common/screen.h" -#include "MainPresenterSample.h" -#include "ScreenModels.h" -#include "SettingModel.h" +#include "main/MainPresenterSample.h" +#include "screensetting/ScreenModels.h" +#include "settings/SettingModel.h" #include "ui_resource_image.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingPresenter.cpp index 7ca2d4c07..1c86925b3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingPresenter.cpp @@ -3,20 +3,20 @@ * Description: VolumeSettingView view * Create: 2021-09-5 */ -#include "VolumeSettingView.h" -#include "VolumeSettingPresenter.h" -#include "PlayersModel.h" +#include "main/VolumeSettingView.h" +#include "main/VolumeSettingPresenter.h" +#include "player/PlayersModel.h" #include "common/image_cache_manager.h" #include "UiConfig.h" #include "ui_resource_image.h" #include "drag_event.h" -#include "MainCallingView.h" -#include "PhoneService.h" -#include "CallerLogModel.h" +#include "makephone/MainCallingView.h" +#include "phoneservice/PhoneService.h" +#include "callerlog/CallerLogModel.h" #include "bts_avrcp_controller.h" #include "bts_avrcp_target.h" #include "notification_manager.h" -#include "BluetoothHeadsetEvent.h" +#include "bluetooth/BluetoothHeadsetEvent.h" #include "bts_avrcp_controller.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingView.cpp index e8eeb4df7..ae6426962 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/VolumeSettingView.cpp @@ -3,8 +3,8 @@ * Description: VolumeSettingView view * Create: 2021-09-5 */ -#include "VolumeSettingView.h" -#include "PlayersView.h" +#include "main/VolumeSettingView.h" +#include "player/PlayersView.h" #include "common/image_cache_manager.h" #include "UiConfig.h" #include "ui_resource_image.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcLabelView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcLabelView.cpp index 02ce99c31..fa4a34771 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcLabelView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcLabelView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialArcLabelView.h" +#include "main/dial/DialArcLabelView.h" #include "securec.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcProgressView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcProgressView.cpp index 67dadd4c7..d045de8e7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcProgressView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialArcProgressView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialArcProgressView.h" +#include "main/dial/DialArcProgressView.h" namespace OHOS { DialArcProgressView::DialArcProgressView(void) @@ -28,4 +28,16 @@ void DialArcProgressView::HandleFloatData(float data) value_ = value; SetValue(value_); } + +void DialArcProgressView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) +{ + if (foregroundStopCount_ != 0) { + Rect rect = GetOrigRect(); + foregroundGradient_.startX = rect.GetX(); + foregroundGradient_.startY = rect.GetY(); + foregroundGradient_.endX = rect.GetRight(); + foregroundGradient_.endY = rect.GetBottom(); + } + UICircleProgress::OnDraw(gfxDstBuffer, invalidatedArea); +} } \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialBoxProgressView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialBoxProgressView.cpp index 8084dfb75..b3ce7908c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialBoxProgressView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialBoxProgressView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialBoxProgressView.h" +#include "main/dial/DialBoxProgressView.h" namespace OHOS { DialBoxProgressView::DialBoxProgressView(void) @@ -28,4 +28,16 @@ void DialBoxProgressView::HandleFloatData(float data) value_ = value; SetValue(value_); } + +void DialBoxProgressView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) +{ + if (foregroundStopCount_ != 0) { + Rect rect = GetOrigRect(); + foregroundGradient_.startX = rect.GetX(); + foregroundGradient_.startY = rect.GetY(); + foregroundGradient_.endX = rect.GetRight(); + foregroundGradient_.endY = rect.GetBottom(); + } + UIBoxProgress::OnDraw(gfxDstBuffer, invalidatedArea); +} } \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDataBase.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDataBase.cpp index bda2cf912..3052d247d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDataBase.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDataBase.cpp @@ -6,7 +6,7 @@ */ #include -#include "dial/DialDataBase.h" +#include "main/dial/DialDataBase.h" namespace { struct DataTypeHash { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDigitalImgView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDigitalImgView.cpp index 4f316171e..50e7b59df 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDigitalImgView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialDigitalImgView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialDigitalImgView.h" +#include "main/dial/DialDigitalImgView.h" #include #include "securec.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialLabelView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialLabelView.cpp index 40fd07671..38a544fd6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialLabelView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialLabelView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialLabelView.h" +#include "main/dial/DialLabelView.h" #include "securec.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelHeartRate.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelHeartRate.cpp index ff827325e..d6b6d91b7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelHeartRate.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelHeartRate.cpp @@ -5,8 +5,8 @@ * Create: 2023-12 */ -#include "RegisterDialModel.h" -#include "DialModelHeartRate.h" +#include "main/dial/RegisterDialModel.h" +#include "main/dial/DialModelHeartRate.h" REGIST_DIAL_MODULE(OHOS::DialDataType::HEART_RATE, OHOS::DialModelHeartRate::GetInstance()); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelPower.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelPower.cpp index b6a2c5a86..dcb3e0d67 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelPower.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelPower.cpp @@ -5,16 +5,32 @@ * Create: 2023-12 */ -#include "RegisterDialModel.h" -#include "DialModelPower.h" +#include "main/dial/RegisterDialModel.h" +#include "main/dial/DialModelPower.h" REGIST_DIAL_MODULE(OHOS::DialDataType::BATTERY, OHOS::DialModelPower::GetInstance()); namespace OHOS { +static RegisterDialModel REGIST_BATTERY_LEVEL(DialDataType::BATTERY_LEVEL, DialModelPower::GetInstance()); +static RegisterDialModel REGIST_BATTERY_ENUM(DialDataType::BATTERY_ENUM, DialModelPower::GetInstance()); bool DialModelPower::GetDialFloatData(DialDataType& type, float& out) { - (void)type; - out = power_; + switch (type) { + case DialDataType::BATTERY: { + out = power_; + break; + } + case DialDataType::BATTERY_LEVEL: { + out = static_cast(power_) / 100.0; // 100.0: full power + break; + } + case DialDataType::BATTERY_ENUM: { + out = static_cast(power_ / 10); // 10: num + break; + } + default: + (void)type; + } return true; } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelSteps.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelSteps.cpp index a1ad2edf9..15fd7393c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelSteps.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelSteps.cpp @@ -5,8 +5,8 @@ * Create: 2023-12 */ -#include "RegisterDialModel.h" -#include "DialModelSteps.h" +#include "main/dial/RegisterDialModel.h" +#include "main/dial/DialModelSteps.h" REGIST_DIAL_MODULE(OHOS::DialDataType::STEP_COUNT, OHOS::DialModelSteps::GetInstance()); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelTime.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelTime.cpp index b626e0233..4422425e9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelTime.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialModelTime.cpp @@ -7,8 +7,8 @@ #include #include "sys/time.h" -#include "RegisterDialModel.h" -#include "DialModelTime.h" +#include "main/dial/RegisterDialModel.h" +#include "main/dial/DialModelTime.h" #include "components/root_view.h" #define REGIST_DIAL_MODULE_ANGLE_H(type, func) static OHOS::RegisterDialModel(REGIST_ANGLE_H)(type, func) @@ -41,6 +41,8 @@ REGIST_DIAL_MODULE_YEAR(OHOS::DialDataType::SOLAR_YEAR, OHOS::DialModelTime::Get REGIST_DIAL_MODULE_GEAR_POSITIVE(OHOS::DialDataType::SWIVEL_GEAR_POSITIVE, OHOS::DialModelTime::GetInstance()); REGIST_DIAL_MODULE_GEAR_NEGATIVE(OHOS::DialDataType::SWIVEL_GEAR_NEGATIVE, OHOS::DialModelTime::GetInstance()); +static OHOS::RegisterDialModel REGIST_MOUNTH_80(OHOS::DialDataType::MONTH_DATA, OHOS::DialModelTime::GetInstance()); + namespace OHOS { static constexpr int16_t S_MS_US_TRANS = 1000; // 1000: seconds, milliseconds, microsecond transform value static constexpr uint8_t ONE_MINUTE_IN_SECOND = 60; // 60: 60 seconds per minute @@ -186,6 +188,10 @@ bool DialModelTime::GetDialFloatData(DialDataType& type, float& out) out = static_cast(accleratedAngle * -1.0 + CIRCLE_IN_DEGREE); break; } + case DialDataType::MONTH_DATA: { + out = static_cast(tblock_->tm_mon) + 1.0; + break; + } default: return false; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialOptionImgView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialOptionImgView.cpp index 980d438cd..4175937c2 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialOptionImgView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialOptionImgView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialOptionImgView.h" +#include "main/dial/DialOptionImgView.h" #include "securec.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialRotateImgView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialRotateImgView.cpp index bec17ca81..171aeea7e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialRotateImgView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialRotateImgView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialRotateImgView.h" +#include "main/dial/DialRotateImgView.h" namespace OHOS { DialRotateImgView::DialRotateImgView(void) diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialSequenceImgView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialSequenceImgView.cpp index c7d1c24e7..8741d4c9a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialSequenceImgView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialSequenceImgView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialSequenceImgView.h" +#include "main/dial/DialSequenceImgView.h" #include "securec.h" #include "common/graphic_utils.h" #include "common/image_cache_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialStaticImgView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialStaticImgView.cpp index ffc87a701..bfa5182ea 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialStaticImgView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialStaticImgView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialStaticImgView.h" +#include "main/dial/DialStaticImgView.h" namespace OHOS { DialStaticImgView::DialStaticImgView() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialVideoView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialVideoView.cpp index f18e9ea9d..9ac7b75d1 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialVideoView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialVideoView.cpp @@ -2,7 +2,7 @@ * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. */ -#include "DialVideoView.h" +#include "main/dial/DialVideoView.h" namespace OHOS { static constexpr int16_t JPEG_HEIGHT_DIVISOR = 2; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewContainer.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewContainer.cpp index 8ed4cf710..198c0679b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewContainer.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewContainer.cpp @@ -5,9 +5,9 @@ * Create: 2025-02-06 */ -#include "DialViewContainer.h" -#include "DialDigitalImgView.h" -#include "ModelDialDataFactory.h" +#include "main/dial/DialViewContainer.h" +#include "main/dial/DialDigitalImgView.h" +#include "main/dial/ModelDialDataFactory.h" namespace OHOS { DialViewContainer::~DialViewContainer() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewGroup.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewGroup.cpp index 54d197579..3c52dd760 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewGroup.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/DialViewGroup.cpp @@ -1,20 +1,20 @@ -#include "DialViewGroup.h" +#include "main/dial/DialViewGroup.h" #include #include #include "NativeAbility.h" #include "msg_center.h" #include "securec.h" -#include "DialBinParser.h" -#include "ModelDialDataFactory.h" +#include "main/DialBinParser.h" +#include "main/dial/ModelDialDataFactory.h" #include "common/low_power_manager.h" #include "common/image_cache_manager.h" #ifdef SUPPORT_OHOSFWK -#include "ui_screennotify.h" +#include "screennotify/ui_screennotify.h" #endif -#include "MainPresenterSample.h" -#include "DialDigitalImgView.h" +#include "main/MainPresenterSample.h" +#include "main/dial/DialDigitalImgView.h" #include "common/input_device_manager.h" -#include "DialSequenceImgView.h" +#include "main/dial/DialSequenceImgView.h" #include "engines/gfx/lite_m_gfx_engine.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/ModelDialDataFactory.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/ModelDialDataFactory.cpp index d17de5b31..71ea7a19f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/ModelDialDataFactory.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/ModelDialDataFactory.cpp @@ -5,7 +5,7 @@ * Create: 2023-12 */ -#include "ModelDialDataFactory.h" +#include "main/dial/ModelDialDataFactory.h" namespace OHOS { bool ModelDialDataFactory::GetDialTextData(DialDataType& type, std::string*& out, int16_t& strNum) { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/WatchInterface.cpp b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/WatchInterface.cpp index c4f9fd1c2..11f98448d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/WatchInterface.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/main/src/dial/WatchInterface.cpp @@ -6,24 +6,35 @@ */ #include +#include #include "dirent.h" -#include "DialBinParser.h" +#include "main/DialBinParser.h" #include "UiConfig.h" -#include "WatchInterface.h" +#include "main/dial/WatchInterface.h" #include "gfx_utils/vector.h" #include "common/screen.h" -#include "MainModel.h" -#include "MainViewSample.h" -#include "SetDialModel.h" +#include "main/MainModel.h" +#include "main/MainViewSample.h" +#include "set_dial/SetDialModel.h" #include "graphic_service.h" #include "NativeAbility.h" +#include "graphic_mutex.h" +#include "set_dial/SetDialModel.h" +#include "set_dial/SetDialPresenter.h" +#include "power_display_service.h" using namespace OHOS; namespace { -struct { - Graphic::Vector fileNames; // only for 3.0 - Graphic::Vector watchInfo; // only for 3.0 -} g_info; +struct WatchInfoInner { + std::string fileName; + watch_dial_info watchInfo; +}; + +Graphic::Vector g_info; +GraphicMutex g_mutex; +GraphicCond g_cond; +bool g_eventFinished = true; +const uint16_t INVALID_INFO_INDEX = 0xFFFF; bool GetActiveWatchPath(std::string &path) { @@ -34,7 +45,7 @@ bool GetActiveWatchPath(std::string &path) return false; } -bool GetPreviewInfo(const std::string &fileName, DialPreviewInfo &preview) +bool GetPreviewInfo(const std::string &fileName, DialPreviewInfo &preview, bool isNeedVerify = false) { const std::string type(".bin"); if (!(fileName.length() > type.length() && @@ -45,7 +56,7 @@ bool GetPreviewInfo(const std::string &fileName, DialPreviewInfo &preview) FILE *file = fopen(fileName.c_str(), "rb"); bool isSuccess = false; if (file != nullptr) { - isSuccess = DialBinParserManager::GetInstance()->GetDialPreviewInfo(file, &preview); + isSuccess = DialBinParserManager::GetInstance()->GetDialPreviewInfo(fileName, file, &preview, isNeedVerify); fclose(file); } return isSuccess; @@ -70,16 +81,14 @@ bool ConvertPreview2WatchDialInfo(const DialPreviewInfo &preview, watch_dial_inf return true; } -bool GetAllWatchInfo() +void RefreshAllWatchInfo() { - g_info.fileNames.Clear(); - g_info.watchInfo.Clear(); + g_info.Clear(); struct dirent *direntp = nullptr; - // ´ò¿ªÄ¿Â¼ + // 打开目录 DIR *dirp = opendir(APP_DIAL_PATH); - bool isSuccess = true; - // ±éÀúÎļþ + // 遍历文件 DialPreviewInfo info; watch_dial_info watchInfo; std::string activePath; @@ -87,56 +96,133 @@ bool GetAllWatchInfo() if (dirp != nullptr) { while ((direntp = readdir(dirp)) != nullptr) { std::string fileName = std::string(APP_DIAL_PATH) + std::string("/") + std::string(direntp->d_name); - isSuccess = GetPreviewInfo(fileName, info); - if (!isSuccess) { + if (!GetPreviewInfo(fileName, info)) { continue; } const std::string lowestVersion("3.0"); std::string curVersion(info.protocolVersion); if (curVersion >= lowestVersion) { - isSuccess = ConvertPreview2WatchDialInfo(info, watchInfo); - if (!isSuccess) { + if (!ConvertPreview2WatchDialInfo(info, watchInfo)) { break; } watchInfo.install_state = true; watchInfo.is_current_watch = isActiveExist ? (activePath == fileName) : false; - g_info.fileNames.PushBack(fileName); - g_info.watchInfo.PushBack(watchInfo); + g_info.PushBack({fileName, watchInfo}); } } } - // ¹Ø±ÕĿ¼ + // 关闭目录 closedir(dirp); - return isSuccess; } -} // namespace -bool GetAllWatchFaceInfo(watch_dial_info *info, uint8_t *num, uint8_t maxCnt) +inline bool IsFileExists(const std::string &file) +{ + return access(file.c_str(), F_OK) == 0; +} + +uint16_t FindMaxVersionIndex(uint16_t indexArray[], uint16_t num) +{ + if (num == 0) { + return INVALID_INFO_INDEX; + } + + if (num == 0) { + return indexArray[0]; + } + std::string version = reinterpret_cast(g_info[indexArray[0]].watchInfo.watch_version); + uint16_t index = 0; + for (uint16_t i = 1; i < num; ++i) { + std::string curVerion = std::string(reinterpret_cast(g_info[indexArray[i]].watchInfo.watch_version)); + if (curVerion > version) { + version = curVerion; + index = i; + } + } + if (num > 1) { + GRAPHIC_LOGE("There are watches with the same uuid. %u", g_info[indexArray[index]].watchInfo.uuid); + } + index = indexArray[index]; + return index; +} + +void GetWatchInfo(uint32_t uuid, uint16_t &index) +{ + index = INVALID_INFO_INDEX; + if (g_info.IsEmpty()) { + RefreshAllWatchInfo(); + } + const uint16_t MAX_INFO_NUM = 128; + static uint16_t indexArray[MAX_INFO_NUM]; + uint16_t num = 0; + std::string activePath; + bool isActive = GetActiveWatchPath(activePath); + bool isNeedRequery = false; + for (uint16_t i = 0; i < g_info.Size(); ++i) { + if (uuid == g_info[i].watchInfo.uuid && num < MAX_INFO_NUM) { + if (IsFileExists(g_info[i].fileName)) { + g_info[i].watchInfo.is_current_watch = isActive ? (g_info[i].fileName == activePath) : false; + indexArray[num++] = i; + } else { + RefreshAllWatchInfo(); + isNeedRequery = true; + break; + } + } + } + + if (!isNeedRequery) { + index = FindMaxVersionIndex(indexArray, num); + return; + } + num = 0; + for (uint16_t i = 0; i < g_info.Size(); ++i) { + if (uuid == g_info[i].watchInfo.uuid && num < MAX_INFO_NUM) { + indexArray[num++] = i; + } + } + index = FindMaxVersionIndex(indexArray, num); +} + +void TryToTurnOnScreen() +{ + const power_display_svr_api_t *ctx = power_display_svr_get_api(); + if (ctx == nullptr) { + return; + } + if (ctx->get_screen_state != nullptr && ctx->get_screen_state() != SCREEN_ON) { + if (ctx->turn_on_screen != nullptr) { + ctx->turn_on_screen(); + } + } +} +} // anonymous namespace + +bool GetAllWatchFaceInfo(watch_dial_info **info, uint8_t *num) { if (info == nullptr || num == nullptr) { GRAPHIC_LOGE("para error!"); return false; } - if (!GetAllWatchInfo()) { - GRAPHIC_LOGE("failed to get all watch info."); - return false; + GraphicLockGuard guard(g_mutex); + while (!g_eventFinished) { + g_cond.Wait(g_mutex); } - if (g_info.watchInfo.Size() > maxCnt) { - GRAPHIC_LOGE("mem is not enough."); - return false; - } - *num = g_info.watchInfo.Size(); + RefreshAllWatchInfo(); + *num = g_info.Size(); if (*num == 0) { - return false; + *info = nullptr; + return true; } - if (memcpy_s(info, - g_info.watchInfo.Size() * sizeof(watch_dial_info), - &g_info.watchInfo[0], - g_info.watchInfo.Size() * sizeof(watch_dial_info)) != 0) { - GRAPHIC_LOGE("copy info error!"); + watch_dial_info *mem = static_cast(malloc(*num * sizeof(watch_dial_info))); + if (mem == nullptr) { + GRAPHIC_LOGE("failed to malloc"); return false; } + for (uint16_t i = 0; i < g_info.Size(); ++i) { + memcpy_s(&mem[i], sizeof(watch_dial_info), &g_info[i].watchInfo, sizeof(watch_dial_info)); + } + *info = mem; return true; } @@ -146,17 +232,19 @@ bool GetWatchFaceInfo(uint32_t uuid, watch_dial_info *watch) GRAPHIC_LOGE("para error!"); return false; } - if (!GetAllWatchInfo()) { - GRAPHIC_LOGE("failed to get all watch info."); + + uint16_t index = INVALID_INFO_INDEX; + GraphicLockGuard guard(g_mutex); + while (!g_eventFinished) { + g_cond.Wait(g_mutex); + } + GetWatchInfo(uuid, index); + if (index == INVALID_INFO_INDEX) { + GRAPHIC_LOGE("uuid %u does not exist", uuid); return false; } - for (uint16_t i = 0; i < g_info.watchInfo.Size(); ++i) { - if (g_info.watchInfo[i].uuid == uuid) { - *watch = g_info.watchInfo[i]; - return true; - } - } - return false; + memcpy_s(watch, sizeof(watch_dial_info), &g_info[index].watchInfo, sizeof(watch_dial_info)); + return true; } bool GetWatchCapability(watch_dev_cap_info *capability) @@ -235,90 +323,118 @@ bool GetCurrentWatchFaceInfo(watch_dial_info *watch) bool SetCurrentWatchFace(uint32_t uuid) { - if (!GetAllWatchInfo()) { - GRAPHIC_LOGE("failed to get all watch info."); + uint16_t index = INVALID_INFO_INDEX; + GraphicLockGuard guard(g_mutex); + while (!g_eventFinished) { + g_cond.Wait(g_mutex); + } + GetWatchInfo(uuid, index); + if (index == INVALID_INFO_INDEX) { + GRAPHIC_LOGE("uuid %u does not exist", uuid); return false; } - watch_dial_info info; - uint16_t index = 0; - bool isExists = false; - for (uint16_t i = 0; i < g_info.watchInfo.Size(); ++i) { - if (uuid == g_info.watchInfo[i].uuid) { - isExists = true; - info = g_info.watchInfo[i]; - index = i; - break; - } - } - if (!isExists) { - GRAPHIC_LOGE("uuid does not exist!"); - return false; + DialSetting setting = MainModel::GetInstance().GetDialSetting(); + setting.dialFlag = 1; + setting.dialFullName = g_info[index].fileName; + if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_SET_DIAL) { + GraphicService::GetInstance()->PostGraphicEvent([setting]() { + if (SetDialPresenter::GetCurrentInstance() != nullptr) { + SetDialPresenter::GetCurrentInstance()->SpecifyDialSetting(setting); + } + }); + NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN_SAMPLE); + return true; } - if (info.is_current_watch) { + if (g_info[index].watchInfo.is_current_watch) { return true; } - - DialSetting setting = MainModel::GetInstance().GetDialSetting(); - setting.dialFlag = 1; - setting.dialFullName = g_info.fileNames[index]; + g_eventFinished = false; GraphicService::GetInstance()->PostGraphicEvent([setting]() { + GraphicLockGuard guardGraphic(g_mutex); MainModel::GetInstance().GetDialSetting() = setting; MainModel::GetInstance().AddDialSetting(setting); if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_MAIN_SAMPLE) { MainViewSample::GetInstance()->ReloadWatchFace(); } + g_eventFinished = true; + g_cond.Signal(); }); + TryToTurnOnScreen(); return true; } bool UninstallWatch(uint32_t uuid) { - if (!GetAllWatchInfo()) { - GRAPHIC_LOGE("failed to get all watch info."); - return false; - } - watch_dial_info info; - uint16_t index = 0; - bool isExists = false; - for (uint16_t i = 0; i < g_info.watchInfo.Size(); ++i) { - if (uuid == g_info.watchInfo[i].uuid) { - isExists = true; - info = g_info.watchInfo[i]; - index = i; - break; - } - } - if (!isExists) { - GRAPHIC_LOGE("uuid does not exist!"); + uint16_t index = INVALID_INFO_INDEX; + GraphicLockGuard guard(g_mutex); + while (!g_eventFinished) { + g_cond.Wait(g_mutex); + } + GetWatchInfo(uuid, index); + if (index == INVALID_INFO_INDEX) { + GRAPHIC_LOGE("uuid %u does not exist", uuid); return false; } - if (info.is_current_watch) { - DialSetting setting = MainModel::GetInstance().GetDialSetting(); + DialSetting setting = MainModel::GetInstance().GetDialSetting(); + if (g_info[index].watchInfo.is_current_watch) { setting.dialFlag = 0; setting.dialId = 0; - std::string fileName = g_info.fileNames[index]; - GraphicService::GetInstance()->PostGraphicEvent([setting, fileName]() { - MainModel::GetInstance().GetDialSetting() = setting; - MainModel::GetInstance().AddDialSetting(setting); - if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_MAIN_SAMPLE) { - MainViewSample::GetInstance()->ReloadWatchFace(); - } - if (remove(fileName.c_str()) != 0) { - GRAPHIC_LOGE("failed to remove file %s", fileName.c_str()); + } + if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_SET_DIAL) { + if (g_info[index].watchInfo.is_current_watch) { + // If it is the current watch face, set it as the default watch face. Otherwise, the configuration remains + // unchanged. + GraphicService::GetInstance()->PostGraphicEvent([setting]() { + if (SetDialPresenter::GetCurrentInstance() != nullptr) { + SetDialPresenter::GetCurrentInstance()->SpecifyDialSetting(setting); + } + }); + } + NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN_SAMPLE); + g_eventFinished = false; + GraphicService::GetInstance()->PostGraphicEvent([index]() { + GraphicLockGuard guardGraphic(g_mutex); + ImageCacheManager::GetInstance().UnloadAllInMultiRes(g_info[index].fileName); + if (remove(g_info[index].fileName.c_str()) != 0) { + GRAPHIC_LOGE("failed to remove file %s", g_info[index].fileName.c_str()); + g_eventFinished = true; + g_cond.Signal(); + return; } + g_info.Erase(index); + g_eventFinished = true; + g_cond.Signal(); }); - } else { - if (remove(g_info.fileNames[index].c_str()) != 0) { - GRAPHIC_LOGE("failed to remove file %s", g_info.fileNames[index].c_str()); - return false; - } + return true; } + + g_eventFinished = false; + GraphicService::GetInstance()->PostGraphicEvent([index, setting]() { + GraphicLockGuard guardGraphic(g_mutex); + if (g_info[index].watchInfo.is_current_watch && + NativeAbility::GetInstance().GetCurSliceId() == VIEW_MAIN_SAMPLE) { + MainModel::GetInstance().GetDialSetting() = setting; + MainModel::GetInstance().AddDialSetting(setting); + MainViewSample::GetInstance()->ReloadWatchFace(); + } + ImageCacheManager::GetInstance().UnloadAllInMultiRes(g_info[index].fileName); + if (remove(g_info[index].fileName.c_str()) != 0) { + GRAPHIC_LOGE("failed to remove file %s", g_info[index].fileName.c_str()); + g_eventFinished = true; + g_cond.Signal(); + return; + } + g_info.Erase(index); + g_eventFinished = true; + g_cond.Signal(); + }); + TryToTurnOnScreen(); return true; } -bool InstallWatch(const char *path, uint32_t *uuid) +bool GetUuidByPath(const char *path, uint32_t *uuid) { if (path == nullptr || uuid == nullptr) { GRAPHIC_LOGE("para error!"); @@ -326,45 +442,31 @@ bool InstallWatch(const char *path, uint32_t *uuid) } DialPreviewInfo preview; - if (!GetPreviewInfo(std::string(path), preview)) { + if (!GetPreviewInfo(std::string(path), preview, true)) { return false; } if (std::string(preview.protocolVersion) < std::string("3.0")) { return false; } - *uuid = preview.uuid; - if (!GetAllWatchInfo()) { - GRAPHIC_LOGE("failed to get all watchinfo!"); - return false; - } - for (uint16_t i = 0; i < g_info.watchInfo.Size(); ++i) { - const std::string &fileName = g_info.fileNames[i]; - const watch_dial_info &info = g_info.watchInfo[i]; - if (!(info.uuid == *uuid && std::string(path) != fileName)) { - continue; - } - - if (info.is_current_watch) { - DialSetting setting = MainModel::GetInstance().GetDialSetting(); - setting.dialFlag = 1; - setting.dialFullName = std::string(path); - GraphicService::GetInstance()->PostGraphicEvent([setting, fileName]() { - MainModel::GetInstance().GetDialSetting() = setting; - MainModel::GetInstance().AddDialSetting(setting); - if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_MAIN_SAMPLE) { - MainViewSample::GetInstance()->ReloadWatchFace(); - } - if (remove(fileName.c_str()) != 0) { - GRAPHIC_LOGE("failed to remove file %s", fileName.c_str()); - } - }); - } else { - if (remove(fileName.c_str()) != 0) { - return false; + watch_dial_info watchInfo; + if (ConvertPreview2WatchDialInfo(preview, watchInfo)) { + std::string activePath; + std::string appendPath(path); + bool isActiveExist = GetActiveWatchPath(activePath); + watchInfo.install_state = true; + watchInfo.is_current_watch = isActiveExist ? (activePath == appendPath) : false; + bool isExist = false; + for (uint16_t i = 0; i < g_info.Size(); ++i) { + if (g_info[i].fileName == appendPath) { + isExist = true; + break; } } + if (!isExist) { + g_info.PushBack({appendPath, watchInfo}); + } } - + *uuid = preview.uuid; return true; } \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallerDisplayView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallerDisplayView.cpp index 2426ea21e..5617586d1 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallerDisplayView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallerDisplayView.cpp @@ -4,8 +4,8 @@ * Author: * Create: 2021-10-12 */ -#include "CallerDisplayView.h" -#include "MainCallingPresenter.h" +#include "makephone/CallerDisplayView.h" +#include "makephone/MainCallingPresenter.h" #include "UiConfig.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallingView.cpp index 2c19d7599..953900e8b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallingView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/CallingView.cpp @@ -4,8 +4,8 @@ * Author: * Create: 2021-10-12 */ -#include "CallingView.h" -#include "MainCallingPresenter.h" +#include "makephone/CallingView.h" +#include "makephone/MainCallingPresenter.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/DialingScreenView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/DialingScreenView.cpp index 99808b2e9..e18ae2a72 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/DialingScreenView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/DialingScreenView.cpp @@ -6,8 +6,8 @@ */ #include "wearable_log.h" #include "UiConfig.h" -#include "DialingScreenView.h" -#include "MainCallingPresenter.h" +#include "makephone/DialingScreenView.h" +#include "makephone/MainCallingPresenter.h" namespace OHOS { static constexpr uint16 MATH_ZERO = 0; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingPresenter.cpp index db8a0b9fc..07b4d2cec 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingPresenter.cpp @@ -9,14 +9,14 @@ #include "common/image_cache_manager.h" #include "UiConfig.h" #include "ui_resource_image.h" -#include "MainCallingPresenter.h" -#include "CallingView.h" -#include "CallerDisplayView.h" -#include "DialingScreenView.h" -#include "MainCallingView.h" +#include "makephone/MainCallingPresenter.h" +#include "makephone/CallingView.h" +#include "makephone/CallerDisplayView.h" +#include "makephone/DialingScreenView.h" +#include "makephone/MainCallingView.h" #include "NativeRegisterManager.h" -#include "PhoneService.h" -#include "WaitingHintsView.h" +#include "phoneservice/PhoneService.h" +#include "makephone/WaitingHintsView.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingView.cpp index c4e6af6ac..d079a9676 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/MainCallingView.cpp @@ -6,9 +6,9 @@ */ #include "wearable_log.h" #include "UiConfig.h" -#include "MainCallingView.h" -#include "MainCallingPresenter.h" -#include "CallerLogModel.h" +#include "makephone/MainCallingView.h" +#include "makephone/MainCallingPresenter.h" +#include "callerlog/CallerLogModel.h" namespace OHOS { static MainCallingView *g_pMainView = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/WaitingHintsView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/WaitingHintsView.cpp index e27e55dbc..549e699f3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/WaitingHintsView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/makephone/src/WaitingHintsView.cpp @@ -4,10 +4,10 @@ * Author: * Create: 2022-03-14 */ -#include "WaitingHintsView.h" +#include "makephone/WaitingHintsView.h" #include "UiConfig.h" -#include "CallerLogModel.h" -#include "MainCallingPresenter.h" +#include "callerlog/CallerLogModel.h" +#include "makephone/MainCallingPresenter.h" namespace OHOS { static constexpr uint16 MATH_ZERO = 0; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/MainVocassistView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/MainVocassistView.cpp index 2b1eb6b10..aa90443bc 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/MainVocassistView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/MainVocassistView.cpp @@ -5,8 +5,8 @@ * Create: 2022-01-18 */ -#include "MainVocassistView.h" -#include "VocassistPresenter.h" +#include "offlinevoice/MainVocassistView.h" +#include "offlinevoice/VocassistPresenter.h" namespace OHOS { static MainVocassistView *g_pMainVocassistView = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistModel.cpp index adae52d69..12b59a00f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistModel.cpp @@ -4,10 +4,10 @@ * Author: CompanyName * Create: 2022-01-18 */ -#include "PhoneService.h" -#include "MainViewSample.h" -#include "VocassistView.h" -#include "VocassistModel.h" +#include "phoneservice/PhoneService.h" +#include "main/MainViewSample.h" +#include "offlinevoice/VocassistView.h" +#include "offlinevoice/VocassistModel.h" #include "AppViewIDs.h" #include "NativeAbility.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistPresenter.cpp index 3a38a9e01..49596a48b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistPresenter.cpp @@ -5,9 +5,9 @@ * Create: 2022-01-18 */ #include "AppViewIDs.h" -#include "VocassistPresenter.h" -#include "PlayersModel.h" -#include "ui_service.h" +#include "offlinevoice/VocassistPresenter.h" +#include "player/PlayersModel.h" +#include "uiservice/ui_service.h" #include "NativeRegisterManager.h" namespace OHOS { @@ -122,7 +122,6 @@ bool VocassistPresenter::OnDrag(UIView& view, const DragEvent& event) void VocassistPresenter::OnResume(void) { - Presenter::OnResume(); ScreenTurnOn(-1); } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistView.cpp index 70f80a813..e0c2c71d6 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/offlinevoice/src/VocassistView.cpp @@ -9,11 +9,11 @@ #include "ohos_timer.h" #include "graphic_timer.h" #include "AppViewIDs.h" -#include "PlayersModel.h" -#include "CallerLogModel.h" -#include "VocassistModel.h" -#include "VocassistView.h" -#include "VocassistPresenter.h" +#include "player/PlayersModel.h" +#include "callerlog/CallerLogModel.h" +#include "offlinevoice/VocassistModel.h" +#include "offlinevoice/VocassistView.h" +#include "offlinevoice/VocassistPresenter.h" static constexpr uint16_t SWITCH_MAP_NUM = 16; static constexpr uint16_t ANI_X = 84; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneAudio.cpp b/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneAudio.cpp index 8b695c89a..665d1462f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneAudio.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneAudio.cpp @@ -4,8 +4,8 @@ * Create: 2021-09-22 */ -#include "PhoneAudio.h" -#include "PhoneService.h" +#include "phoneservice/PhoneAudio.h" +#include "phoneservice/PhoneService.h" #include #include #include "audio_manager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneService.cpp b/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneService.cpp index adaf6ce57..66b889773 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneService.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/phoneservice/src/PhoneService.cpp @@ -4,8 +4,8 @@ * Create: 2021-09-22 */ -#include "PhoneService.h" -#include "PhoneAudio.h" +#include "phoneservice/PhoneService.h" +#include "phoneservice/PhoneAudio.h" #include "securec.h" #include #include @@ -24,7 +24,7 @@ #include "service_id_define.h" #include "graphic_mutex.h" #include "samgr_lite.h" -#include "ui_service.h" +#include "uiservice/ui_service.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/src/BluetoothView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/player/src/BluetoothView.cpp index dfae52888..b05219ea4 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/src/BluetoothView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/player/src/BluetoothView.cpp @@ -3,11 +3,11 @@ * Description: bluetooth view 设置页面 * Create: 2021-09-5 */ -#include "BluetoothView.h" -#include "PlayersView.h" +#include "player/BluetoothView.h" +#include "player/PlayersView.h" #include "UiConfig.h" -#include "BluetoothEarPhoneView.h" -#include "PlayersPresenter.h" +#include "bluetooth/BluetoothEarPhoneView.h" +#include "player/PlayersPresenter.h" namespace OHOS { static BluetoothView *g_bluetoothView{nullptr}; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersCaseListAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersCaseListAdapter.cpp index b9e550257..06775205a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersCaseListAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersCaseListAdapter.cpp @@ -5,12 +5,12 @@ * Create: 2021-07-26 */ #include -#include "PlayersCaseListAdapter.h" +#include "player/PlayersCaseListAdapter.h" #include "gfx_utils/list.h" -#include "PlayersView.h" -#include "PlayersPresenter.h" +#include "player/PlayersView.h" +#include "player/PlayersPresenter.h" #include "wearable_log.h" -#include "PlayersModel.h" +#include "player/PlayersModel.h" namespace OHOS { constexpr uint16_t TESTCASE_BUTTON_HEIGHT = 64; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersModel.cpp index e454449be..410d07351 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersModel.cpp @@ -5,13 +5,13 @@ * Create: 2021-07-26 */ -#include "PlayersModel.h" +#include "player/PlayersModel.h" #include "thread_adapter.h" #include "UiConfig.h" #include "bts_avrcp_controller.h" #include "bts_avrcp_target.h" #include "bts_a2dp_source.h" -#include "BluetoothModel.h" +#include "bluetooth/BluetoothModel.h" namespace OHOS { @@ -107,7 +107,7 @@ int PlayersModel::PlayerStat() interrupt = {AUDIO_STREAM_MUSIC, sessionId, playerInterruptListener}; // 激活音频中断 5s超时 if (amIntance.ActivateAudioInterrupt(interrupt) == INTERRUPT_FAILED) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ActivateAudioInterrupt faild"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ActivateAudioInterrupt faild"); return OHOS_FAILURE; } isActivateAudioInterrupt = true; @@ -667,19 +667,22 @@ void PlayersModel::SetBTMusicPlay(avrcp_key_operation_t notification) } } // 蓝牙连接和本地的音乐播放 -void PlayersModel::ConnectBtAndLocalPlay(int32_t connCtState, int32_t connTgState, int32_t playerState) +int32_t PlayersModel::ConnectBtAndLocalPlay(int32_t connCtState, int32_t connTgState, int32_t playerState) { int ret; WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[PlayerModel] ConnectBtAndLocalPlay connCtState = %d connTgState = %d", connCtState, connTgState); avrcp_key_operation_t playNotification = AVRCP_KEY_PLAY; if (PlayersModel::GetInstance()->GetPlayerCtr() == nullptr) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[PlayersModel::ConnectBtAndLocalPlay] BT GetPlayerCtr is nullptr "); - return; + return -1; } if (connCtState == HFP_SCO_STATE_CONNECTED || connTgState == HFP_SCO_STATE_CONNECTED) { if (playerState == PlayerStates::PLAYER_PAUSED) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BTPLAYER_PAUSED play, 122."); - PlayersModel::GetInstance()->GetPlayerCtr()->Play(); // 暂停后的播放 + if (playerInterruptListener->IsInterruptedPaused()) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Paused by interrupt, dont resume"); + return -1; + } + ret = PlayersModel::GetInstance()->GetPlayerCtr()->Play(); // 暂停后的播放 PlayersModel::GetInstance()->SetBTMusicPlay(playNotification); } else { ret = PlayersModel::GetInstance()->PlayerStat(); // 蓝牙连接播放 @@ -691,7 +694,11 @@ void PlayersModel::ConnectBtAndLocalPlay(int32_t connCtState, int32_t connTgStat } else { if (playerState == PlayerStates::PLAYER_PAUSED) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PLAYER_PAUSED play, 122."); - PlayersModel::GetInstance()->GetPlayerCtr()->Play(); + if (playerInterruptListener->IsInterruptedPaused()) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Paused by interrupt, dont resume"); + return -1; + } + ret = PlayersModel::GetInstance()->GetPlayerCtr()->Play(); } else { ret = PlayersModel::GetInstance()->PlayerStat(); // 本地播放 if (ret != 0) { @@ -699,19 +706,20 @@ void PlayersModel::ConnectBtAndLocalPlay(int32_t connCtState, int32_t connTgStat } } } + return ret; } // 蓝牙连接和本地音乐的暂停 -void PlayersModel::ConnectBtAndLocalPause(int32_t connCtState, int32_t connTgState) +int32_t PlayersModel::ConnectBtAndLocalPause(int32_t connCtState, int32_t connTgState) { - int ret; + int32_t ret = 0; WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[PlayerModel] ConnectBtAndLocalPause"); avrcp_key_operation_t playNotification = AVRCP_KEY_PAUSE; if (connCtState == HFP_SCO_STATE_CONNECTED || connTgState == HFP_SCO_STATE_CONNECTED) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "state == BTUNSELECTED, 105."); if (PlayersModel::GetInstance()->GetPlayerCtr() == nullptr) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[PlayersModel::ConnectBtAndLocalPause] BT GetPlayerCtr is nullptr"); - return; + return -1; } ret = PlayersModel::GetInstance()->GetPlayerCtr()->Pause(); // 蓝牙连接暂停 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BT Music Pause, ret:%d", ret); @@ -721,6 +729,7 @@ void PlayersModel::ConnectBtAndLocalPause(int32_t connCtState, int32_t connTgSta ret = PlayersModel::GetInstance()->GetPlayerCtr()->Pause(); // 本地暂停 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Pause, ret:%d", ret); } + return ret; } void PlayersModel::ClearActivateAudioInterrupt() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersPresenter.cpp index e595ee337..8571cc9d3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersPresenter.cpp @@ -9,17 +9,17 @@ #include #include #include -#include "PlayersPresenter.h" +#include "player/PlayersPresenter.h" #include "wearable_log.h" #include "common/image_cache_manager.h" #include "UiConfig.h" #include "ui_resource_image.h" -#include "PlayersView.h" -#include "PlayersModel.h" -#include "BluetoothPresenter.h" +#include "player/PlayersView.h" +#include "player/PlayersModel.h" +#include "bluetooth/BluetoothPresenter.h" #include "graphic_service.h" -#include "PhoneService.h" -#include "MainViewSample.h" +#include "phoneservice/PhoneService.h" +#include "main/MainViewSample.h" #include "bts_avrcp_controller.h" #include "bts_avrcp_target.h" @@ -733,6 +733,11 @@ bool PlayerInterruptListener::IsPaused() return isPaused_; } +bool PlayerInterruptListener::IsInterruptedPaused() +{ + return isInterruptedPause_; +} + bool PlayerInterruptListener::IsDelayed() { return isDelayed_; @@ -864,10 +869,12 @@ void PlayerInterruptListener::OnInterrupt(int32_t type, int32_t hint) WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "[PlayerInterruptListener::] OnInterrupt go in, type %d, hint %d.", type, hint); if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_PAUSE) { + isInterruptedPause_ = true; PausePlayer(); } if (type == INTERRUPT_TYPE_END && hint == INTERRUPT_HINT_RESUME) { + isInterruptedPause_ = false; ResumePlayer(); } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersView.cpp index e318718aa..3c10323bf 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/player/src/PlayersView.cpp @@ -8,11 +8,11 @@ #include #include "common/image_cache_manager.h" #include "ui_resource_image.h" -#include "PlayersView.h" +#include "player/PlayersView.h" #include "UiConfig.h" -#include "PlayersModel.h" -#include "PlayersCaseListAdapter.h" -#include "MainViewSample.h" +#include "player/PlayersModel.h" +#include "player/PlayersCaseListAdapter.h" +#include "main/MainViewSample.h" namespace OHOS { static PlayersView* g_pPlayersView = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnModel.cpp new file mode 100644 index 000000000..2a78dc648 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnModel.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: QrcodeConnModel.cpp + * Author: + * Create: 2025-04-24 + */ + +#include "qrcode_conn/QrcodeConnModel.h" + +namespace OHOS { +QrcodeConnModel::QrcodeConnModel() {} + +QrcodeConnModel::~QrcodeConnModel() {} + +QrcodeConnModel &QrcodeConnModel::GetInstance() +{ + static QrcodeConnModel instance; + return instance; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnPresenter.cpp new file mode 100644 index 000000000..cf94db4d2 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnPresenter.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: QrcodeConnPresenter.cpp + * Author: + * Create: 2025-04-24 + */ +#include "qrcode_conn/QrcodeConnPresenter.h" +#include "uiservice/ui_service.h" +#include "NativeRegisterManager.h" + +namespace OHOS { + +REGIST_MENU(VIEW_QRCODE_CONN, QrcodeConnView, QrcodeConnPresenter, PNG_APPLIST_UI_SAMPLE_IMAGE, PNG_APPLIST_DEFAULT_IMG, + "二维码连接"); + +static QrcodeConnPresenter *g_QrcodeConnPresenter = nullptr; + +QrcodeConnPresenter::QrcodeConnPresenter() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnPresenter::QrcodeConnPresenter"); + g_QrcodeConnPresenter = this; +} + +QrcodeConnPresenter::~QrcodeConnPresenter() {} + +QrcodeConnPresenter *QrcodeConnPresenter::GetInstance() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnPresenter GetInstance"); + return g_QrcodeConnPresenter; +} + +bool QrcodeConnPresenter::OnDrag(UIView &view, const DragEvent &event) +{ + std::string id = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnPresenter::OnDrag [%s]", id.c_str()); + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + return false; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnView.cpp new file mode 100644 index 000000000..02efc59b7 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/qrcode_conn/src/QrcodeConnView.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: QrcodeConnView.cpp + * Author: + * Create: 2025-04-24 + */ + +#include "qrcode_conn/QrcodeConnView.h" +#include "qrcode_conn/QrcodeConnPresenter.h" +#include "qrcode_conn/QrcodeConnModel.h" +#include "bluetooth/BluetoothModel.h" +#include "wearable_log.h" + +namespace OHOS { +static const uint32_t QRCODE_POS_X = 76; +static const uint32_t QRCODE_POS_Y = 76; +static const uint32_t QRCODE_WIDTH = 282; +static const uint32_t QRCODE_HEIGHT = 282; +static const uint32_t PAD_SIZE = 10; + +static QrcodeConnView *g_pQrcodeConnView = nullptr; + +QrcodeConnView::QrcodeConnView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnView::QrcodeConnView"); + g_pQrcodeConnView = this; +} + +QrcodeConnView::~QrcodeConnView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnView::~QrcodeConnView"); + g_pQrcodeConnView = nullptr; +} + +QrcodeConnView *QrcodeConnView::GetInstance() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnView::GetInstance"); + return g_pQrcodeConnView; +} + +void QrcodeConnView::InitView() +{ + if (group_ == nullptr) { + group_ = new UIScrollView(); + group_->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + group_->SetStyle(STYLE_BACKGROUND_OPA, 0); + } + if (qrcode_ == nullptr) { + qrcode_ = new UIQrcode(); + } + qrcode_->SetPosition(QRCODE_POS_X, QRCODE_POS_Y, QRCODE_WIDTH, QRCODE_HEIGHT); + qrcode_->SetQrcodeInfo(BluetoothModel::GetInstance()->getWatchName()); + qrcode_->SetStyle(STYLE_PADDING_LEFT, PAD_SIZE); + qrcode_->SetStyle(STYLE_PADDING_RIGHT, PAD_SIZE); + qrcode_->SetStyle(STYLE_PADDING_TOP, PAD_SIZE); + qrcode_->SetStyle(STYLE_PADDING_BOTTOM, PAD_SIZE); + group_->Add(qrcode_); + UIView::OnDragListener *dragListener = (UIView::OnDragListener *)OHOS::QrcodeConnPresenter::GetInstance(); + group_->SetOnDragListener(dragListener); + // 更新 + group_->SetVisible(true); + AddViewToRootContainer(group_); + GetRootContainer()->Invalidate(); +} + +void QrcodeConnView::DeInit() +{ + if (group_ != nullptr) { + group_->RemoveAll(); + delete group_; + group_ = nullptr; + } + if (qrcode_ != nullptr) { + delete qrcode_; + qrcode_ = nullptr; + } +} + +void QrcodeConnView::OnStart() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnView::OnStart"); + InitView(); +} + +void QrcodeConnView::OnStop() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QrcodeConnView::OnStop"); + DeInit(); + return; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootDeviceView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootDeviceView.cpp index d2777a947..60dad05ba 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootDeviceView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootDeviceView.cpp @@ -4,10 +4,11 @@ * Create: 2022-04-28 */ -#include "RebootDeviceView.h" +#include "rebootdevice/RebootDeviceView.h" +#include "PageTransitionMgr.h" #include "wearable_log.h" #include "UiConfig.h" -#include "RebootPresenter.h" +#include "rebootdevice/RebootPresenter.h" namespace OHOS { static RebootDeviceView *g_pRebootDeviceView{nullptr}; @@ -98,7 +99,7 @@ UIViewGroup *RebootDeviceView::InitShowUpView(void) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "rebootDeviceDragListener GetInstance fail"); return nullptr; } - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly group->SetOnDragListener(rebootDeviceDragListener); } group->SetViewId(REBOOTDEVICE_VIEW); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootModel.cpp index d974582fd..889715b37 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootModel.cpp @@ -4,7 +4,7 @@ * Create: 2022-04-28 */ -#include "RebootModel.h" +#include "rebootdevice/RebootModel.h" #include "dfx_reboot.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootPresenter.cpp index c248e7ea7..223e102dd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootPresenter.cpp @@ -4,9 +4,9 @@ * Create: 2022-04-28 */ -#include "RebootPresenter.h" -#include "RebootView.h" -#include "RebootModel.h" +#include "rebootdevice/RebootPresenter.h" +#include "rebootdevice/RebootView.h" +#include "rebootdevice/RebootModel.h" #include "drag_event.h" #include "wearable_log.h" #include "NativeRegisterManager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootView.cpp index 5d8d43736..5c7956474 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/RebootView.cpp @@ -4,11 +4,12 @@ * Create: 2022-04-28 */ -#include "RebootView.h" -#include "RebootModel.h" +#include "rebootdevice/RebootView.h" +#include "PageTransitionMgr.h" +#include "rebootdevice/RebootModel.h" #include "wearable_log.h" #include "UiConfig.h" -#include "RebootPresenter.h" +#include "rebootdevice/RebootPresenter.h" namespace OHOS { static RebootView *g_pRebootView{nullptr}; @@ -47,6 +48,7 @@ RebootView *RebootView::GetInstance() void RebootView::OnStart() { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RebootView::~OnStart"); if (RebootModel::GetInstance()->GetSelectView() == REBOOT) { ChangeView(REBOOT_MAX, REBOOTVIEW); } else if (RebootModel::GetInstance()->GetSelectView() == REBOOTDEVICE) { @@ -161,7 +163,7 @@ UIViewGroup *RebootView::InitShowUpView(void) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "rebootDragListener GetInstance fail"); return nullptr; } - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly group->SetOnDragListener(rebootDragListener); } group->SetViewId(REBOOT_VIEW); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/ShutdownDeviceView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/ShutdownDeviceView.cpp index 24ef4ef1f..f2acf7ea8 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/ShutdownDeviceView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/rebootdevice/src/ShutdownDeviceView.cpp @@ -4,10 +4,11 @@ * Create: 2022-04-28 */ -#include "ShutdownDeviceView.h" +#include "rebootdevice/ShutdownDeviceView.h" +#include "PageTransitionMgr.h" #include "wearable_log.h" #include "UiConfig.h" -#include "RebootPresenter.h" +#include "rebootdevice/RebootPresenter.h" namespace OHOS { static ShutdownDeviceView *g_pShutdownDeviceView{nullptr}; @@ -98,7 +99,7 @@ UIViewGroup *ShutdownDeviceView::InitShowUpView(void) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "rebootDragListener GetInstance fail"); return nullptr; } - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly group->SetOnDragListener(rebootDragListener); } group->SetViewId(SHUTDOWNDEVICE_VIEW); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppPresenter.cpp new file mode 100644 index 000000000..63b9a668f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppPresenter.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2025 CompanyNameMagicTag. + * 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 "recent_app/RecentAppPresenter.h" +#include "recent_app/RecentAppView.h" +#include "RecentManager.h" +#include "NativeRegisterManager.h" +#include "msg_center_customer.h" + +namespace OHOS { + +REGIST_SLICE(VIEW_RECENT_APP, RecentAppView, RecentAppPresenter); + + RecentAppPresenter::RecentAppPresenter() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecentAppPresenter::RecentAppPresenter()"); + } + + RecentAppPresenter::~RecentAppPresenter() {} + + void RecentAppPresenter::OnResume() + { + if (view_ != nullptr) { + view_->LoadContent(); + } + } + + bool RecentAppPresenter::OnClick(UIView &view, const ClickEvent &event) + { + UIRollerView* roller = view_->GetRollerView(); + if (roller == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "roller is nullptr!"); + return false; + } + + UIViewGroup* currentItemGroup = roller->GetCurrentItem(); + if (currentItemGroup == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "currentItemGroup is nullptr!"); + return false; + } + + std::string itemName = roller->GetCurrentItemName(); + std::string prefix(itemName.begin(), itemName.begin() + RECENT_ITEM_PREFIX_LEN); + std::string name(itemName.begin() + RECENT_ITEM_PREFIX_LEN, itemName.end()); + + uint32_t sliceId = 0; + bool isNativeSlice = true; + if (prefix == RECENT_ITEM_NATIVE_PREFIX) { + sliceId = static_cast(std::stoul(name)); + } else { + isNativeSlice = false; + } + + const char* viewId = view.GetViewId(); + if (viewId != nullptr && strcmp(viewId, RECENT_APP_DELETE_BTN_ID) == 0) { + if (isNativeSlice) { + RecentManager::GetInstance()->RemoveRecentApp(sliceId); + } else { + RecentManager::GetInstance()->RemoveRecentApp(name.c_str()); + } + roller->RemoveItem(itemName); + return true; + } + + Point clickPoint = event.GetCurrentPos(); + Rect rect = currentItemGroup->GetChildrenHead()->GetRect(); + if (rect.IsContains(clickPoint)) { + if (isNativeSlice) { + NativeAbility::GetInstance().ChangeSlice(sliceId); + } else { +#ifdef JS_ENABLE + StartJsApp(const_cast(name.c_str())); +#endif + } + } + return true; + } +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppView.cpp new file mode 100644 index 000000000..792432059 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/recent_app/src/RecentAppView.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2025 CompanyNameMagicTag. + * 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 "recent_app/RecentAppView.h" +#include "wearable_log.h" +#include "common/image_cache_manager.h" +#include "common/screen.h" +#include "Slice.h" +#include "RecentManager.h" + +namespace OHOS { +static constexpr uint8_t DEFAULT_TEXT_SIZE = 30; +RecentAppView::RecentAppView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecentAppView::RecentAppView"); + loadingAnimCb_.SetRecentAppView(this); +} + +RecentAppView::~RecentAppView() +{ + if (roller_ != nullptr) { + delete roller_; + } + if (loadingAnim_ != nullptr) { + if (loadingAnim_->GetState() != Animator::STOP) { + loadingAnim_->Stop(); + } + delete loadingAnim_; + } + if (loadingLabel_ != nullptr) { + delete loadingLabel_; + } + if (noRecentAppLabel_ != nullptr) { + delete noRecentAppLabel_; + } + if (delBtn_ != nullptr) { + delete delBtn_; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecentAppView::~RecentAppView"); +} + +void RecentAppView::OnStart(void) +{ + UIViewGroup* container = GetRootContainer(); + + loadingLabel_ = new UILabel(); + if (loadingLabel_ == nullptr) { + return; + } + container->Add(loadingLabel_); + loadingLabel_->SetText("Loading..."); + loadingLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, DEFAULT_TEXT_SIZE); + loadingLabel_->Resize(300, 100); // 300, 100: size + loadingLabel_->LayoutCenterOfParent(); + loadingLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); +} + +void RecentAppView::LoadContent() +{ + if (viewiInitStatus_) { + return; + } + + UIViewGroup* rootContainer = GetRootContainer(); + if (!RecentManager::GetInstance()->IsUpdateCompleted()) { + loadingAnim_ = new Animator(&loadingAnimCb_, roller_, 0, true); + if (loadingAnim_ == nullptr) { + return; + } + loadingAnim_->Start(); + } else { + LoadRecentAppContent(); + } + viewiInitStatus_ = true; +} + +void RecentAppView::LoadingAnimCb::Callback(UIView* view) +{ + if (RecentManager::GetInstance()->IsUpdateCompleted()) { + recentAppView_->LoadRecentAppContent(); + } +} + +void RecentAppView::AddRecentAppToRoller() +{ + const List& recent = RecentManager::GetInstance()->GetRecentApps(); + ListNode* node = recent.Begin(); + std::string alignItemName = ""; + while (node != recent.End()) { + RecentAppInfo* appInfo = node->data_; + ImageInfo* imgInfo = appInfo->snapshot; + std::string name; + if (appInfo->isNativeSlice) { + name = RECENT_ITEM_NATIVE_PREFIX + std::to_string(appInfo->targetId & SLICE_MASK); + } else { + name = RECENT_ITEM_JS_PREFIX + appInfo->bundleName; + } + if (imgInfo->data != nullptr) { + roller_->AddItem(name, imgInfo); + } else { + std::string path(appInfo->snapshot->file, appInfo->snapshot->fileLen); + if (appInfo->snapshot->resId == 0) { + imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(path); + } else { + imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(appInfo->snapshot->resId, path); + } + + if (imgInfo == nullptr) { + GRAPHIC_LOGE("Load res failed: %s", path.c_str()); + node = node->next_; + continue; + } + roller_->AddItem(name, imgInfo); + } + node = node->next_; + if (alignItemName == "") { + alignItemName = name; + } + } + roller_->SetCurrentItem(alignItemName); +} + +void RecentAppView::InitRecentApps() +{ + if (delBtn_ == nullptr) { + delBtn_ = new UILabelButton(); + } + if (delBtn_ == nullptr) { + GRAPHIC_LOGE("new delBtn_ failed!"); + return; + } + + if (roller_ == nullptr) { + roller_ = new UIRollerView(false); + } + if (roller_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new UIRollerView fail"); + return; + } + + UIView::OnClickListener* onClickListener = dynamic_cast(presenter_); + + GetRootContainer()->Add(roller_); + roller_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + roller_->SetItemSize(250, 250); // 250: item size + roller_->SetThrowDrag(true); + roller_->SetItemPadding(80); // 80: item padding + roller_->SetCamDistance(380); // 380: Camera distance + roller_->SetCamY(48); // 48: camY + roller_->SetOnClickListener(onClickListener); + + GetRootContainer()->Add(delBtn_); + delBtn_->Resize(120, 50); // 120,50: width and height + delBtn_->LayoutCenterOfParent(0, 180); // 180: y offset + delBtn_->SetText("delete"); + delBtn_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, DEFAULT_TEXT_SIZE); + delBtn_->SetViewId(RECENT_APP_DELETE_BTN_ID); + delBtn_->SetOnClickListener(onClickListener); + + AddRecentAppToRoller(); +} + +void RecentAppView::LoadRecentAppContent() +{ + if (loadingAnim_ != nullptr) { + loadingAnim_->Stop(); + } + + if (loadingLabel_ != nullptr) { + loadingLabel_->SetVisible(false); + } + + uint32_t size = RecentManager::GetInstance()->GetCurrentSize(); + if (size == 0) { + if (noRecentAppLabel_ == nullptr) { + noRecentAppLabel_ = new UILabel(); + } + if (noRecentAppLabel_ != nullptr) { + GetRootContainer()->Add(noRecentAppLabel_); + noRecentAppLabel_->SetText("No Recent App."); + noRecentAppLabel_->Resize(300, 100); // 300, 100: size + noRecentAppLabel_->LayoutCenterOfParent(); + noRecentAppLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + } + return; + } + + InitRecentApps(); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreDefaultsView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreDefaultsView.cpp index 707c2b7b7..90e10c7b9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreDefaultsView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreDefaultsView.cpp @@ -4,7 +4,7 @@ * Create: 2024-08-12 */ -#include "RestoreDefaultsView.h" +#include "restoredefaults/RestoreDefaultsView.h" #include "components/ui_label.h" #include "wearable_log.h" #include "UiConfig.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestorePresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestorePresenter.cpp index 8fb3a7676..47a30ab48 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestorePresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestorePresenter.cpp @@ -4,9 +4,9 @@ * Create: 2024-08-12 */ -#include "RestoreDefaultsPresenter.h" -#include "RestoreDefaultsView.h" -#include "BluetoothModel.h" +#include "restoredefaults/RestoreDefaultsPresenter.h" +#include "restoredefaults/RestoreDefaultsView.h" +#include "bluetooth/BluetoothModel.h" #include "bts_br_gap.h" #include "drag_event.h" #include "cmsis_os.h" @@ -17,6 +17,10 @@ #ifdef SUPPORT_ALIPAY_SEC #include "alipay_feature.h" #endif +#include "adapter.h" +#include "bundlems_slite_client.h" +#include "abilityms_slite_client.h" +#include "stopwatch/StopwatchModel.h" namespace OHOS { @@ -56,6 +60,11 @@ bool RestoreDefaultsPresenter::OnClick(UIView &view, const ClickEvent &event) return true; } +static void UninstallCallbackFunc(const uint8_t resultCode, const void *resultMessage) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "UninstallCallbackFunc."); +} + void RestoreDefaultsPresenter::ConfirmOnClick() { bool res = bluetooth_factory_reset(); @@ -64,6 +73,53 @@ void RestoreDefaultsPresenter::ConfirmOnClick() (void)uapi_alipay_svr_reset(); WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_alipay_svr_reset process."); #endif + + BundleInfo *bundleInfos = nullptr; + int32_t count = 0; + int32_t ret = ERRCODE_FAIL; + + ret = OHOS::BundleMsClient::GetInstance().GetBundleInfos(0, &bundleInfos, &count); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetBundleInfos count = %d bundleRet = 0x%x", count, ret); + if (ret != 0) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Get bundleInfos Failed\n"); + }else { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "\n" + "----------------- AppList Start --------------------\n"); + for (int32_t i = 0; i < count; i++) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, + "App:%d-----------------\n" + "label: %s\n" + "bundleName: %s\n", + i+1, + bundleInfos[i].label, + bundleInfos[i].bundleName + ); + ElementName* topAbility = OHOS::AbilityMsClient::GetInstance().GetTopAbility(); + + if ((topAbility != nullptr) && (strcmp(topAbility->bundleName, bundleInfos[i].bundleName) == 0)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "js app is active, first need terminate"); + int token = 0; + OHOS::AbilityMsClient::GetInstance().TerminateAbility(token); + } + + InstallParam installParam = { .installLocation = 1, .keepData = false }; + OHOS::BundleMsClient::GetInstance().Uninstall(bundleInfos[i].bundleName, &installParam, UninstallCallbackFunc); + FreeElement(topAbility); + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "\n" + "----------------- AppList End -----------------------\n"); + } + if (bundleInfos != nullptr) { + for (uint8_t i = 0; i < count; i++) { + ClearBundleInfo(bundleInfos + i); + } + + if (bundleInfos != nullptr) { + AdapterFree(bundleInfos); + bundleInfos = nullptr; + } + } + StopwatchModel::GetInstance().ClearData(); uapi_system_reboot(SYSTEM_SOFT_REBOOT); return; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreSelectView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreSelectView.cpp index 9c04748d0..d51d35f10 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreSelectView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/restoredefaults/src/RestoreSelectView.cpp @@ -3,10 +3,11 @@ * Description: RestoreSelect View * Create: 2024-08-12 */ -#include "RestoreSelectView.h" +#include "restoredefaults/RestoreSelectView.h" +#include "PageTransitionMgr.h" #include "wearable_log.h" #include "UiConfig.h" -#include "RestoreDefaultsPresenter.h" +#include "restoredefaults/RestoreDefaultsPresenter.h" namespace OHOS { static RestoreSelectView *g_pRestoreSelectView { nullptr }; @@ -110,7 +111,7 @@ UIViewGroup *RestoreSelectView::InitShowUpView() WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "connectDragListener GetInstance fail"); return nullptr; } - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly group->SetOnDragListener(connectDragListener); } group->SetViewId(RESTORE_SELECT_VIEW); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/rtcservice/src/RtcService.cpp b/code/sdk/application/wearable/nativeapp/nativeui/rtcservice/src/RtcService.cpp index bd99bcdb1..5814fee69 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/rtcservice/src/RtcService.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/rtcservice/src/RtcService.cpp @@ -14,8 +14,8 @@ #include "securec.h" #include "broadcast_service.h" -#include "AlmmgrAlarmClockManage.h" -#include "RtcService.h" +#include "alarmclockmanage/AlmmgrAlarmClockManage.h" +#include "rtcservice/RtcService.h" #ifdef __cplusplus extern "C" { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/screennotify/src/ui_screennotify.cpp b/code/sdk/application/wearable/nativeapp/nativeui/screennotify/src/ui_screennotify.cpp index 89cef0ac3..991ee5938 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/screennotify/src/ui_screennotify.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/screennotify/src/ui_screennotify.cpp @@ -9,16 +9,22 @@ #include "power_display_service.h" #include "NativeAbility.h" #include "AppViewIDs.h" -#include "MainViewSample.h" -#include "ui_screennotify.h" +#include "main/MainViewSample.h" +#include "screennotify/ui_screennotify.h" #include "components/root_view.h" #include "notification_manager.h" -#include "DialBinTypesV2.h" +#include "main/DialBinTypesV2.h" +#include "hal_tick.h" +#include "abilityms_slite_client.h" #ifdef __cplusplus extern "C" { #endif static uint32_t g_back_to_home_interval = 5; +static uint32_t g_back_to_pre_slice = 5; +static uint32_t g_last_aod_on_stamp = 0; +static std::string g_pre_bundle_name = "com.huawei.launcher"; +static bool g_is_native = true; // 需要屏蔽掉的slice,ignore_slice_ids数组中的slice灭屏超时后不会调转到默认界面 uint16_t ignore_slice_ids[] = { @@ -59,25 +65,53 @@ static void ChangeToHomeView(void) } } -static void GuiEnterAod(bool entry) +static void EnterAod() { using namespace OHOS; - DisplayState newState = entry ? DisplayState::AOD : DisplayState::NORMAL; - - uint16_t current_slice_id = NativeAbility::GetInstance().GetCurSliceId(); - for (uint16_t i = 0; i < sizeof(ignore_slice_ids) / sizeof(uint16_t); i++) { - if (ignore_slice_ids[i] == current_slice_id) { - return; + g_last_aod_on_stamp = HALTick::GetInstance().GetTime(); + if (NativeAbility::GetInstance().GetNativeAbilityState() == STATE_ACTIVE) { + g_is_native = true; + } else { + ElementName *elementName = AbilityMsClient::GetInstance().GetTopAbility(); + if (elementName != nullptr) { + g_pre_bundle_name = elementName->bundleName; } + g_is_native = false; } - if (NativeAbility::GetInstance().GetNativeAbilityState() == STATE_ACTIVE) { - if (newState == DisplayState::AOD) { - NativeAbility::GetInstance().ChangeSlice(VIEW_AOD); - } else { - NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN_SAMPLE); + NativeAbility::GetInstance().ChangeSlice(VIEW_AOD); +} + +static void ExitAod() +{ + using namespace OHOS; + uint32_t aodDur = HALTick::GetInstance().GetElapseTime(g_last_aod_on_stamp) / 1000; // 1000: 1s = 1000ms + if (aodDur > g_back_to_pre_slice) { + uint16_t sliceId = NativeAbility::GetInstance().GetPreTargetId() & SLICE_MASK; + for (uint16_t i = 0; i < sizeof(ignore_slice_ids) / sizeof(uint16_t); i++) { + if (ignore_slice_ids[i] == sliceId) { + NativeAbility::GetInstance().ChangeSlice(sliceId); + return; + } } + NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN_SAMPLE); + } else { + if (!g_is_native) { + Want *want = new Want(); + memset_s(want, sizeof(Want), 0, sizeof(Want)); + ElementName startElement = {}; + startElement.abilityName = "default"; + startElement.bundleName = const_cast(g_pre_bundle_name.c_str()); + startElement.deviceId = nullptr; + SetWantElement(want, startElement); + StartAbility(want); + ClearWant(want); + delete want; + return; + } + uint32_t preId = NativeAbility::GetInstance().GetPreTargetId(); + NativeAbility::GetInstance().SwitchSlice(preId & SLICE_MASK, preId >> PAGE_OFFSET); } -}; +} void notify_screen_on_event(void) { @@ -103,12 +137,12 @@ void notify_screen_off_event(void) void notify_screen_aod_on_event(void) { - GuiEnterAod(true); + EnterAod(); } void notify_screen_aod_off_event(void) { - GuiEnterAod(false); + ExitAod(); } void set_back_to_home_interval(uint32_t time_sec) @@ -121,6 +155,16 @@ uint32_t get_back_to_home_interval(void) return g_back_to_home_interval; } +void set_back_to_pre_slice_interval(uint32_t time_sec) +{ + g_back_to_pre_slice = time_sec; +} + +uint32_t get_back_to_pre_slice_interval(void) +{ + return g_back_to_pre_slice; +} + void registerNotifyScreenStatus(ScreenStatusNotifyCallback callback) { if (callback != nullptr) { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/screensetting/src/ScreenModels.cpp b/code/sdk/application/wearable/nativeapp/nativeui/screensetting/src/ScreenModels.cpp index 5720b8336..6be2328bd 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/screensetting/src/ScreenModels.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/screensetting/src/ScreenModels.cpp @@ -13,7 +13,7 @@ #include #include "kvstore_env.h" #include "kv_store.h" -#include "ScreenModels.h" +#include "screensetting/ScreenModels.h" #include "common/image_cache_manager.h" #include "UiConfig.h" #include "ui_resource_image.h" @@ -38,7 +38,7 @@ void ScreenModels::InitKvStorage(void) { #if !defined(_WIN32) #ifndef XTS_SUPPORT - int ret = UtilsSetEnv("/user/system"); + int ret = UtilsSetEnv("/user"); WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "UtilsSetEnv /user ret = %d", ret); #endif #else diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardAdapter.cpp index badbc10dc..5d15eb63e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardAdapter.cpp @@ -5,7 +5,7 @@ * Create: 2021-09-18 */ -#include "SetCardAdapter.h" +#include "set_card/SetCardAdapter.h" namespace OHOS { SetCardAdapter::SetCardAdapter() {} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardDeleteView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardDeleteView.cpp index c916f4c7f..f37a50d36 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardDeleteView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardDeleteView.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "SetCardDeleteView.h" +#include "set_card/SetCardDeleteView.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardItem.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardItem.cpp index 4bdd7ba98..7d08205d9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardItem.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardItem.cpp @@ -1,5 +1,5 @@ -#include "SetCardItem.h" -#include "SetCardPresenter.h" +#include "set_card/SetCardItem.h" +#include "set_card/SetCardPresenter.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardModel.cpp index 32ca2b547..df4d971e3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardModel.cpp @@ -5,8 +5,8 @@ * Create: 2021-11-23 */ -#include "SetCardModel.h" -#include "MainModel.h" +#include "set_card/SetCardModel.h" +#include "main/MainModel.h" #include "kv_store.h" #include "securec.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardNoCardView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardNoCardView.cpp index eadcec935..f09315818 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardNoCardView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardNoCardView.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "SetCardNoCardView.h" +#include "set_card/SetCardNoCardView.h" #include "wearable_log.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardPresenter.cpp index 1012057c9..0a93f42d8 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardPresenter.cpp @@ -5,9 +5,9 @@ * Create: 2021-11-23 */ -#include "SetCardView.h" -#include "SetCardModel.h" -#include "SetCardPresenter.h" +#include "set_card/SetCardView.h" +#include "set_card/SetCardModel.h" +#include "set_card/SetCardPresenter.h" #include "hal_tick.h" #include "NativeRegisterManager.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardView.cpp index c375c864c..b9d31c386 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_card/src/SetCardView.cpp @@ -6,8 +6,8 @@ */ #include -#include "SetCardView.h" -#include "SetCardPresenter.h" +#include "set_card/SetCardView.h" +#include "set_card/SetCardPresenter.h" namespace OHOS { SetCardView::SetCardView():contentList_(UIList::HORIZONTAL) diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopPresenter.h deleted file mode 100644 index 93c05876e..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopPresenter.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SetDesktopPresenter.h - * Author: - * Create: 2021-11-23 - */ - -#ifndef SET_DESKTOP_PRESENTER_H -#define SET_DESKTOP_PRESENTER_H - -#include "Presenter.h" -#include "components/ui_view.h" - -namespace OHOS { -static const char *SET_DESKTOP_LIST = "setdesktopList"; -static const char *SET_DESKTOP_HEXAGONS = "setdesktopHexagons"; -static const char *SET_DESKTOP_FOOTBALL = "setdesktopFootball"; -static const char *SET_DESKTOP_WATERFALL = "setdesktopWaterfall"; - -class SetDesktopView; -class SetDesktopModel; -class SetDesktopPresenter : public Presenter, - public UIView::OnClickListener, - public UIView::OnDragListener { -public: - SetDesktopPresenter(); - ~SetDesktopPresenter() override; - bool OnClick(UIView &view, const ClickEvent &event) override; - bool OnDrag(UIView& view, const DragEvent& event) override; - uint8_t GetCurrentStyle(void); -private: -}; -} - -#endif // SET_DESKTOP_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopView.h b/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopView.h deleted file mode 100644 index 8de637987..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/include/SetDesktopView.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SetDesktopView.h - * Author: - * Create: 2021-11-23 - */ - -#ifndef SET_DESKTOP_VIEW_H -#define SET_DESKTOP_VIEW_H - -#include "View.h" -#include "components/ui_scroll_view.h" -#include "components/ui_view_group.h" -#include "components/ui_label.h" -#include "components/ui_image_view.h" -#include "components/ui_toggle_button.h" -#include "ChangeSliceListener.h" -#include "UiConfig.h" - -namespace OHOS { -class SetDesktopPresenter; - -class SetDesktopView : public View { -public: - SetDesktopView(); - ~SetDesktopView() override; - - static SetDesktopView *GetInstance() - { - static SetDesktopView instance; - return &instance; - } - - void OnStart() override; - void UpdateSelectedStyle(uint8_t selectedStyle); - uint8_t GetCurrentSelectedStyle(void); - -private: - void InitFootballItem(); - void InitWaterfallItem(); - UIScrollView *scrollview{nullptr}; - UILabel titleText; - UIToggleButton hexagonsBtn; - UIToggleButton listBtn; - UIToggleButton footballBtn_; - UIToggleButton waterfallBtn_; - UIImageView hexagonsImage; - UIImageView listImage; - UIImageView footballImage_; - UIImageView waterfallImage_; - UILabel listText; - UILabel hexagonsText; - UILabel footballText_; - UILabel waterfallText_; -}; -} -#endif // SET_DESKTOP_VIEW_H diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopPresenter.cpp deleted file mode 100644 index 68b000b03..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopPresenter.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SettingPresenter.cpp - * Author: - * Create: 2021-11-23 - */ - -#include "SetDesktopView.h" -#include "SetDesktopModel.h" -#include "SetDesktopPresenter.h" -#include "NativeRegisterManager.h" - -namespace OHOS { - -REGIST_SLICE(VIEW_SET_DESKTOP, SetDesktopView, SetDesktopPresenter); - - SetDesktopPresenter::SetDesktopPresenter() - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDesktopPresenter::SetDesktopPresenter"); - } - - SetDesktopPresenter::~SetDesktopPresenter() {} - - bool SetDesktopPresenter::OnDrag(UIView& view, const DragEvent& event) - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDesktopPresenter::OnDrag"); - UNUSED(view); - if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && - (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::OnDrag ChangeSlice"); - uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId(); - NativeAbility::GetInstance().ChangeSlice(preSlice); - } - return false; - } - - bool SetDesktopPresenter::OnClick(UIView &view, const ClickEvent &event) - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDesktopPresenter::OnClick"); - if (strcmp(view.GetViewId(), SET_DESKTOP_HEXAGONS) == 0) { - SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::HEXAGONS_STYLE); - } else if (strcmp(view.GetViewId(), SET_DESKTOP_LIST) == 0) { - SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::APPLIST_STYLE); - } else if (strcmp(view.GetViewId(), SET_DESKTOP_FOOTBALL) == 0) { - SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::FOOTBALL_STYLE); - } else if (strcmp(view.GetViewId(), SET_DESKTOP_WATERFALL) == 0) { - SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::WATERFALL_STYLE); - } - uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId(); - NativeAbility::GetInstance().ChangeSlice(preSlice); - return true; - } - - uint8_t SetDesktopPresenter::GetCurrentStyle(void) - { - DesktopStyle style = SetDesktopModel::GetInstance().GetDesktopStyle(); - if (style == HEXAGONS_STYLE) { - return 1; // 1: hexagons style enum index - } else if (style == FOOTBALL_STYLE) { - return 2; // 2: football style enum index - } else if (style == WATERFALL_STYLE) { - return 3; // 3: waterfall style enum index - } - return 0; - } -} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialModel.cpp index 974954c3a..8f15cfcd0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialModel.cpp @@ -5,12 +5,12 @@ * Create: 2021-11-23 */ #include -#include "MainModel.h" -#include "SetDialModel.h" +#include "main/MainModel.h" +#include "set_dial/SetDialModel.h" #include "kv_store.h" #include "securec.h" #include "dirent.h" -#include "DialBinParser.h" +#include "main/DialBinParser.h" #include "wearable_log.h" namespace OHOS { @@ -108,7 +108,7 @@ namespace OHOS { return -1; } DialPreviewInfo preInfo{0}; - bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(fp, &preInfo); + bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(dialFullName, fp, &preInfo); if (!ret) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetDialPreviewInfo %s fail", dialFullName.c_str()); diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialPresenter.cpp index f769b0f9d..e33267320 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialPresenter.cpp @@ -5,14 +5,17 @@ * Create: 2021-11-23 */ -#include "SetDialView.h" -#include "SetDialModel.h" -#include "SetDialPresenter.h" +#include "set_dial/SetDialView.h" +#include "set_dial/SetDialModel.h" +#include "set_dial/SetDialPresenter.h" #include "hal_tick.h" #include "NativeRegisterManager.h" namespace OHOS { +namespace { +SetDialPresenter *g_presenter = nullptr; +} // anonymous namespace REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter); @@ -22,10 +25,25 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter); model = &SetDialModel::GetInstance(); model->LoadAllDial(); ResetTickTimer(); + g_presenter = this; + specificSetting.dialFlag = 0; + specificSetting.dialId = 0; } SetDialPresenter::~SetDialPresenter() { + g_presenter = nullptr; + } + + SetDialPresenter *SetDialPresenter::GetCurrentInstance() + { + return g_presenter; + } + + void SetDialPresenter::SpecifyDialSetting(const DialSetting &setting) + { + isSpecific = true; + specificSetting = setting; } void SetDialPresenter::OnClickAction(void) @@ -79,6 +97,10 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter); void SetDialPresenter::OnStop() { model->ClearDialInfo(); + if (isSpecific) { + MainModel::GetInstance().GetDialSetting() = specificSetting; + MainModel::GetInstance().AddDialSetting(specificSetting); + } } void SetDialPresenter::ResetTickTimer(void) diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialView.cpp index 15bba5fd5..a932d18be 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_dial/src/SetDialView.cpp @@ -6,9 +6,9 @@ */ #include -#include "SetDialView.h" -#include "SetDialPresenter.h" -#include "SetDialStyleModel.h" +#include "set_dial/SetDialView.h" +#include "set_dial/SetDialPresenter.h" +#include "set_dial_style/SetDialStyleModel.h" namespace OHOS { SetDialView::SetDialView() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleModel.cpp index 81d833aef..3126804b3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleModel.cpp @@ -5,7 +5,7 @@ * Create: 2024-06-06 */ -#include "SetDialStyleModel.h" +#include "set_dial_style/SetDialStyleModel.h" #include "kv_store.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStylePresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStylePresenter.cpp index 6980d5f48..8c85a6a34 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStylePresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStylePresenter.cpp @@ -5,9 +5,9 @@ * Create: 2024-06-06 */ -#include "SetDialStyleView.h" -#include "SetDialStyleModel.h" -#include "SetDialStylePresenter.h" +#include "set_dial_style/SetDialStyleView.h" +#include "set_dial_style/SetDialStyleModel.h" +#include "set_dial_style/SetDialStylePresenter.h" #include "NativeRegisterManager.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleView.cpp index 7d786aab4..85d72a819 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_dial_style/src/SetDialStyleView.cpp @@ -5,10 +5,11 @@ * Create: 2024-06-06 */ -#include "SetDialStyleView.h" -#include "SetDialStyleModel.h" -#include "SetDialStylePresenter.h" -#include "MainModel.h" +#include "set_dial_style/SetDialStyleView.h" +#include "PageTransitionMgr.h" +#include "set_dial_style/SetDialStyleModel.h" +#include "set_dial_style/SetDialStylePresenter.h" +#include "main/MainModel.h" namespace OHOS { SetDialStyleView::SetDialStyleView() @@ -23,7 +24,7 @@ void SetDialStyleView::OnStart() { GetRootContainer()->SetDraggable(true); GetRootContainer()->SetTouchable(true); - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + if (!PageTransitionMgr::GetInstance().CanSlideBack()) { // support default slide back firstly GetRootContainer()->SetOnDragListener(presenter_); } const int16_t BTN_HEIGHT = 55; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAModel.cpp new file mode 100644 index 000000000..60715c5f4 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAModel.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: ota local update + * Author: wangle + * Create: 2025-5-6 + */ +#include "set_ota/OTACommon.h" +#include "set_ota/OTAModel.h" +#include "set_ota/OTAPresenter.h" +#include "tcxo.h" +#include "upg.h" +#include "upg_porting.h" +#include "upg_definitions.h" +#include "upg_common_porting.h" +#include "wearable_log.h" + + +namespace OHOS { +OTAModel::OTAModel() +{ + isIdel = true; + wait.wait = nullptr; + if (osal_wait_init(&wait) != 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ota osal_wait_init error"); + return; + } + task = osal_kthread_create(&OTAModel::OSALKthreadCallback, this, "ota_model", MODLE_THREAD_STACK_SIZE); + if (task == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ota osal_wait_init error"); + osal_wait_destroy(&wait); + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "model init succ"); +} +OTAModel::~OTAModel() +{ + if (task != nullptr) { + osal_kthread_destroy(task, 0); + } + if (wait.wait != nullptr) { + osal_wait_destroy(&wait); + } +} + +int OTAModel::WaitCondition(const void *data) +{ + OTAModel *model = (OTAModel *)data; + return model->isIdel ? 0 : 1; // 不空闲说明有任务 +} + +int OTAModel::OSALKthreadCallback(void *data) +{ + OTAModel *model = (OTAModel *)data; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "model thread... callback"); + while (true) { // osal_kthread_destroy规定 线程销毁前必须一直存在 + osal_wait_interruptible(&model->wait, &OTAModel::WaitCondition, data); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "model thread... wait done"); + model->SwitchTask(); + } + return 0; +} +bool OTAModel::ModelRunTask(TaskType tasktype, void *taskdata) +{ + if (!isIdel) + return false; + type = tasktype; + data = taskdata; + isIdel = false; + osal_wait_wakeup(&wait); + return true; +} +void OTAModel::SwitchTask() +{ + switch (type) { + case TaskType::UpdateInfo: + UpdateInfo(data); + isIdel = true; + break; + case TaskType::LocalUpdate: + LocalUpdate(data); + isIdel = true; + break; + default: + break; // 不处理 + } +} + +void OTAModel::UpdateInfo(void *data) +{ + uint32_t total_size = 0; + do { + FILE *fp = fopen(upg_get_pkg_file_path(), "rb"); + if (fp == nullptr) { + break; + } + fseek(fp, 0L, SEEK_END); + total_size = ftell(fp); + fclose(fp); + } while (false); + presenter_->SetPackageInfo(upg_get_pkg_file_path(), total_size); +} +void OTAModel::LocalUpdate(void *data) +{ + upg_prepare_info_t info{((LocalUpdateData *)data)->fileSize}; + + // update 准备工作 + presenter_->SetUpdateProgress("upg_prepare", LOCAL_UPDATE_PROGRESS_5); + errcode_t ret = uapi_upg_prepare(&info); + if (ret != ERRCODE_SUCC) { + presenter_->SetErrorMessage("uapi_upg_prepare error"); + return; + } + + // update 申请升级 + presenter_->SetUpdateProgress("upg_request_upgrade", LOCAL_UPDATE_PROGRESS_25); + ret = uapi_upg_request_upgrade(false); + if (ret != ERRCODE_SUCC) { + presenter_->SetErrorMessage("uapi_upg_request_upgrade error"); + return; + } + // 备份 + presenter_->SetUpdateProgress("upg_image_backups", LOCAL_UPDATE_PROGRESS_40); + ret = upg_image_backups_update(); + if (ret != ERRCODE_SUCC) { + presenter_->SetErrorMessage("upg_image_backups_update error"); + return; + } + + // update 开始升级 + presenter_->SetUpdateProgress("upg_start", LOCAL_UPDATE_PROGRESS_50); + ret = uapi_upg_start(); + if (ret != ERRCODE_SUCC) { + presenter_->SetErrorMessage("uapi_upg_start error"); + return; + } + presenter_->SetUpdateProgress("reboot", LOCAL_UPDATE_PROGRESS_100); + DelayRebootFor5S(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "update"); +} +void OTAModel::DelayRebootFor5S() +{ + char temp[60] = ""; + for (int i = 5; i > 0; i--) { + sprintf_s(temp, sizeof(temp), "%ds后系统将进行重启\r\n完成后续升级操作", i); + presenter_->SetMessage(temp); + osal_msleep(SLEEP_TIME_S); + } + upg_reboot(); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAPresenter.cpp new file mode 100644 index 000000000..a77f53fc4 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAPresenter.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: ota local update + * Author: wangle + * Create: 2025-5-6 + */ +#include "AppViewIDs.h" +#include "NativeRegisterManager.h" +#include "gfx_utils/graphic_math.h" +#include "set_ota/OTACommon.h" +#include "set_ota/OTAView.h" +#include "set_ota/OTAPresenter.h" +#include "set_ota/OTAModel.h" +#include "main/HealthModel.h" +#include "uiservice/ui_service.h" + +namespace OHOS { + +REGIST_SLICE(VIEW_SET_OTA, OTAView, OTAPresenter); + +void OTAPresenter::OnStart() +{ + if (model_ == nullptr) { + Attach(new OTAModel); + } + if (model_ != nullptr) { + model_->Attach(this); + } + view_->SetUpdateDisable(); + view_->SetMessage("正在获取升级文件信息..."); + view_->SetProgress(0); + model_->ModelRunTask(TaskType::UpdateInfo, nullptr); +} +void OTAPresenter::OnStop() +{ + if (model_ != nullptr) { + delete model_; + model_ = nullptr; + } +} +bool OTAPresenter::OnClick(UIView &view, const ClickEvent &event) +{ + if (strcmp(view.GetViewId(), "update") == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTA OnClick... update"); + // 调用model升级方法 + model_->ModelRunTask(TaskType::LocalUpdate, nullptr); + view_->SetMessage("正在升级..."); + view_->SetProgress(0); + view_->SetUpdateDisable(); + updateEnable = true; // 升级中, 禁止右滑退出 + SaveSystemScreen(); // 升级中, 设置屏幕常亮 + } + return true; +} +bool OTAPresenter::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTA OnDrag..."); + if (updateEnable && event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) { + int16_t deltaX = event.GetDeltaX(); + int16_t deltaY = event.GetDeltaY(); + if (MATH_ABS(deltaX) >= MATH_ABS(deltaY) && MATH_ABS(deltaX) > SLIDING_LENGTH) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST, TransitionType::TRANSITION_ZOOM); + } + } + return true; +} + +void OTAPresenter::SetPackageInfo(const char *filePath, uint32_t fileSize) +{ + char tempBuffer[60] = ""; + updateFilePath = filePath; + updateFileSize = fileSize; + updateEnable = true; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTA SetPackageInfo"); + if (fileSize != 0) { + double tempSizeMB = 1.0 * updateFileSize / 1024 / 1024; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "calc"); + sprintf_s(tempBuffer, sizeof(tempBuffer), "升级文件:%s\r\n大小:%.2lfMB", filePath, tempSizeMB); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sprintf"); + view_->SetUpdateEnable(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "View setEnable"); + view_->SetMessage(tempBuffer); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "view SetMessage"); + } else { + sprintf_s(tempBuffer, sizeof(tempBuffer), "升级文件:%s\r\n不存在或已损坏", filePath); + view_->SetUpdateDisable(); + view_->SetMessage(tempBuffer); + } +} + +void OTAPresenter::SetUpdateProgress(const char *message, uint8_t progress) +{ + char tempBuffer[60] = ""; + sprintf_s(tempBuffer, sizeof(tempBuffer), "正在升级...%u%%...\r\n%s", progress, message); + view_->SetMessage(tempBuffer); + view_->SetProgress(progress); +} +void OTAPresenter::SetErrorMessage(const char *message) +{ + char tempBuffer[60] = ""; + sprintf_s(tempBuffer, sizeof(tempBuffer), "升级失败...\r\n%s", message); + view_->SetMessage(tempBuffer); + view_->SetUpdateEnable(); // 升级失败后, 允许重新升级 + updateEnable = false; // 升级失败后, 允许右滑退出 + BackSystemScreen(); // 升级失败后, 回滚屏幕亮屏设置 +} +void OTAPresenter::SetMessage(const char *message) +{ + view_->SetMessage(message); +} +void OTAPresenter::SaveSystemScreen() +{ + briScrStatus = HealthModel::GetInstance()->GetBriScrStatus(); + if (briScrStatus == 0) { // 若系统常亮未打开则打开系统常亮 + ScreenOffEnable(0); + HealthModel::GetInstance()->UpdateBriScrStatus(1); + } +} +void OTAPresenter::BackSystemScreen() +{ + if (briScrStatus == 0) { // 若系统原本未处于常亮则恢复 + ScreenOffEnable(1); + HealthModel::GetInstance()->UpdateBriScrStatus(0); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAView.cpp new file mode 100644 index 000000000..1161894fa --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/set_ota/src/OTAView.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: ota local update + * Author: wangle + * Create: 2025-5-6 + */ +#include "UiConfig.h" +#include "set_ota/OTACommon.h" +#include "set_ota/OTAView.h" +#include "set_ota/OTAPresenter.h" +#include "wearable_log.h" + +namespace OHOS { +void OTAView::OnStart() +{ + InitMessageCtrl(); + InitProgressCtrl(); + InitUpdateCtrl(); + AddCtrlToView(); +} +void OTAView::InitMessageCtrl() +{ + if (message == nullptr) { + message = new UILabel(); + } + message->SetPosition(VIEW_MESSAGE_X, VIEW_MESSAGE_Y); + message->Resize(VIEW_MESSAGE_W, VIEW_MESSAGE_H); + message->SetViewId("message"); + message->SetStyle(STYLE_BACKGROUND_OPA, 0xff); + message->SetStyle(STYLE_TEXT_FONT, VIEW_MESSAGE_FONT); + message->SetStyle(STYLE_LINE_SPACE, 0); + + message->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + message->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + message->SetRollSpeed(0); + message->SetFont(DEFAULT_VECTOR_FONT_FILENAME, VIEW_MESSAGE_FONT); +} +void OTAView::InitProgressCtrl() +{ + if (progress == nullptr) { + progress = new UIBoxProgress(); + } + progress->SetViewId("progress"); + progress->SetDirection(UIBoxProgress::Direction::DIR_LEFT_TO_RIGHT); + progress->SetPosition(VIEW_PROGRESS_X, VIEW_PROGRESS_Y, VIEW_PROGRESS_W, VIEW_PROGRESS_H); + progress->SetValue(0); + progress->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + progress->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + progress->SetStyle(STYLE_BORDER_COLOR, Color::Yellow().full); + progress->SetStep(1); + progress->EnableBackground(true); +} +void OTAView::InitUpdateCtrl() +{ + if (update == nullptr) { + update = new UILabelButton(); + } + update->SetPosition(VIEW_UPDATE_X, VIEW_UPDATE_Y); + update->Resize(VIEW_UPDATE_W, VIEW_UPDATE_H); + update->SetViewId("update"); + update->SetText("升级"); + update->SetFont(DEFAULT_VECTOR_FONT_FILENAME, VIEW_UPDATE_FONT); + update->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + update->SetOnClickListener(presenter_); +} +void OTAView::AddCtrlToView() +{ + if (GetRootContainer() == nullptr) + return; + message->SetVisible(true); + progress->SetVisible(true); + update->SetVisible(true); + GetRootContainer()->Add(message); + GetRootContainer()->Add(progress); + GetRootContainer()->Add(update); + GetRootContainer()->SetTouchable(true); // 添加滑动响应 + GetRootContainer()->SetDraggable(true); + GetRootContainer()->SetOnDragListener(presenter_); +} +void OTAView::OnStop() +{ + DeInitMessageCtrl(); + DeInitProgressCtrl(); + DeInitUpdateCtrl(); +} +void OTAView::DeInitMessageCtrl() +{ + if (message != nullptr) { + delete message; + message = nullptr; + } +} +void OTAView::DeInitProgressCtrl() +{ + if (progress != nullptr) { + delete progress; + progress = nullptr; + } +} +void OTAView::DeInitUpdateCtrl() +{ + if (update != nullptr) { + delete update; + update = nullptr; + } +} +void OTAView::SetUpdateEnable() +{ + if (update == nullptr) + return; + update->Enable(); +} +void OTAView::SetUpdateDisable() +{ + if (update == nullptr) + return; + update->Disable(); +} + +void OTAView::SetMessage(const char *msg) +{ + if (message == nullptr) + return; + message->SetText(msg); +} +void OTAView::SetProgress(uint8_t progressNum) +{ + if (progress == nullptr) + return; + progress->SetValue(progressNum); +} + +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingPresenter.h b/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingPresenter.h deleted file mode 100644 index 6edba6ab1..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingPresenter.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SettingPresenter.h - * Author: - * Create: 2021-11-23 - */ - -#ifndef SETTING_PRESENTER_H -#define SETTING_PRESENTER_H - -#include "Presenter.h" -#include "components/ui_view.h" -#include "SettingAdapter.h" - -namespace OHOS { -class SettingView; -class SettingModel; -class SettingAdapter; -class SettingPresenter : public Presenter, - public UIView::OnClickListener, - public UIView::OnDragListener { -public: - SettingPresenter(); - ~SettingPresenter() override; - - void OnStart() override; - bool OnClick(UIView &view, const ClickEvent &event) override; - bool OnDrag(UIView& view, const DragEvent& event) override; -private: - SettingModel *settingModel; -}; -} - -#endif // SETTING_PRESENTER_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingView.h b/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingView.h deleted file mode 100644 index f8936c6db..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/include/SettingView.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SettingView.h - * Author: - * Create: 2021-11-23 - */ - -#ifndef SETTING_VIEW_H -#define SETTING_VIEW_H - -#include "View.h" -#include "components/root_view.h" -#include "components/ui_view_group.h" -#include "components/ui_scroll_view.h" -#include "components/ui_label.h" -#include "components/ui_list.h" -#include "SettingAdapter.h" -#include "ChangeSliceListener.h" -namespace OHOS { -class SettingPresenter; -class SettingView : public View { -public: - SettingView(); - ~SettingView() override; - - void OnStart() override; - void RefreshSettingsList(const SettingItem* item, uint8_t count); -private: - SettingAdapter *listAdapter{nullptr}; - UIScrollView *scrollView{nullptr}; - UIList *contentList{nullptr}; - UILabel *title{nullptr}; -}; -} -#endif // SETTING_VIEW_H \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SetDesktopModel.cpp similarity index 83% rename from code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopModel.cpp rename to code/sdk/application/wearable/nativeapp/nativeui/settings/src/SetDesktopModel.cpp index 25c23a40e..f18610db0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SetDesktopModel.cpp @@ -1,19 +1,16 @@ /* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SettingModel.cpp - * Author: - * Create: 2021-11-23 + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SetDesktopModel + * Author: Hisi Graphic Team + * Created: 2025-4 */ -#include "SetDesktopModel.h" +#include "settings/SetDesktopModel.h" #include "kv_store.h" #include "securec.h" namespace OHOS { static const int STYLE_VALUE_LEN = 32; - SetDesktopModel::SetDesktopModel() {} - - SetDesktopModel::~SetDesktopModel() {} SetDesktopModel &SetDesktopModel::GetInstance() { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingAdapter.cpp index 3ffb62c85..535c672ce 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingAdapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingAdapter.cpp @@ -5,7 +5,7 @@ * Create: 2021-11-23 */ -#include "SettingAdapter.h" +#include "settings/SettingAdapter.h" namespace OHOS { SettingAdapter::SettingAdapter() {} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingDesktopPage.cpp similarity index 55% rename from code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopView.cpp rename to code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingDesktopPage.cpp index 2a661577c..0c1c2cd3d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/set_desktop/src/SetDesktopView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingDesktopPage.cpp @@ -1,24 +1,35 @@ /* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SetDesktopView.cpp - * Author: - * Create: 2021-11-23 + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingDesktopPage + * Author: Hisi Graphic Team + * Created: 2025-4 */ +#include "settings/SettingDesktopPage.h" #include -#include "SetDesktopView.h" -#include "SetDesktopPresenter.h" #include "components/ui_scroll_view_nested.h" +#include "common/screen.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "PageTransitionMgr.h" +#include "SlicePageFactory.h" +#include "settings/SettingView.h" namespace OHOS { -SetDesktopView::SetDesktopView() +static const char *SET_DESKTOP_LIST = "setdesktopList"; +static const char *SET_DESKTOP_HEXAGONS = "setdesktopHexagons"; +static const char *SET_DESKTOP_FOOTBALL = "setdesktopFootball"; +static const char *SET_DESKTOP_WATERFALL = "setdesktopWaterfall"; + +REGIST_SLICE_PAGE(VIEW_SETTING, SETTING_PAGES::SETTING_DESKTOP_PAGE, SettingDesktopPage, false); +SettingDesktopPage::SettingDesktopPage() { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDesktopView::SetDesktopView"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingDesktopPage::SettingDesktopPage"); } -SetDesktopView::~SetDesktopView() +SettingDesktopPage::~SettingDesktopPage() { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDesktopView::~SetDesktopView"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingDesktopPage::~SettingDesktopPage"); if (scrollview != nullptr) { scrollview->RemoveAll(); delete scrollview; @@ -26,13 +37,11 @@ SetDesktopView::~SetDesktopView() } } -void SetDesktopView::OnStart() +void SettingDesktopPage::OnStart(void *data) { - GetRootContainer()->SetDraggable(true); - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly - GetRootContainer()->SetOnDragListener(presenter_); + if (GetBackDragListener() == nullptr) { // support default slide back firstly + GetSlicePageContainer()->SetOnDragListener(this); } - GetRootContainer()->SetTouchable(true); scrollview = new UIScrollViewNested(UIAbstractScroll::HORIZONTAL); UIScrollViewNested *nested = dynamic_cast(scrollview); @@ -40,14 +49,14 @@ void SetDesktopView::OnStart() nested->SetBoundaryIntercept(DragEvent::DIRECTION_LEFT_TO_RIGHT, false); } scrollview->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); - AddViewToRootContainer(scrollview); + AddViewToPageContainer(scrollview); titleText.SetPosition(180, 45, 260, 110); titleText.SetText("桌面"); titleText.SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); titleText.SetFont(DEFAULT_VECTOR_FONT_FILENAME, 40); titleText.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - AddViewToRootContainer(&titleText); + AddViewToPageContainer(&titleText); listImage.SetPosition(0, 135, 190, 190); listImage.SetSrc(PNG_SET_DESKTOP_BG_IMAGE); @@ -83,14 +92,14 @@ void SetDesktopView::OnStart() InitFootballItem(); InitWaterfallItem(); - listBtn.SetOnClickListener(presenter_); - hexagonsBtn.SetOnClickListener(presenter_); - footballBtn_.SetOnClickListener(presenter_); - waterfallBtn_.SetOnClickListener(presenter_); - UpdateSelectedStyle(presenter_->GetCurrentStyle()); + listBtn.SetOnClickListener(this); + hexagonsBtn.SetOnClickListener(this); + footballBtn_.SetOnClickListener(this); + waterfallBtn_.SetOnClickListener(this); + UpdateSelectedStyle(SetDesktopModel::GetInstance().GetDesktopStyle()); } -void SetDesktopView::UpdateSelectedStyle(uint8_t selectedStyle) +void SettingDesktopPage::UpdateSelectedStyle(DesktopStyle selectedStyle) { hexagonsImage.SetVisible(false); hexagonsBtn.SetState(false); @@ -101,13 +110,13 @@ void SetDesktopView::UpdateSelectedStyle(uint8_t selectedStyle) waterfallImage_.SetVisible(false); waterfallBtn_.SetState(false); - if (selectedStyle == 1) { // 1: select hexagons style + if (selectedStyle == HEXAGONS_STYLE) { // 1: select hexagons style hexagonsImage.SetVisible(true); hexagonsBtn.SetState(true); - } else if (selectedStyle == 2) { // 2: select football style + } else if (selectedStyle == FOOTBALL_STYLE) { // 2: select football style footballImage_.SetVisible(true); footballBtn_.SetState(true); - } else if (selectedStyle == 3) { // 3: select waterfall style + } else if (selectedStyle == WATERFALL_STYLE) { // 3: select waterfall style waterfallImage_.SetVisible(true); waterfallBtn_.SetState(true); } else { @@ -116,7 +125,7 @@ void SetDesktopView::UpdateSelectedStyle(uint8_t selectedStyle) } } -void SetDesktopView::InitFootballItem() +void SettingDesktopPage::InitFootballItem() { footballImage_.SetPosition(300, 135, 190, 190); footballImage_.SetSrc(PNG_SET_DESKTOP_BG_IMAGE); @@ -135,7 +144,7 @@ void SetDesktopView::InitFootballItem() scrollview->Add(&footballText_); } -void SetDesktopView::InitWaterfallItem() +void SettingDesktopPage::InitWaterfallItem() { waterfallImage_.SetPosition(450, 135, 190, 190); waterfallImage_.SetSrc(PNG_SET_DESKTOP_BG_IMAGE); @@ -153,8 +162,34 @@ void SetDesktopView::InitWaterfallItem() waterfallText_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); scrollview->Add(&waterfallText_); } -uint8_t SetDesktopView::GetCurrentSelectedStyle() + +bool SettingDesktopPage::OnDrag(UIView& view, const DragEvent& event) { - return presenter_->GetCurrentStyle(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingDesktopPage::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::OnDrag ChangeSlice"); + uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId(); + NativeAbility::GetInstance().ChangeSlice(preSlice); + } + return false; +} + +bool SettingDesktopPage::OnClick(UIView &view, const ClickEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingDesktopPage::OnClick"); + if (strcmp(view.GetViewId(), SET_DESKTOP_HEXAGONS) == 0) { + SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::HEXAGONS_STYLE); + } else if (strcmp(view.GetViewId(), SET_DESKTOP_LIST) == 0) { + SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::APPLIST_STYLE); + } else if (strcmp(view.GetViewId(), SET_DESKTOP_FOOTBALL) == 0) { + SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::FOOTBALL_STYLE); + } else if (strcmp(view.GetViewId(), SET_DESKTOP_WATERFALL) == 0) { + SetDesktopModel::GetInstance().SetDesktopStyle(DesktopStyle::WATERFALL_STYLE); + } + uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId(); + NativeAbility::GetInstance().ChangeSlice(preSlice); + return true; } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingItemView.cpp index 19129a3ea..9e88a4e28 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingItemView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingItemView.cpp @@ -6,7 +6,7 @@ */ #include "wearable_log.h" -#include "SettingItemView.h" +#include "settings/SettingItemView.h" namespace OHOS { static constexpr int16 SETTING_ICON_X = 20; @@ -43,7 +43,6 @@ namespace OHOS { void SettingItemView::SetItemInfo(const SettingItem itemInfo) { sItemInfo = itemInfo; - WEARABLE_LOGE("SettingItemView::SetItemInfo: %s", sItemInfo.label); sIcon.SetSrc(itemInfo.icon); sLabel.SetText(itemInfo.label); sNextImage.SetVisible(itemInfo.hasSecondMenu); @@ -68,9 +67,9 @@ namespace OHOS { sNextImage.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); } - AppViewId SettingItemView::GetViewId() + uint32_t SettingItemView::GetTargetId() { - return sItemInfo.viewId; + return sItemInfo.targetId; } const char* SettingItemView::GetIconId() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingMainPage.cpp new file mode 100644 index 000000000..207eef016 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingMainPage.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingMainPage + * Author: Hisi Graphic Team + * Created: 2025-4 + */ + +#include + +#include "settings/SettingMainPage.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "settings/SettingItem.h" +#include "settings/SettingPresenter.h" +#include "settings/SettingView.h" +#include "PageTransitionMgr.h" +#include "settings/SetDesktopModel.h" +#include "rebootdevice/RebootModel.h" +#include "settings/SettingModel.h" + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_SETTING, SETTING_PAGES::SETTING_MAIN_PAGE, SettingMainPage, true); + +static constexpr uint8_t SETTINGS_ITEM_FONT_SIZE = 40; +static constexpr int16_t SETTINGS_RESIZE_SIZE_WIDTH = 100; +static constexpr int16_t SETTINGS_RESIZE_SIZE_HEIGHT = 60; +static constexpr int16_t SETTING_TITLE_POSITION_X = 187; +static constexpr int16_t SETTING_LIST_POSITION_X = 32; +static constexpr int16_t SETTING_LIST_POSITION_Y = 90; +static constexpr int16_t SETTING_SCROLLBLANKSIZE = 50; +static constexpr int16 MAX_SCR_DIS = 1000; +static constexpr int16 LIST_POS = 20; +static constexpr int16 SNUM_2 = 2; + +SettingMainPage::~SettingMainPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingMainPage::~SettingMainPage"); + if (scrollView != nullptr) { + scrollView->RemoveAll(); + delete scrollView; + scrollView = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (listAdapter != nullptr) { + delete listAdapter; + listAdapter = nullptr; + } + + if (contentList != nullptr) { + delete contentList; + contentList = nullptr; + } +} + +void SettingMainPage::OnStart(void* data) +{ + title = new UILabel(); + if (title == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingMainPage::OnStart::title is nullptr"); + return; + } + title->SetPosition(SETTING_TITLE_POSITION_X, 0); + title->SetText("设置"); + title->Resize(SETTINGS_RESIZE_SIZE_WIDTH, SETTINGS_RESIZE_SIZE_HEIGHT); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTINGS_ITEM_FONT_SIZE); + title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + title->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + title->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + title->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + contentList = new UIListNested(); + if (contentList == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingMainPage::OnStart::contentList is nullptr"); + return; + } + contentList->SetPosition(SETTING_LIST_POSITION_X, SETTING_LIST_POSITION_Y); + contentList->Resize(HORIZONTAL_RESOLUTION, 364); // 364: height + contentList->SetScrollBlankSize(SETTING_SCROLLBLANKSIZE); + contentList->SetSelectPosition(HORIZONTAL_RESOLUTION / SNUM_2); // middle position + contentList->SetDraggable(true); + contentList->SetThrowDrag(true); + contentList->EnableAutoAlign(true); + contentList->SetMaxScrollDistance(MAX_SCR_DIS); + + scrollView = new UIScrollViewNested(); + if (scrollView == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingMainPage::OnStart::scrollView is nullptr"); + return; + } + scrollView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + scrollView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + scrollView->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + scrollView->SetThrowDrag(true); + + if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly + scrollView->SetOnDragListener(this); + } + scrollView->Add(title); + scrollView->Add(contentList); + SettingModel::GetInstance().InitSettingItem(); + AddViewToPageContainer(scrollView); + RefreshSettingsList(SettingModel::GetInstance().GetSettinglistItems(), + SettingModel::GetInstance().GetSettingListNum()); +} + +void SettingMainPage::RefreshSettingsList(const SettingItem* item, uint8_t count) +{ + listAdapter = new SettingAdapter(); + if (listAdapter == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SettingMainPage::OnStart::listAdapter is nullptr"); + return; + } + listAdapter->SetItemClickListener(this); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingMainPage::RefreshSettingsList"); + for (int i = 0; i < count; i++) { + listAdapter->AddListItem(item[i]); + } + contentList->SetAdapter(listAdapter); +} + +bool SettingMainPage::OnDrag(UIView& view, const DragEvent& event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::OnDrag ChangeSlice(VIEW_APPLIST)"); + if (SetDesktopModel::GetInstance().GetDesktopStyle() == HEXAGONS_STYLE) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST, TransitionType::TRANSITION_BACK_TO_HEXAGONS); + } else if (SetDesktopModel::GetInstance().GetDesktopStyle() == WATERFALL_STYLE) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST, TransitionType::TRANSITION_BACK_TO_WATERFALL); + } else { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + } + return false; +} + +bool SettingMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + SettingItemView *settingItemView = static_cast(&view); + uint32_t targetId = settingItemView->GetTargetId(); + uint16_t sliceId = static_cast(targetId & SLICE_MASK); + uint16_t pageId = static_cast(targetId >> PAGE_OFFSET); + if (sliceId == VIEW_REBOOT) { + if (strstr(settingItemView->GetIconId(), "REBOOT") != nullptr) { + RebootModel::GetInstance()->SetSelectViewId(REBOOTDEVICE); + RebootModel::GetInstance()->SetExitsView(true); + } else { + RebootModel::GetInstance()->SetSelectViewId(SHUTDOWNDEVICE); + RebootModel::GetInstance()->SetExitsView(true); + } + } + if (sliceId != VIEW_SETTING) { + if (settingItemView->SlideBackEnabled()) { + NativeAbility::GetInstance().ChangeSlice(sliceId, TransitionType::TRANSITION_INVALID, + gSliceDefaultPriority, true); + } else { + NativeAbility::GetInstance().ChangeSlice(sliceId); + } + } else { + NativeAbility::GetInstance().SwitchPageInSlice(pageId, nullptr, TransitionType::TRANSITION_INVALID, true); + } + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingModel.cpp index 3345274df..d732125d7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingModel.cpp @@ -5,8 +5,10 @@ * Create: 2021-11-23 */ -#include "SettingModel.h" -#include "PullUpDownView.h" +#include "settings/SettingModel.h" +#include "Slice.h" +#include "main/PullUpDownView.h" +#include "settings/SettingView.h" namespace OHOS { SettingModel::SettingModel() {} @@ -22,15 +24,20 @@ namespace OHOS { void SettingModel::InitSettingItem() { int index = 0; - settings[index++] = {VIEW_BLUETOOTH_EARPHONE, PNG_BLUETOOTH_STITLE, "蓝牙耳机", true, false}; - settings[index++] = {VIEW_CONNECT_PHONE, PNG_CONNECT_PHONE_IMAGE, "连接手机", true, true}; - settings[index++] = {VIEW_REBOOT, PNG_SETTTING_REBOOT_IMAGE, "重启", true, true}; - settings[index++] = {VIEW_REBOOT, PNG_SETTTING_SHUTDOWN_IMAGE, "关机", true, true}; - settings[index++] = {VIEW_SET_DESKTOP, PNG_SETTTING_DESKTOP_IMAGE, "桌面", true, true}; - settings[index++] = {VIEW_SET_DIAL, PNG_SETTTING_DESKTOP_IMAGE, "表盘", true, false}; - settings[index++] = {VIEW_SET_CARD, PNG_SETTTING_DESKTOP_IMAGE, "卡片", true, false}; - settings[index++] = {VIEW_SET_DIAL_STYLE, PNG_SETTTING_DESKTOP_IMAGE, "表盘风格", true, true}; - settings[index++] = {VIEW_RESTORE_DEFAULTS, PNG_SETTTING_DESKTOP_IMAGE, "恢复出厂", true, true}; + settings[index++] = {static_cast(VIEW_BLUETOOTH_EARPHONE), PNG_BLUETOOTH_STITLE, + "蓝牙耳机", true, false}; + settings[index++] = {static_cast(VIEW_CONNECT_PHONE), PNG_CONNECT_PHONE_IMAGE, "连接手机", true, true}; + settings[index++] = {static_cast(VIEW_REBOOT), PNG_SETTTING_REBOOT_IMAGE, "重启", true, true}; + settings[index++] = {static_cast(VIEW_REBOOT), PNG_SETTTING_SHUTDOWN_IMAGE, "关机", true, true}; + settings[index++] = {static_cast(VIEW_SET_DIAL), PNG_SETTTING_DESKTOP_IMAGE, "表盘", true, false}; + settings[index++] = {static_cast(VIEW_SETTING) | (SETTING_DESKTOP_PAGE << PAGE_OFFSET), + PNG_SETTTING_DESKTOP_IMAGE, "桌面", true, true}; + settings[index++] = {static_cast(VIEW_SET_CARD), PNG_SETTTING_DESKTOP_IMAGE, "卡片", true, false}; + settings[index++] = {static_cast(VIEW_SET_DIAL_STYLE), PNG_SETTTING_DESKTOP_IMAGE, + "表盘风格", true, true}; + settings[index++] = {static_cast(VIEW_RESTORE_DEFAULTS), PNG_SETTTING_DESKTOP_IMAGE, + "恢复出厂", true, true}; + settings[index++] = {static_cast(VIEW_SET_OTA), PNG_SETTTING_DESKTOP_IMAGE, "OTA升级", true, true}; usedLen = index; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingPresenter.cpp index 16499b9f7..fbf508ee9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingPresenter.cpp @@ -5,74 +5,10 @@ * Create: 2021-11-23 */ -#include "SettingView.h" -#include "SettingModel.h" -#include "SettingPresenter.h" -#include "RebootModel.h" -#include "SetDesktopModel.h" +#include "settings/SettingView.h" +#include "settings/SettingPresenter.h" #include "NativeRegisterManager.h" namespace OHOS { - REGIST_MENU(VIEW_SETTING, SettingView, SettingPresenter, PNG_APPLIST_SETTING_IMAGE, PNG_APPLIST_DEFAULT_IMG, "设置"); - - SettingPresenter::SettingPresenter() - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::SettingPresenter()"); - settingModel = &SettingModel::GetInstance(); - } - - SettingPresenter::~SettingPresenter() {} - - void SettingPresenter::OnStart() - { - settingModel->InitSettingItem(); - if (view_ == nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "view_ is nullptr!!"); - return; - } - const SettingItem *itemInfo = settingModel->GetSettinglistItems(); - view_->RefreshSettingsList(itemInfo, settingModel->GetSettingListNum()); - } - - bool SettingPresenter::OnDrag(UIView& view, const DragEvent& event) - { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::OnDrag"); - UNUSED(view); - if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && - (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::OnDrag ChangeSlice(VIEW_APPLIST)"); - if (SetDesktopModel::GetInstance().GetDesktopStyle() == HEXAGONS_STYLE) { - NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST, TransitionType::TRANSITION_BACK_TO_HEXAGONS); - } else if (SetDesktopModel::GetInstance().GetDesktopStyle() == WATERFALL_STYLE) { - NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST, TransitionType::TRANSITION_BACK_TO_WATERFALL); - } else { - NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); - } - } - return false; - } - - bool SettingPresenter::OnClick(UIView &view, const ClickEvent &event) - { - UNUSED(event); - SettingItemView *settingItemView = static_cast(&view); - AppViewId viewId = settingItemView->GetViewId(); - if (viewId == VIEW_REBOOT) { - if (strstr(settingItemView->GetIconId(), "REBOOT") != nullptr) { - RebootModel::GetInstance()->SetSelectViewId(REBOOTDEVICE); - RebootModel::GetInstance()->SetExitsView(true); - } else { - RebootModel::GetInstance()->SetSelectViewId(SHUTDOWNDEVICE); - RebootModel::GetInstance()->SetExitsView(true); - } - } - if (settingItemView->SlideBackEnabled()) { - NativeAbility::GetInstance().ChangeSlice(viewId, TransitionType::TRANSITION_INVALID, - gSliceDefaultPriority, true); - } else { - NativeAbility::GetInstance().ChangeSlice(viewId); - } - return true; - } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingView.cpp deleted file mode 100644 index 2b03b50ce..000000000 --- a/code/sdk/application/wearable/nativeapp/nativeui/settings/src/SettingView.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: SettingView.cpp - * Author: - * Create: 2021-11-23 - */ - -#include - -#include "SettingView.h" -#include "SettingItem.h" -#include "SettingPresenter.h" -#include "components/ui_list_nested.h" -#include "components/ui_scroll_view_nested.h" - -namespace OHOS { -static constexpr uint8_t SETTINGS_ITEM_FONT_SIZE = 40; -static constexpr int16_t SETTINGS_RESIZE_SIZE_WIDTH = 100; -static constexpr int16_t SETTINGS_RESIZE_SIZE_HEIGHT = 60; -static constexpr int16_t SETTING_TITLE_POSITION_X = 187; -static constexpr int16_t SETTING_LIST_POSITION_X = 32; -static constexpr int16_t SETTING_LIST_POSITION_Y = 90; -static constexpr int16_t SETTING_SCROLLBLANKSIZE = 50; -static constexpr int16 MAX_SCR_DIS = 1000; -static constexpr int16 LIST_POS = 20; -static constexpr int16 SNUM_2 = 2; - -SettingView::SettingView() -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::SettingView"); -} - -SettingView::~SettingView() -{ - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::~SettingView"); - if (scrollView != nullptr) { - scrollView->RemoveAll(); - delete scrollView; - scrollView = nullptr; - } - - if (title != nullptr) { - delete title; - title = nullptr; - } - - if (listAdapter != nullptr) { - delete listAdapter; - listAdapter = nullptr; - } - - if (contentList != nullptr) { - delete contentList; - contentList = nullptr; - } -} - -void SettingView::OnStart() -{ - title = new UILabel(); - if (title == nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::title is nullptr"); - return; - } - title->SetPosition(SETTING_TITLE_POSITION_X, 0); - title->SetText("设置"); - title->Resize(SETTINGS_RESIZE_SIZE_WIDTH, SETTINGS_RESIZE_SIZE_HEIGHT); - title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTINGS_ITEM_FONT_SIZE); - title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); - title->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); - title->SetStyle(STYLE_TEXT_COLOR, Color::White().full); - title->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); - title->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); - - contentList = new UIListNested(); - if (contentList == nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::contentList is nullptr"); - return; - } - contentList->SetPosition(SETTING_LIST_POSITION_X, SETTING_LIST_POSITION_Y); - contentList->Resize(HORIZONTAL_RESOLUTION, 364); // 364: height - contentList->SetScrollBlankSize(SETTING_SCROLLBLANKSIZE); - contentList->SetSelectPosition(HORIZONTAL_RESOLUTION / SNUM_2); // middle position - contentList->SetDraggable(true); - contentList->SetThrowDrag(true); - contentList->EnableAutoAlign(true); - contentList->SetMaxScrollDistance(MAX_SCR_DIS); - - scrollView = new UIScrollViewNested(); - if (scrollView == nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::scrollView is nullptr"); - return; - } - scrollView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); - scrollView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); - scrollView->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); - scrollView->SetThrowDrag(true); - - if (PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { // support default slide back firstly - scrollView->SetOnDragListener(presenter_); - } - scrollView->Add(title); - scrollView->Add(contentList); - AddViewToRootContainer(scrollView); -} - -void SettingView::RefreshSettingsList(const SettingItem* item, uint8_t count) -{ - listAdapter = new SettingAdapter(); - if (listAdapter == nullptr) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::listAdapter is nullptr"); - return; - } - listAdapter->SetItemClickListener(presenter_); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::RefreshSettingsList"); - for (int i = 0; i < count; i++) { - listAdapter->AddListItem(item[i]); - } - contentList->SetAdapter(listAdapter); -} -} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingDetailsPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingDetailsPage.cpp new file mode 100644 index 000000000..1341d7b1b --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingDetailsPage.cpp @@ -0,0 +1,635 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingDetailsPage + * Created: 2025-06-05 + */ +#include +#include +#include "ohos_timer.h" +#include "wearable_log.h" +#include "SlicePageFactory.h" +#include "common/image_cache_manager.h" +#include "AppViewIDs.h" +#include "NativeAbility.h" +#include "sleep/SleepingView.h" +#include "sleep/SleepingModel.h" +#include "sleep/SleepingDetailsPage.h" + +namespace OHOS { + +static constexpr int16_t SLEEPDETAIL_SLEEP_X = 97; +static constexpr int16_t SLEEPDETAIL_SLEEP_Y = 31; +static constexpr int16_t SLEEPDETAIL_SLEEP_WIDTH = 260; +static constexpr int16_t SLEEPDETAIL_SLEEP_HEIGHT = 53; +static constexpr int16_t SLEEPDETAIL_SLEEP_FONT_SIZE = 38; +static constexpr int16_t SLEEPDETAIL_IMAGE1_X = 77; +static constexpr int16_t SLEEPDETAIL_IMAGE1_Y = 215; +static constexpr int16_t SLEEPDETAIL_SOBERINGTIME_X = 103; +static constexpr int16_t SLEEPDETAIL_SOBERINGTIME_Y = 205; +static constexpr int16_t SLEEPDETAIL_SOBERINGTIME_WIDTH = 48; +static constexpr int16_t SLEEPDETAIL_SOBERINGTIME_HEIGHT = 29; +static constexpr int16_t SLEEPDETAIL_SOBERINGTIME_FONT_SIZE = 24; +static constexpr int16_t SLEEPDETAIL_IMAGE2_Y = 254; +static constexpr int16_t SLEEPDETAIL_IMAGE3_Y = 291; +static constexpr int16_t SLEEPDETAIL_IMAGE4_Y = 330; +static constexpr int16_t SLEEPDETAIL_RAPID_Y = 244; +static constexpr int16_t SLEEPDETAIL_RAPID_WIDTH = 100; +static constexpr int16_t SLEEPDETAIL_RAPID_HEIGHT = 38; +static constexpr int16_t SLEEPDETAIL_LIGHT_Y = 283; +static constexpr int16_t SLEEPDETAIL_DEEP_Y = 322; +static constexpr int16_t SLEEPDETAIL_GRAYBG_X = 62; +static constexpr int16_t SLEEPDETAIL_GRAYBG_Y = 185; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_X = 180; +static constexpr int16_t SLEEPDETAIL_ACTUAL_NORECODE_X = 96; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_Y = 100; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_WIDTH = 200; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_HEIGHT = 35; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_FONT_SIZE = 32; +static constexpr int16_t SLEEPDETAIL_LABEL_WIDTH = 160; +static constexpr int16_t SLEEPDETAIL_PADDING_RIGHT = 30; +static constexpr int16_t SLEEPDETAIL_SOBERINGTEXT_X = 220; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_NORECORD_X = 179; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEP_NORECORD_Y = 110; +static constexpr int16_t SLEEPDETAIL_SOBERTIMETEXT_X = 300; +static constexpr int16_t SLEEPDETAIL_SOBERTIMETEXT_Y = 190; +static constexpr int16_t SLEEPDETAIL_RAPIDTIMETEXT_Y = 230; +static constexpr int16_t SLEEPDETAIL_LIGHTIMETEXT_Y = 270; +static constexpr int16_t SLEEPDETAIL_DEEPIMETEXT_Y = 310; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEPTIMEHOURS_FONT_SIZE = 40; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT = 50; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEPTIMINUTES_FONT_SIZE = 40; +static constexpr int16_t SLEEPDETAIL_ACTUALMINUTE_X = 230; +static constexpr int16_t SLEEPDETAIL_ACTUALMINUTE_Y = 116; +static constexpr int16_t SLEEPDETAIL_ACTUALHOUR_X = 135; +static constexpr int16_t SLEEPDETAIL_ACTUALHOUR_Y = 100; +static constexpr int16_t SLEEPDETAIL_ACTUALHOURTEXT_X = 170; +static constexpr int16_t SLEEPDETAIL_ACTUALMINUTETEXT_X = 280; +static constexpr int16_t ACTUALHOURS_X = 140; +static constexpr int16_t ACTUALHOURSTEXT_X = 180; +static constexpr int16_t ACTUALMINUTESTEXT_X = 270; + +REGIST_SLICE_PAGE(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_DEATIL_PAGE, SleepingDetailsPage, false); + +SleepingDetailsPage::SleepingDetailsPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepingDetailsPage::SleepingDetailsPage"); +} + +SleepingDetailsPage::~SleepingDetailsPage() +{ + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (detailsSleepView != nullptr) { + delete detailsSleepView; + detailsSleepView = nullptr; + } + + if (sleep != nullptr) { + delete sleep; + sleep = nullptr; + } + + if (actualSleepTime != nullptr) { + delete actualSleepTime; + actualSleepTime = nullptr; + } + + if (actualSleepTimeHours != nullptr) { + delete actualSleepTimeHours; + actualSleepTimeHours = nullptr; + } + + if (actualSleepTimeHoursText != nullptr) { + delete actualSleepTimeHoursText; + actualSleepTimeHoursText = nullptr; + } + + if (actualSleepTimeMinutes != nullptr) { + delete actualSleepTimeMinutes; + actualSleepTimeMinutes = nullptr; + } + + if (actualSleepTimeMinutesText != nullptr) { + delete actualSleepTimeMinutesText; + actualSleepTimeMinutesText = nullptr; + } + + if (grayBg != nullptr) { + delete grayBg; + grayBg = nullptr; + } + + if (image1 != nullptr) { + delete image1; + image1 = nullptr; + } + + if (soberingTime_ != nullptr) { + delete soberingTime_; + soberingTime_ = nullptr; + } + + if (soberingTimeText != nullptr) { + delete soberingTimeText; + soberingTimeText = nullptr; + } + + if (image2 != nullptr) { + delete image2; + image2 = nullptr; + } + + if (rapidEyeMovement_ != nullptr) { + delete rapidEyeMovement_; + rapidEyeMovement_ = nullptr; + } + + if (rapidEyeMovementText != nullptr) { + delete rapidEyeMovementText; + rapidEyeMovementText = nullptr; + } + + if (image3 != nullptr) { + delete image3; + image3 = nullptr; + } + + if (lightSleepTime_ != nullptr) { + delete lightSleepTime_; + lightSleepTime_ = nullptr; + } + + if (lightSleepTimeText != nullptr) { + delete lightSleepTimeText; + lightSleepTimeText = nullptr; + } + + if (image4 != nullptr) { + delete image4; + image4 = nullptr; + } + + if (deepSleepTime_ != nullptr) { + delete deepSleepTime_; + deepSleepTime_ = nullptr; + } + + if (deepSleepTimeText != nullptr) { + delete deepSleepTimeText; + deepSleepTimeText = nullptr; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepingDetailsPage::~SleepingDetailsPage"); +} + +void SleepingDetailsPage::OnStart(void* data) +{ + group = new UIScrollView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group is nullptr"); + return; + } + group->SetPosition(0, 0); + group->Resize(RESOLUTION_WIDTH, RESOLUTION_HEIGHT); + group->SetViewId("sleepDetails"); + + detailsSleepView = new UIImageView(); + if (detailsSleepView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "detailsSleepView is nullptr"); + return; + } + LOADIMG::LoadImageViewImg(detailsSleepView, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_BACKGROUND); + detailsSleepView->SetPosition(0, 0, RESOLUTION_WIDTH, RESOLUTION_HEIGHT); + group->Add(detailsSleepView); + + sleep = new UILabel(); + if (sleep == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleep is nullptr"); + return; + } + sleep->SetPosition(SLEEPDETAIL_SLEEP_X, SLEEPDETAIL_SLEEP_Y); + sleep->Resize(SLEEPDETAIL_SLEEP_WIDTH, SLEEPDETAIL_SLEEP_HEIGHT); + sleep->SetText("睡眠"); + sleep->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + sleep->SetTextColor(Color::White()); + sleep->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SLEEP_FONT_SIZE); + sleep->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(sleep); + + InitPage(); + + if (GetRecord() == true) { + InitDetailPage(); + } else { + InitNoDeatilPage(); + }; + group->SetOnDragListener(this); + group->SetDraggable(true); + group->SetTouchable(true); + AddViewToPageContainer(group); +} + +void SleepingDetailsPage::InitSoberingTime() +{ + image1 = new UIImageView(); + if (image1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "image1 is nullptr"); + return; + } + image1->SetPosition(SLEEPDETAIL_IMAGE1_X, SLEEPDETAIL_IMAGE1_Y); + LOADIMG::LoadImageViewImg(image1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_RED_CIR); + group->Add(image1); + soberingTime_ = new UILabel(); + if (soberingTime_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "soberingTime_ is nullptr"); + return; + } + soberingTime_->SetPosition(SLEEPDETAIL_SOBERINGTIME_X, SLEEPDETAIL_SOBERINGTIME_Y); + soberingTime_->Resize(SLEEPDETAIL_SOBERINGTIME_WIDTH, SLEEPDETAIL_SOBERINGTIME_HEIGHT); + soberingTime_->SetText("清醒"); + soberingTime_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + soberingTime_->SetTextColor(Color::White()); + soberingTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + soberingTime_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + group->Add(soberingTime_); +} + +void SleepingDetailsPage::InitRapidEyeMovement() +{ + image2 = new UIImageView(); + if (image2 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "image2 is nullptr"); + return; + } + image2->SetPosition(SLEEPDETAIL_IMAGE1_X, SLEEPDETAIL_IMAGE2_Y); + LOADIMG::LoadImageViewImg(image2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_ORANGE_CIR); + group->Add(image2); + + rapidEyeMovement_ = new UILabel(); + if (rapidEyeMovement_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "rapidEyeMovement_ is nullptr"); + return; + } + rapidEyeMovement_->SetPosition(SLEEPDETAIL_SOBERINGTIME_X, SLEEPDETAIL_RAPID_Y); + rapidEyeMovement_->Resize(SLEEPDETAIL_RAPID_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + rapidEyeMovement_->SetText("快速动眼"); + rapidEyeMovement_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + rapidEyeMovement_->SetTextColor(Color::White()); + rapidEyeMovement_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + rapidEyeMovement_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + group->Add(rapidEyeMovement_); +} + +void SleepingDetailsPage::InitLightSleepTime() +{ + image3 = new UIImageView(); + if (image3 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "image3 is nullptr"); + return; + } + image3->SetPosition(SLEEPDETAIL_IMAGE1_X, SLEEPDETAIL_IMAGE3_Y); + LOADIMG::LoadImageViewImg(image3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_GREEN_CIR); + group->Add(image3); + + lightSleepTime_ = new UILabel(); + if (lightSleepTime_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "lightSleepTime_ is nullptr"); + return; + } + lightSleepTime_->SetPosition(SLEEPDETAIL_SOBERINGTIME_X, SLEEPDETAIL_LIGHT_Y); + lightSleepTime_->Resize(SLEEPDETAIL_SOBERINGTIME_WIDTH, SLEEPDETAIL_SOBERINGTIME_HEIGHT); + lightSleepTime_->SetText("浅睡"); + lightSleepTime_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + lightSleepTime_->SetTextColor(Color::White()); + lightSleepTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + lightSleepTime_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + group->Add(lightSleepTime_); +} + +void SleepingDetailsPage::InitDeepSleepTime() +{ + image4 = new UIImageView(); + if (image4 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "image4 is nullptr"); + return; + } + image4->SetPosition(SLEEPDETAIL_IMAGE1_X, SLEEPDETAIL_IMAGE4_Y); + LOADIMG::LoadImageViewImg(image4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_BLUE_CIR); + group->Add(image4); + + deepSleepTime_ = new UILabel(); + if (deepSleepTime_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deepSleepTime_ is nullptr"); + return; + } + deepSleepTime_->SetPosition(SLEEPDETAIL_SOBERINGTIME_X, SLEEPDETAIL_DEEP_Y); + deepSleepTime_->Resize(SLEEPDETAIL_SOBERINGTIME_WIDTH, SLEEPDETAIL_SOBERINGTIME_HEIGHT); + deepSleepTime_->SetText("深睡"); + deepSleepTime_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + deepSleepTime_->SetTextColor(Color::White()); + deepSleepTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + deepSleepTime_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + group->Add(deepSleepTime_); +} + +void SleepingDetailsPage::InitPage() +{ + grayBg = new UIImageView(); + if (grayBg == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "grayBg is nullptr"); + return; + } + grayBg->SetPosition(SLEEPDETAIL_GRAYBG_X, SLEEPDETAIL_GRAYBG_Y); + LOADIMG::LoadImageViewImg(grayBg, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_RECORD_BG); + group->Add(grayBg); + + // 加载详情四项 + InitSoberingTime(); + InitRapidEyeMovement(); + InitLightSleepTime(); + InitDeepSleepTime(); +} + +void SleepingDetailsPage::IoadDeatilActualSleepTime() +{ + actualSleepTimeHours = new UILabel(); + if (actualSleepTimeHours == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeHours is nullptr"); + return; + } + + actualSleepTimeHours->SetTextColor(Color::White()); + actualSleepTimeHours->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_ACTUALSLEEPTIMEHOURS_FONT_SIZE); + actualSleepTimeHours->SetVisible(false); + + actualSleepTimeHoursText = new UILabel(); + if (actualSleepTimeHoursText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeHoursText is nullptr"); + return; + } + actualSleepTimeHoursText->SetText("小时"); + actualSleepTimeHoursText->Resize(SLEEPDETAIL_SOBERINGTIME_WIDTH, SLEEPDETAIL_SOBERINGTIME_HEIGHT); + actualSleepTimeHoursText->SetTextColor(Color::White()); + actualSleepTimeHoursText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + actualSleepTimeHoursText->SetVisible(false); + + actualSleepTimeMinutes = new UILabel(); + if (actualSleepTimeMinutes == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeMinutes is nullptr"); + return; + } + + actualSleepTimeMinutes->Resize(SLEEPDETAIL_RAPID_WIDTH, SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT); + actualSleepTimeMinutes->SetTextColor(Color::White()); + actualSleepTimeMinutes->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_ACTUALSLEEPTIMINUTES_FONT_SIZE); + actualSleepTimeMinutes->SetVisible(false); + + actualSleepTimeMinutesText = new UILabel(); + if (actualSleepTimeMinutesText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeHours is nullptr"); + return; + } + + actualSleepTimeMinutesText->SetText("分钟"); + actualSleepTimeMinutesText->Resize(SLEEPDETAIL_SOBERINGTIME_WIDTH, SLEEPDETAIL_SOBERINGTIME_HEIGHT); + actualSleepTimeMinutesText->SetTextColor(Color::White()); + actualSleepTimeMinutesText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + actualSleepTimeMinutesText->SetVisible(false); +} + +void SleepingDetailsPage::InitActualSleepTime(std::tuple timeTuple) +{ + IoadDeatilActualSleepTime(); + uint32_t hours = std::get<0>(timeTuple); + uint32_t minutes = std::get<1>(timeTuple); + + if ((hours == 0) && (minutes != 0)) { + actualSleepTimeMinutes->SetPosition(SLEEPDETAIL_ACTUALSLEEP_X, SLEEPDETAIL_ACTUALSLEEP_Y); + actualSleepTimeMinutes->SetVisible(true); + actualSleepTimeMinutes->SetText(std::to_string(minutes).c_str()); + group->Add(actualSleepTimeMinutes); + + actualSleepTimeMinutesText->SetPosition(SLEEPDETAIL_ACTUALMINUTE_X, SLEEPDETAIL_ACTUALMINUTE_Y); + actualSleepTimeMinutesText->SetVisible(true); + group->Add(actualSleepTimeMinutesText); + } else if ((hours != 0) && (minutes == 0)) { + actualSleepTimeHours->SetPosition(SLEEPDETAIL_ACTUALSLEEP_X, SLEEPDETAIL_ACTUALSLEEP_Y); + actualSleepTimeHours->Resize(SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT, SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT); + actualSleepTimeHours->SetVisible(true); + actualSleepTimeHours->SetText(std::to_string(hours).c_str()); + group->Add(actualSleepTimeHours); + + actualSleepTimeHoursText->SetPosition(SLEEPDETAIL_ACTUALMINUTE_X, SLEEPDETAIL_ACTUALMINUTE_Y); + actualSleepTimeHoursText->SetVisible(true); + group->Add(actualSleepTimeHoursText); + } else if ((hours != 0) && (minutes != 0)) { + actualSleepTimeHours->SetPosition(SLEEPDETAIL_ACTUALHOUR_X, SLEEPDETAIL_ACTUALHOUR_Y); + actualSleepTimeHours->Resize(SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT, SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT); + + actualSleepTimeHours->SetVisible(true); + actualSleepTimeHours->SetText(std::to_string(hours).c_str()); + group->Add(actualSleepTimeHours); + + actualSleepTimeHoursText->SetPosition(SLEEPDETAIL_ACTUALHOURTEXT_X, SLEEPDETAIL_ACTUALMINUTE_Y); + actualSleepTimeHoursText->SetVisible(true); + group->Add(actualSleepTimeHoursText); + + actualSleepTimeMinutes->SetPosition(SLEEPDETAIL_ACTUALMINUTE_X, SLEEPDETAIL_ACTUALHOUR_Y); + actualSleepTimeMinutes->SetVisible(true); + actualSleepTimeMinutes->SetText(std::to_string(minutes).c_str()); + group->Add(actualSleepTimeMinutes); + + actualSleepTimeMinutesText->SetPosition(SLEEPDETAIL_ACTUALMINUTETEXT_X, SLEEPDETAIL_ACTUALMINUTE_Y); + actualSleepTimeMinutesText->SetVisible(true); + group->Add(actualSleepTimeMinutesText); + } else if ((hours == 0) && (minutes == 0)) { + actualSleepTimeHours->SetPosition(ACTUALHOURS_X, SLEEPDETAIL_ACTUALHOUR_Y); + actualSleepTimeHours->Resize(SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT, SLEEPDETAIL_ACTUALSLEEPTIMINUTES_HEIGHT); + actualSleepTimeHours->SetVisible(true); + actualSleepTimeHours->SetText("--"); + group->Add(actualSleepTimeHours); + + actualSleepTimeHoursText->SetPosition(ACTUALHOURSTEXT_X, SLEEPDETAIL_ACTUALMINUTE_Y); + actualSleepTimeHoursText->SetVisible(true); + group->Add(actualSleepTimeHoursText); + + actualSleepTimeMinutes->SetPosition(SLEEPDETAIL_ACTUALMINUTE_X, SLEEPDETAIL_ACTUALHOUR_Y); + actualSleepTimeMinutes->SetVisible(true); + actualSleepTimeMinutes->SetText("--"); + group->Add(actualSleepTimeMinutes); + + actualSleepTimeMinutesText->SetPosition(ACTUALMINUTESTEXT_X, SLEEPDETAIL_ACTUALMINUTE_Y); + actualSleepTimeMinutesText->SetVisible(true); + group->Add(actualSleepTimeMinutesText); + } +} + +void SleepingDetailsPage::InitDetailPage() +{ + InitActualSleepTime(SleepingModel::GetInstance().GetSleepTime()); + + soberingTimeText = new UILabel(); + if (soberingTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "soberingTimeText is nullptr"); + return; + } + soberingTimeText->SetText((SetTimeText(SleepingModel::GetInstance().GetSoberingTime())).c_str()); + soberingTimeText->SetPosition(SLEEPDETAIL_SOBERINGTEXT_X, SLEEPDETAIL_SOBERINGTIME_Y); + + soberingTimeText->Resize(SLEEPDETAIL_LABEL_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + soberingTimeText->SetTextColor(Color::White()); + soberingTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + soberingTimeText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + soberingTimeText->SetStyle(STYLE_PADDING_RIGHT, SLEEPDETAIL_PADDING_RIGHT); + group->Add(soberingTimeText); + + rapidEyeMovementText = new UILabel(); + if (rapidEyeMovementText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "rapidEyeMovementText is nullptr"); + return; + } + rapidEyeMovementText->SetText((SetTimeText(SleepingModel::GetInstance().GetRapidEyeMovementTime())).c_str()); + rapidEyeMovementText->SetPosition(SLEEPDETAIL_SOBERINGTEXT_X, SLEEPDETAIL_RAPID_Y); + + rapidEyeMovementText->Resize(SLEEPDETAIL_LABEL_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + rapidEyeMovementText->SetTextColor(Color::White()); + rapidEyeMovementText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + rapidEyeMovementText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + rapidEyeMovementText->SetStyle(STYLE_PADDING_RIGHT, SLEEPDETAIL_PADDING_RIGHT); + group->Add(rapidEyeMovementText); + + lightSleepTimeText = new UILabel(); + if (lightSleepTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "lightSleepTimeText is nullptr"); + return; + } + lightSleepTimeText->SetText((SetTimeText(SleepingModel::GetInstance().GetLightSleepTime())).c_str()); + lightSleepTimeText->SetPosition(SLEEPDETAIL_SOBERINGTEXT_X, SLEEPDETAIL_LIGHT_Y); + lightSleepTimeText->Resize(SLEEPDETAIL_LABEL_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + lightSleepTimeText->SetTextColor(Color::White()); + lightSleepTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + lightSleepTimeText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + lightSleepTimeText->SetStyle(STYLE_PADDING_RIGHT, SLEEPDETAIL_PADDING_RIGHT); + group->Add(lightSleepTimeText); + + deepSleepTimeText = new UILabel(); + if (deepSleepTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deepSleepTimeText is nullptr"); + return; + } + deepSleepTimeText->SetText((SetTimeText(SleepingModel::GetInstance().GetDeepSleepTime())).c_str()); + deepSleepTimeText->SetPosition(SLEEPDETAIL_SOBERINGTEXT_X, SLEEPDETAIL_DEEP_Y); + deepSleepTimeText->Resize(SLEEPDETAIL_LABEL_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + deepSleepTimeText->SetTextColor(Color::White()); + deepSleepTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + deepSleepTimeText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + deepSleepTimeText->SetStyle(STYLE_PADDING_RIGHT, SLEEPDETAIL_PADDING_RIGHT); + group->Add(deepSleepTimeText); +} + +void SleepingDetailsPage::InitNoDeatilPage() +{ + actualSleepTime = new UILabel(); + if (actualSleepTime == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTime is nullptr"); + return; + } + actualSleepTime->SetText("无记录"); + actualSleepTime->SetPosition(SLEEPDETAIL_ACTUALSLEEP_NORECORD_X, SLEEPDETAIL_ACTUALSLEEP_NORECORD_Y); + actualSleepTime->Resize(SLEEPDETAIL_ACTUAL_NORECODE_X, SLEEPDETAIL_SOBERINGTIME_WIDTH); + actualSleepTime->SetTextColor(Color::White()); + actualSleepTime->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_ACTUALSLEEP_FONT_SIZE); + group->Add(actualSleepTime); + + soberingTimeText = new UILabel(); + if (soberingTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "soberingTimeText is nullptr"); + return; + } + soberingTimeText->SetText("--"); + soberingTimeText->SetPosition(SLEEPDETAIL_SOBERTIMETEXT_X, SLEEPDETAIL_SOBERTIMETEXT_Y); + soberingTimeText->Resize(SLEEPDETAIL_RAPID_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + soberingTimeText->SetTextColor(Color::White()); + soberingTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + soberingTimeText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + group->Add(soberingTimeText); + + rapidEyeMovementText = new UILabel(); + if (rapidEyeMovementText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "rapidEyeMovementText is nullptr"); + return; + } + rapidEyeMovementText->SetText("--"); + rapidEyeMovementText->SetPosition(SLEEPDETAIL_SOBERTIMETEXT_X, SLEEPDETAIL_RAPIDTIMETEXT_Y); + rapidEyeMovementText->Resize(SLEEPDETAIL_RAPID_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + rapidEyeMovementText->SetTextColor(Color::White()); + rapidEyeMovementText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + rapidEyeMovementText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + group->Add(rapidEyeMovementText); + + lightSleepTimeText = new UILabel(); + if (lightSleepTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "lightSleepTimeText is nullptr"); + return; + } + lightSleepTimeText->SetText("--"); + lightSleepTimeText->SetPosition(SLEEPDETAIL_SOBERTIMETEXT_X, SLEEPDETAIL_LIGHTIMETEXT_Y); + lightSleepTimeText->Resize(SLEEPDETAIL_RAPID_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + lightSleepTimeText->SetTextColor(Color::White()); + lightSleepTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + lightSleepTimeText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + group->Add(lightSleepTimeText); + + deepSleepTimeText = new UILabel(); + if (deepSleepTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deepSleepTimeText is nullptr"); + return; + } + deepSleepTimeText->SetText("--"); + deepSleepTimeText->SetPosition(SLEEPDETAIL_SOBERTIMETEXT_X, SLEEPDETAIL_DEEPIMETEXT_Y); + deepSleepTimeText->Resize(SLEEPDETAIL_RAPID_WIDTH, SLEEPDETAIL_RAPID_HEIGHT); + deepSleepTimeText->SetTextColor(Color::White()); + deepSleepTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_SOBERINGTIME_FONT_SIZE); + deepSleepTimeText->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + group->Add(deepSleepTimeText); +} + +std::string SleepingDetailsPage::SetTimeText(std::tuple timeTuple) +{ + uint32_t hours = std::get<0>(timeTuple); + uint32_t minutes = std::get<1>(timeTuple); + + std::string str = ""; + if ((hours == 0) && (minutes != 0)) { + str = std::to_string(minutes) + "分钟"; + } else if ((hours != 0) && (minutes == 0)) { + str = std::to_string(hours) + "小时"; + } else if ((hours != 0) && (minutes != 0)) { + str = std::to_string(hours) + "小时" + std::to_string(minutes) + "分钟"; + } else if ((hours == 0) && (minutes == 0)) { + str = "---"; + } + return str; +} + +bool SleepingDetailsPage::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if (event.GetDragDirection() == DragEvent::DIRECTION_TOP_TO_BOTTOM) { + NativeAbility::GetInstance().SwitchSlice(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_MAIN_PAGE); + } + return true; +} + +bool SleepingDetailsPage::GetRecord() +{ + if (SleepingModel::GetInstance().GetRecord()) { + return true; + } + return false; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingMainPage.cpp new file mode 100644 index 000000000..d88a582cc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingMainPage.cpp @@ -0,0 +1,705 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingMainPage + * Created: 2025-06-05 + */ + +#include +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "PageTransitionMgr.h" +#include "settings/SetDesktopModel.h" +#include "rebootdevice/RebootModel.h" +#include "common/image_cache_manager.h" +#include "diag_service.h" +#include "msg_center_device.h" +#include "diag_common.h" +#include "sleep/TargetSleepTime.h" +#include "sleep/SleepingMainPage.h" +#include "sleep/SleepingPresenter.h" +#include "sleep/SleepingView.h" + +namespace OHOS { + +REGIST_SLICE_PAGE(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_MAIN_PAGE, SleepingMainPage, true); + +static constexpr int16_t SLEEPMAIN_SLEEP_X = 190; +static constexpr int16_t SLEEPMAIN_SLEEP_Y = 50; +static constexpr int16_t SLEEPMAIN_SLEEP_WIDTH = 64; +static constexpr int16_t SLEEPMAIN_SLEEP_HEIGHT = 38; +static constexpr int16_t SLEEPMAIN_SLEEP_FONT_SIZE = 38; +static constexpr int16_t SLEEPMAIN_NORECORD_X = 179; +static constexpr int16_t SLEEPMAIN_NORECORD_Y = 179; +static constexpr int16_t SLEEPMAIN_NORECORD_WIDTH = 96; +static constexpr int16_t SLEEPMAIN_NORECORD_HEIGHT = 48; +static constexpr int16_t SLEEPMAIN_NORECORD_FONT_SIZE = 38; +static constexpr int16_t SLEEPMAIN_TIPS_X = 93; +static constexpr int16_t SLEEPMAIN_TIPS_Y = 321; +static constexpr int16_t SLEEPMAIN_TIPS_WIDTH = 188; +static constexpr int16_t SLEEPMAIN_TIPS_HEIGHT = 87; +static constexpr int16_t SLEEPMAIN_TIPS_FONT_SIZE = 24; +static constexpr int16_t SLEEPMAIN_SCORE_X = 164; +static constexpr int16_t SLEEPMAIN_SCORE_Y = 129; +static constexpr int16_t SLEEPMAIN_SCORE_WIDTH = 95; +static constexpr int16_t SLEEPMAIN_SCORE_HEIGHT = 65; +static constexpr int16_t SLEEPMAIN_SCORE_FONT_SIZE = 56; +static constexpr int16_t SLEEPMAIN_MOONNORECORD_X = 154; +static constexpr int16_t SLEEPMAIN_MOONNORECORD_Y = 154; +static constexpr int16_t SLEEPMAIN_SCORETEXT_FONT_SIZE = 21; +static constexpr int16_t SLEEP_SCORE_THRESHOLD_1 = 20; +static constexpr int16_t SLEEP_SCORE_THRESHOLD_2 = 40; +static constexpr int16_t SLEEP_SCORE_THRESHOLD_3 = 60; +static constexpr int16_t SLEEP_SCORE_THRESHOLD_4 = 80; +static constexpr int16_t SLEEP_SCORE_THRESHOLD_5 = 100; +static constexpr int16_t SLEEP_FONT_SIZE_LARGE = 40; +static constexpr int16_t SLEEPMAIN_SCORETEXT_X = 265; +static constexpr int16_t SLEEPMAIN_SCORETEXT_Y = 161; +static constexpr int16_t SLEEP_LABEL_WIDTH = 48; +static constexpr int16_t SLEEP_LABEL_HEIGHT = 29; +static constexpr int16_t SLEEP_TIME_LABEL_WIDTH = 100; +static constexpr int16_t SLEEP_TIME_LABEL_HEIGHT = 50; +static constexpr int16_t SLEEPMAIN_SETTING_X = 280; +static constexpr int16_t SLEEPMAIN_SETTING_Y = 374; +static constexpr int16_t SLEEPMAIN_ACTUALMINUTE_X = 230; +static constexpr int16_t SLEEPMAIN_ACTUALMINUTE_Y = 319; +static constexpr int16_t SLEEPMAIN_ACTUALHOUR_X = 135; +static constexpr int16_t ACTUALHOURS_X = 140; +static constexpr int16_t ACTUALMINUTES_X = 180; +static constexpr int16_t ACTUALMINUTES_Y = 303; +static constexpr int16_t SLEEPMAIN_ACTUALHOURTEXT_X = 170; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEPTIMEHOURS_FONT_SIZE = 32; +static constexpr int16_t SLEEPMAIN_HEIGHT = 50; +static constexpr int16_t SLEEPDETAIL_ACTUALSLEEPTIMINUTES_FONT_SIZE = 40; +static constexpr int16_t SLEEPMAIN_ACTUALMINUTETEXT_X = 280; +static constexpr int16_t SLEEPMAIN_ACTUALH_X = 170; +static constexpr int16_t SLEEPMAIN_ACTUALMINUTETEXT2_X = 270; +static constexpr int16_t SLEEPMAIN_CIR_HIGHT = 444; +static constexpr int16_t SLEEPMAIN_CIR_X = 228; +static constexpr int16_t SLEEPMAIN_CIR_Y = 228; +static constexpr int16_t SLEEPMAIN_CIR_RADIUS = 215; +static constexpr int16_t SLEEPMAIN_CIR_ANGLE = 360; +static constexpr int16_t SLEEPMAIN_CIR_RANGE = 100; +static constexpr int16_t SLEEPMAIN_CIR_LINE_WIDTH = 10; +static constexpr int16_t SLEEPMAIN_SCORE = 100; +static constexpr int16_t SLEEPMAIN_RATE = 100; +static constexpr float MINUTE_HOUR = 60.0f; +static constexpr int16_t TARGETTIMETEXT_Y = 363; +static constexpr int16_t TARGETTIMEBUTTON_X = 137; +static constexpr int16_t TARGETTIMETEXT_WIDTH = 184; +static constexpr int16_t TARGETTIMETEXT_HIGHT = 46; +static constexpr int16_t MAIN_SLEEP_COLOR_R = 181; +static constexpr int16_t MAIN_SLEEP_COLOR_G = 402; +static constexpr int16_t MAIN_SLEEP_COLOR_B = 255; +static constexpr int16_t MAIN_SLEEP_OPT = 110; +static constexpr int16_t MAIN_SLEEP_RANGE = 10; +static constexpr int16_t MAIN_SLEEP_POSX_2 = 2; +static constexpr int16_t MAIN_SLEEP_POSX_3 = 3; +static constexpr int16_t MAIN_SLEEP_POSX_4 = 4; +static constexpr int16_t MAIN_SLEEP_MOON_POSX = 198; +static constexpr int16_t MAIN_SLEEP_SCORE_HEIGHT = 192; +static constexpr int16_t MAIN_SLEEP_SCORE_X = 131; +static constexpr int16_t MAIN_SLEEP_SCORE_Y = 200; +static constexpr int16_t MAIN_SLEEP_STAR1_X = 145; +static constexpr int16_t MAIN_SLEEP_STAR2_X = 180; +static constexpr int16_t MAIN_SLEEP_STAR3_X = 215; +static constexpr int16_t MAIN_SLEEP_STAR4_X = 250; +static constexpr int16_t MAIN_SLEEP_STAR5_X = 285; +static constexpr int16_t MAIN_SLEEP_STAR_Y = 255; +static constexpr int16_t MAIN_SLEEP_SCORE_TEXT_FONT_SIZE = 55; +static constexpr int16_t MAIN_SLEEP_STAR_NUM = 5; + +int posX[MAIN_SLEEP_STAR_NUM] = {MAIN_SLEEP_STAR1_X, MAIN_SLEEP_STAR2_X, MAIN_SLEEP_STAR3_X, MAIN_SLEEP_STAR4_X, MAIN_SLEEP_STAR5_X}; +int posY = MAIN_SLEEP_STAR_Y; + +SleepingMainPage::SleepingMainPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepingMainPage::SleepingMainPage"); +} + +SleepingMainPage::~SleepingMainPage() +{ + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (imageViewMain != nullptr) { + delete imageViewMain; + imageViewMain = nullptr; + } + + if (sleep != nullptr) { + delete sleep; + sleep = nullptr; + } + + if (moonNoRecord != nullptr) { + delete moonNoRecord; + moonNoRecord = nullptr; + } + + if (moon != nullptr) { + delete moon; + moon = nullptr; + } + + if (noRecord != nullptr) { + delete noRecord; + noRecord = nullptr; + } + + if (tips != nullptr) { + delete tips; + tips = nullptr; + } + + if (sleepScores_ != nullptr) { + delete sleepScores_; + sleepScores_ = nullptr; + } + + if (scoreText != nullptr) { + delete scoreText; + scoreText = nullptr; + } + + if (sleepScore != nullptr) { + delete sleepScore; + sleepScore = nullptr; + } + + if (scoreDisplayPicture1 != nullptr) { + delete scoreDisplayPicture1; + scoreDisplayPicture1 = nullptr; + } + + if (scoreDisplayPicture2 != nullptr) { + delete scoreDisplayPicture2; + scoreDisplayPicture2 = nullptr; + } + + if (scoreDisplayPicture3 != nullptr) { + delete scoreDisplayPicture3; + scoreDisplayPicture3 = nullptr; + } + if (scoreDisplayPicture4 != nullptr) { + delete scoreDisplayPicture4; + scoreDisplayPicture4 = nullptr; + } + + if (scoreDisplayPicture5 != nullptr) { + delete scoreDisplayPicture5; + scoreDisplayPicture5 = nullptr; + } + + if (setting != nullptr) { + delete setting; + setting = nullptr; + } + + if (targetTimeText != nullptr) { + delete targetTimeText; + targetTimeText = nullptr; + } + + if (actualSleepTimeHours != nullptr) { + delete actualSleepTimeHours; + actualSleepTimeHours = nullptr; + } + + if (actualSleepTimeHoursText != nullptr) { + delete actualSleepTimeHoursText; + actualSleepTimeHoursText = nullptr; + } + + if (actualSleepTimeMinutes != nullptr) { + delete actualSleepTimeMinutes; + actualSleepTimeMinutes = nullptr; + } + + if (actualSleepTimeMinutesText != nullptr) { + delete actualSleepTimeMinutesText; + actualSleepTimeMinutesText = nullptr; + } + + if (targetTimeButton != nullptr) { + delete targetTimeButton; + targetTimeButton = nullptr; + } + + if (circleProgress != nullptr) { + delete circleProgress; + circleProgress = nullptr; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepingMainPage::~SleepingMainPage"); +} + +void SleepingMainPage::OnStart(void* data) +{ + group = new UIScrollView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group is nullptr"); + return; + } + group->SetPosition(0, 0); + group->Resize(RESOLUTION_WIDTH, RESOLUTION_HEIGHT); + group->SetViewId("sleepMain"); + + imageViewMain = new UIImageView(); + if (imageViewMain == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "imageViewMain is nullptr"); + return; + } + LOADIMG::LoadImageViewImg(imageViewMain, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_BACKGROUND); + imageViewMain->SetPosition(0, 0, RESOLUTION_WIDTH, RESOLUTION_HEIGHT); + group->Add(imageViewMain); + + if (GetRecord() == false) { + InitNoRecordPage(); + } else { + InitRecordPage(); + } + + group->SetOnDragListener(this); + group->SetDraggable(true); + group->SetTouchable(true); + AddViewToPageContainer(group); +} + +void SleepingMainPage::InitNoRecordPage() +{ + sleep = new UILabel(); + if (sleep == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleep is nullptr"); + return; + } + sleep->SetPosition(SLEEPMAIN_SLEEP_X, SLEEPMAIN_SLEEP_Y); + sleep->Resize(SLEEPMAIN_SLEEP_WIDTH, SLEEPMAIN_SLEEP_HEIGHT); + sleep->SetText("睡眠"); + sleep->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + sleep->SetTextColor(Color::White()); + sleep->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_SLEEP_FONT_SIZE); + sleep->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(sleep); + + moonNoRecord = new UIImageView(); + if (moonNoRecord == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "moonNoRecord is nullptr"); + return; + } + LOADIMG::LoadImageViewImg(moonNoRecord, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_NORECORD_SLEEP); + moonNoRecord->SetPosition(SLEEPMAIN_MOONNORECORD_X, SLEEPMAIN_MOONNORECORD_Y); + group->Add(moonNoRecord); + + noRecord = new UILabel(); + if (noRecord == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "noRecord is nullptr"); + return; + } + noRecord->SetPosition(SLEEPMAIN_NORECORD_X, SLEEPMAIN_NORECORD_Y); + noRecord->Resize(SLEEPMAIN_NORECORD_WIDTH, SLEEPMAIN_NORECORD_HEIGHT); + noRecord->SetText("无记录"); + noRecord->SetTextColor(Color::White()); + noRecord->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_NORECORD_FONT_SIZE); + noRecord->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(noRecord); + + tips = new UILabel(); + if (tips == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "tips is nullptr"); + return; + } + tips->SetPosition(SLEEPMAIN_TIPS_X, SLEEPMAIN_TIPS_Y); + tips->Resize(SLEEPMAIN_TIPS_WIDTH, SLEEPMAIN_TIPS_HEIGHT); + tips->SetText("睡眠时间过短或睡眠中动作幅度大,手表可能检测不到睡眠"); + tips->SetTextColor(Color::White()); + tips->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_TIPS_FONT_SIZE); + tips->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(tips); +} + +void SleepingMainPage::InitRecordPage() +{ + SleepingModel::GetInstance().SendData(); + CircleProgress(); + moon = new UIImageView(); + if (moon == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "moon is nullptr"); + return; + } + + moon->SetPosition(MAIN_SLEEP_MOON_POSX, TARGETTIMETEXT_HIGHT); + LOADIMG::LoadImageViewImg(moon, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_RECORD_SLEEP); + group->Add(moon); + + sleepScores_ = new UILabel(); + if (sleepScores_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleepScores_ is nullptr"); + return; + } + + sleepScores_->SetText(std::to_string(GetSleepingScores()).c_str()); + sleepScores_->SetPosition(SLEEPMAIN_SCORE_X, SLEEPMAIN_SCORE_Y); + sleepScores_->Resize(SLEEPMAIN_SCORE_WIDTH, SLEEPMAIN_SCORE_HEIGHT); + sleepScores_->SetTextColor(Color::White()); + sleepScores_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + sleepScores_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_SCORE_FONT_SIZE); + sleepScores_->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + group->Add(sleepScores_); + + scoreText = new UILabel(); + if (scoreText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "scoreText is nullptr"); + return; + } + scoreText->SetText("分"); + scoreText->SetPosition(SLEEPMAIN_SCORETEXT_X, SLEEPMAIN_SCORETEXT_Y); + scoreText->Resize(MAIN_SLEEP_SCORE_TEXT_FONT_SIZE, SLEEPMAIN_TIPS_FONT_SIZE); + scoreText->SetTextColor(Color::White()); + scoreText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_SCORETEXT_FONT_SIZE); + group->Add(scoreText); + ScoreDisplay(); + sleepScore = new UILabel(); + if (sleepScore == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleepScore is nullptr"); + return; + } + sleepScore->SetText("夜间睡眠得分"); + sleepScore->Resize(MAIN_SLEEP_SCORE_HEIGHT, SLEEPMAIN_NORECORD_HEIGHT); + sleepScore->SetPosition(MAIN_SLEEP_SCORE_X, MAIN_SLEEP_SCORE_Y); + sleepScore->SetTextColor(Color::White()); + sleepScore->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPDETAIL_ACTUALSLEEPTIMEHOURS_FONT_SIZE); + group->Add(sleepScore); + + // 显示具体睡觉时间 + IoadActualSleepTime(SleepingModel::GetInstance().GetSleepTime()); + + // 加载目标按钮 + IoadTargetTimeButton(SleepingModel::GetInstance().GetTime()); +} +void SleepingMainPage::InitScoreDisplayPicture() +{ + if (scoreDisplayPicture1 == nullptr) { + scoreDisplayPicture1 = new UIImageView(); + } + scoreDisplayPicture1->SetPosition(posX[0], posY); + group->Add(scoreDisplayPicture1); + + if (scoreDisplayPicture2 == nullptr) { + scoreDisplayPicture2 = new UIImageView(); + } + scoreDisplayPicture2->SetPosition(posX[1], posY); + group->Add(scoreDisplayPicture2); + + if (scoreDisplayPicture3 == nullptr) { + scoreDisplayPicture3 = new UIImageView(); + } + scoreDisplayPicture3->SetPosition(posX[MAIN_SLEEP_POSX_2], posY); + group->Add(scoreDisplayPicture3); + + if (scoreDisplayPicture4 == nullptr) { + scoreDisplayPicture4 = new UIImageView(); + } + scoreDisplayPicture4->SetPosition(posX[MAIN_SLEEP_POSX_3], posY); + group->Add(scoreDisplayPicture4); + + if (scoreDisplayPicture5 == nullptr) { + scoreDisplayPicture5 = new UIImageView(); + } + + scoreDisplayPicture5->SetPosition(posX[MAIN_SLEEP_POSX_4], posY); + group->Add(scoreDisplayPicture5); +} + +void SleepingMainPage::ScoreDisplay() +{ + InitScoreDisplayPicture(); + if (GetSleepingScores() < SLEEP_SCORE_THRESHOLD_1) { + LOADIMG::LoadImageViewImg(scoreDisplayPicture1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture5, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + } else if (GetSleepingScores() >= SLEEP_SCORE_THRESHOLD_1 && GetSleepingScores() < SLEEP_SCORE_THRESHOLD_2) { + LOADIMG::LoadImageViewImg(scoreDisplayPicture1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture5, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + } else if (GetSleepingScores() >= SLEEP_SCORE_THRESHOLD_2 && GetSleepingScores() < SLEEP_SCORE_THRESHOLD_3) { + LOADIMG::LoadImageViewImg(scoreDisplayPicture1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture5, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + } else if (GetSleepingScores() >= SLEEP_SCORE_THRESHOLD_3 && GetSleepingScores() < SLEEP_SCORE_THRESHOLD_4) { + LOADIMG::LoadImageViewImg(scoreDisplayPicture1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + LOADIMG::LoadImageViewImg(scoreDisplayPicture5, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + } else if (GetSleepingScores() >= SLEEP_SCORE_THRESHOLD_4 && GetSleepingScores() < SLEEP_SCORE_THRESHOLD_5) { + LOADIMG::LoadImageViewImg(scoreDisplayPicture1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture5, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_GRAY); + } else if (GetSleepingScores() == SLEEP_SCORE_THRESHOLD_5) { + LOADIMG::LoadImageViewImg(scoreDisplayPicture1, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture2, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture3, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture4, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + LOADIMG::LoadImageViewImg(scoreDisplayPicture5, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_STAR_YELLOW); + } +} + +void SleepingMainPage::InitSleepTimeLabel() +{ + actualSleepTimeHours = new UILabel(); + if (actualSleepTimeHours == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeHours is nullptr"); + return; + } + + actualSleepTimeHours->SetTextColor(Color::White()); + actualSleepTimeHours->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEP_FONT_SIZE_LARGE); + actualSleepTimeHours->SetVisible(false); + + actualSleepTimeHoursText = new UILabel(); + if (actualSleepTimeHoursText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeHoursText is nullptr"); + return; + } + actualSleepTimeHoursText->SetText("小时"); + actualSleepTimeHoursText->Resize(SLEEP_LABEL_WIDTH, SLEEP_LABEL_HEIGHT); + actualSleepTimeHoursText->SetTextColor(Color::White()); + actualSleepTimeHoursText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_TIPS_FONT_SIZE); + actualSleepTimeHoursText->SetVisible(false); + + actualSleepTimeMinutes = new UILabel(); + if (actualSleepTimeMinutes == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeMinutes is nullptr"); + return; + } + + actualSleepTimeMinutes->Resize(SLEEP_TIME_LABEL_WIDTH, SLEEP_TIME_LABEL_HEIGHT); + actualSleepTimeMinutes->SetTextColor(Color::White()); + actualSleepTimeMinutes->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEP_FONT_SIZE_LARGE); + actualSleepTimeMinutes->SetVisible(false); + + actualSleepTimeMinutesText = new UILabel(); + if (actualSleepTimeMinutesText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "actualSleepTimeMinutesText is nullptr"); + return; + } + + actualSleepTimeMinutesText->SetText("分钟"); + actualSleepTimeMinutesText->Resize(SLEEP_LABEL_WIDTH, SLEEP_LABEL_HEIGHT); + actualSleepTimeMinutesText->SetTextColor(Color::White()); + actualSleepTimeMinutesText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_TIPS_FONT_SIZE); + actualSleepTimeMinutesText->SetVisible(false); +} + +void SleepingMainPage::IoadTargetTimeButton(std::tuple timeTuple) +{ + uint32_t hours = std::get<0>(timeTuple); + uint32_t minutes = std::get<1>(timeTuple); + + std::string str = ""; + if ((hours == 0) && (minutes != 0)) { + str = std::to_string(minutes) + "分钟"; + } else if ((hours != 0) && (minutes == 0)) { + str = std::to_string(hours) + "小时"; + } else if ((hours != 0) && (minutes != 0)) { + if (minutes < MAIN_SLEEP_RANGE && hours >= MAIN_SLEEP_RANGE) { + str = " " + std::to_string(hours) + ":0" + std::to_string(minutes); + } else if (hours < MAIN_SLEEP_RANGE && minutes >= MAIN_SLEEP_RANGE) { + str = " 0"+ std::to_string(hours) + ":" + std::to_string(minutes); + } else if (minutes < MAIN_SLEEP_RANGE && hours < MAIN_SLEEP_RANGE) { + str = " 0" + std::to_string(hours) + ":0" + std::to_string(minutes); + } else if (minutes >= MAIN_SLEEP_RANGE && hours >= MAIN_SLEEP_RANGE) { + str = " " + std::to_string(hours) + ":" + std::to_string(minutes); + } + } + targetTimeButton = new UILabelButton(); + if (targetTimeButton == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "targetTimeButton is nullptr"); + return; + } + targetTimeButton->SetPosition(TARGETTIMEBUTTON_X, TARGETTIMETEXT_Y); + targetTimeButton->SetViewId("targetTime"); + targetTimeButton->SetOnClickListener(this); + targetTimeButton->SetStyle(STYLE_BACKGROUND_COLOR, + Color::GetColorFromRGBA(MAIN_SLEEP_COLOR_R, MAIN_SLEEP_COLOR_G, + MAIN_SLEEP_COLOR_B, MAIN_SLEEP_OPT).full); + targetTimeButton->SetStyleForState ( + STYLE_BACKGROUND_COLOR, Color::GetColorFromRGBA( + MAIN_SLEEP_COLOR_R, MAIN_SLEEP_COLOR_G, MAIN_SLEEP_COLOR_B, MAIN_SLEEP_OPT).full, UIButton::PRESSED); + targetTimeButton->Resize(TARGETTIMETEXT_WIDTH, TARGETTIMETEXT_HIGHT); + targetTimeButton->SetTextColor(Color::White()); + targetTimeButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_TIPS_FONT_SIZE); + group->Add(targetTimeButton); + + targetTimeText = new UILabel(); + if (targetTimeText == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "targetTimeText is nullptr"); + return; + } + std::string targetText = "目标" + str; + targetTimeText->SetText(targetText.c_str()); + targetTimeText->SetPosition(SLEEPMAIN_MOONNORECORD_X, TARGETTIMETEXT_Y); + targetTimeText->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + targetTimeText->Resize(TARGETTIMETEXT_WIDTH, TARGETTIMETEXT_HIGHT); + targetTimeText->SetTextColor(Color::White()); + targetTimeText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SLEEPMAIN_TIPS_FONT_SIZE); + targetTimeText->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + group->Add(targetTimeText); + + if (setting == nullptr) { + setting = new UIImageView(); + } + setting->SetPosition(SLEEPMAIN_SETTING_X, SLEEPMAIN_SETTING_Y); + LOADIMG::LoadImageViewImg(setting, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_SETTING); + group->Add(setting); +} + +void SleepingMainPage::IoadActualSleepTime(std::tuple timeTuple) +{ + InitSleepTimeLabel(); + uint32_t hours = std::get<0>(timeTuple); + uint32_t minutes = std::get<1>(timeTuple); + + if ((hours == 0) && (minutes != 0)) { + actualSleepTimeMinutes->SetPosition(ACTUALMINUTES_X, ACTUALMINUTES_Y); + actualSleepTimeMinutes->SetVisible(true); + actualSleepTimeMinutes->SetText(std::to_string(minutes).c_str()); + group->Add(actualSleepTimeMinutes); + + actualSleepTimeMinutesText->SetPosition(SLEEPMAIN_ACTUALMINUTE_X, SLEEPMAIN_ACTUALMINUTE_Y); + actualSleepTimeMinutesText->SetVisible(true); + group->Add(actualSleepTimeMinutesText); + } else if ((hours != 0) && (minutes == 0)) { + actualSleepTimeHours->SetPosition(ACTUALMINUTES_X, ACTUALMINUTES_Y); + actualSleepTimeHours->Resize(SLEEPMAIN_HEIGHT, SLEEPMAIN_HEIGHT); + + actualSleepTimeHours->SetVisible(true); + actualSleepTimeHours->SetText(std::to_string(hours).c_str()); + group->Add(actualSleepTimeHours); + + actualSleepTimeHoursText->SetPosition(SLEEPMAIN_ACTUALMINUTE_X, SLEEPMAIN_ACTUALMINUTE_Y); + actualSleepTimeHoursText->SetVisible(true); + group->Add(actualSleepTimeHoursText); + } else if ((hours != 0) && (minutes != 0)) { + actualSleepTimeHours->SetPosition(SLEEPMAIN_ACTUALHOUR_X, ACTUALMINUTES_Y); + actualSleepTimeHours->Resize(SLEEPMAIN_HEIGHT, SLEEPMAIN_HEIGHT); + + actualSleepTimeHours->SetVisible(true); + actualSleepTimeHours->SetText(std::to_string(hours).c_str()); + group->Add(actualSleepTimeHours); + + actualSleepTimeHoursText->SetPosition(SLEEPMAIN_ACTUALHOURTEXT_X, SLEEPMAIN_ACTUALMINUTE_Y); + actualSleepTimeHoursText->SetVisible(true); + group->Add(actualSleepTimeHoursText); + + actualSleepTimeMinutes->SetPosition(SLEEPMAIN_ACTUALMINUTE_X, ACTUALMINUTES_Y); + actualSleepTimeMinutes->SetVisible(true); + actualSleepTimeMinutes->SetText(std::to_string(minutes).c_str()); + group->Add(actualSleepTimeMinutes); + + actualSleepTimeMinutesText->SetPosition(SLEEPMAIN_ACTUALMINUTETEXT_X, SLEEPMAIN_ACTUALMINUTE_Y); + actualSleepTimeMinutesText->SetVisible(true); + group->Add(actualSleepTimeMinutesText); + } else if ((hours == 0) && (minutes == 0)) { + actualSleepTimeHours->SetPosition(ACTUALHOURS_X, ACTUALMINUTES_Y); + actualSleepTimeHours->Resize(SLEEPMAIN_HEIGHT, SLEEPMAIN_HEIGHT); + actualSleepTimeHours->SetVisible(true); + actualSleepTimeHours->SetText("--"); + group->Add(actualSleepTimeHours); + + actualSleepTimeHoursText->SetPosition(ACTUALMINUTES_X, SLEEPMAIN_ACTUALMINUTE_Y); + actualSleepTimeHoursText->SetVisible(true); + group->Add(actualSleepTimeHoursText); + + actualSleepTimeMinutes->SetPosition(SLEEPMAIN_ACTUALMINUTE_X, ACTUALMINUTES_Y); + actualSleepTimeMinutes->SetVisible(true); + actualSleepTimeMinutes->SetText("--"); + group->Add(actualSleepTimeMinutes); + + actualSleepTimeMinutesText->SetPosition(SLEEPMAIN_ACTUALMINUTETEXT2_X, SLEEPMAIN_ACTUALMINUTE_Y); + actualSleepTimeMinutesText->SetVisible(true); + group->Add(actualSleepTimeMinutesText); + } +} + +void SleepingMainPage::CircleProgress() +{ + if (circleProgress == nullptr) { + circleProgress = new UICircleProgress(); + } + circleProgress->SetPosition(0, 0); + circleProgress->Resize(SLEEPMAIN_CIR_HIGHT, SLEEPMAIN_CIR_HIGHT); + + circleProgress->SetCenterPosition(SLEEPMAIN_CIR_X, SLEEPMAIN_CIR_Y); + circleProgress->SetRadius(SLEEPMAIN_CIR_RADIUS); + circleProgress->SetStartAngle(0); + circleProgress->SetEndAngle(SLEEPMAIN_CIR_ANGLE); + circleProgress->SetRange(0, SLEEPMAIN_CIR_RANGE); + circleProgress->SetBackgroundStyle(STYLE_LINE_COLOR, 0xFF6f29a0); + circleProgress->SetForegroundStyle(STYLE_LINE_COLOR, 0xFFB566FF); + circleProgress->SetBackgroundStyle(STYLE_LINE_WIDTH, SLEEPMAIN_CIR_LINE_WIDTH); + circleProgress->SetForegroundStyle(STYLE_LINE_WIDTH, SLEEPMAIN_CIR_LINE_WIDTH); + + group->Add(circleProgress); + circleProgress->SetValue(GetSleepingScores()); + circleProgress->Invalidate(); +} + +uint32_t SleepingMainPage::GetSleepingScores() +{ + uint32_t hours = SleepingModel::GetInstance().GetSleepTimeHours(); + uint32_t minutes = SleepingModel::GetInstance().GetSleepTimeMinutes(); + std::tuple timeTuple = SleepingModel::GetInstance().GetTime(); + uint32_t timeHours = std::get<0>(timeTuple); + uint32_t timeMinutes = std::get<1>(timeTuple); + if (((hours * MINUTE_HOUR) + minutes) > ((timeHours * MINUTE_HOUR) + timeMinutes)) { + return SLEEPMAIN_SCORE; + } else { + float score = ((hours * MINUTE_HOUR) + minutes) / ((timeHours * MINUTE_HOUR) + timeMinutes); + return uint32_t(score * SLEEPMAIN_RATE); + } +} + +bool SleepingMainPage::GetRecord() +{ + if (SleepingModel::GetInstance().GetRecord()) { + return true; + } + return false; +} + +bool SleepingMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(view); + if (strcmp(view.GetViewId(), "targetTime") == 0) { + NativeAbility::GetInstance().SwitchSlice(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_TARGET_PAGE); + } + return true; +} + +bool SleepingMainPage::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepingMainPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + } else if (event.GetDragDirection() == DragEvent::DIRECTION_BOTTOM_TO_TOP) { + NativeAbility::GetInstance().SwitchSlice(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_DEATIL_PAGE); + } + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingModel.cpp new file mode 100644 index 000000000..fc254503d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingModel.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingModel + * Created: 2025-06-05 + */ + +#include +#include +#include +#include +#include "main/HealthModel.h" +#include "uiservice/ui_service.h" +#include "wearable_log.h" +#include "NativeAbility.h" +#include "ui_test_group.h" +#include "graphic_timer.h" +#include "ohos_timer.h" +#include "wearable_onlinelog.h" +#include "sleep/SleepingModel.h" + +namespace OHOS { +static constexpr uint64_t SLEEPMODEL_MINUTE_HOUR = 60; +static constexpr uint64_t SLEEPMODEL_HOUR = 23; +static constexpr uint64_t SLEEPMODEL_MINUTE = 59; +static constexpr uint64_t SLEEPMODEL_ERROR = 100; +static constexpr uint64_t SLEEPMODEL_DEEP = 4; +static constexpr uint64_t SLEEPMODEL_LIGHT = 3; +static constexpr uint64_t SLEEPMODEL_EYEMOVE = 2; +static constexpr uint64_t SLEEPMODEL_EIGHT_HOUR = 480; + +SleepingModel::SleepingModel() +{ + SetSleepData(); + SetSoberingTime(); + SetRapidEyeMovementTime(); + SetLightSleepTime(); + SetDeepSleepTime(); + SetTime(SLEEPMODEL_EIGHT_HOUR); +} + +SleepingModel::~SleepingModel() +{ +} + +bool SleepingModel::GetRecord() +{ + if (sleepDataVector.empty() == true) { + return false; + } + return true; +} + +uint8_t* SleepingModel::SerializeSleepData(const SleepData* sleepData, size_t* outSize) +{ + if (sleepData == nullptr) { + return nullptr; + } + size_t dataSize = sizeof(SleepData); + *outSize = dataSize; + uint8_t* buffer = new uint8_t[dataSize]; + uint8_t isSendValue = sleepData->isSend ? 1 : 0; + memcpy_s(buffer, sizeof(isSendValue), &isSendValue, sizeof(isSendValue)); + memcpy_s(buffer + offsetof(SleepData, date), sizeof(sleepData->date), + sleepData->date, sizeof(sleepData->date)); + memcpy_s(buffer + offsetof(SleepData, type), sizeof(sleepData->type), + &sleepData->type, sizeof(sleepData->type)); + memcpy_s(buffer + offsetof(SleepData, start), sizeof(sleepData->start), + sleepData->start, sizeof(sleepData->start)); + memcpy_s(buffer + offsetof(SleepData, end), sizeof(sleepData->end), + sleepData->end, sizeof(sleepData->end)); + memcpy_s(buffer + offsetof(SleepData, sleepStart), sizeof(sleepData->sleepStart), + sleepData->sleepStart, sizeof(sleepData->sleepStart)); + memcpy_s(buffer + offsetof(SleepData, sleepEnd), sizeof(sleepData->sleepEnd), + sleepData->sleepEnd, sizeof(sleepData->sleepEnd)); + return buffer; +} + +void SleepingModel::SendData() +{ +#ifndef _WIN32 + // 发送数据 + size_t dataSize; + for (int i = 0; i < sleepDataVector.size(); i++) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "send Date number: %d\n", i+1); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "send front isSend: %s\n\n", + sleepDataVector[i].isSend ? "true" : "false"); + if (sleepDataVector[i].isSend == true) { + continue; + } + PrintSleepData(&sleepDataVector[i]); + uint8_t* serializedData = SerializeSleepData(&sleepDataVector[i], &dataSize); + errcode_t ret = uapi_diag_service_send_log(msg_center_get_trans_channel(), + MSGCENTER_TYPE_ID_SLEEP_DATA, serializedData, dataSize); + delete[] serializedData; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MSGCENTER_TYPE_ID_SLEEP_DATA ret = %d", ret); + if (ret == 0) { + sleepDataVector[i].isSend = true; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "isSend after: %s\n\n", sleepDataVector[i].isSend ? "true" : "false"); + } +#endif +} + +void SleepingModel::SetSleepData() +{ +#ifndef _WIN32 + sleepDataVector.push_back({ + false, "2025-06-03", 4, "2025-06-03 00:00:00", "2025-06-03 00:30:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); + sleepDataVector.push_back({ + false, "2025-06-03", 2, "2025-06-03 00:30:00", "2025-06-03 03:00:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); + sleepDataVector.push_back({ + false, "2025-06-03", 3, "2025-06-03 03:00:00", "2025-06-03 03:30:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); + sleepDataVector.push_back({ + false, "2025-06-03", 1, "2025-06-03 03:30:00", "2025-06-03 05:30:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); + sleepDataVector.push_back({ + false, "2025-06-03", 3, "2025-06-03 05:30:00", "2025-06-03 06:00:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); + sleepDataVector.push_back({ + false, "2025-06-03", 2, "2025-06-03 06:00:00", "2025-06-03 07:30:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); + sleepDataVector.push_back({ + false, "2025-06-03", 4, "2025-06-03 07:30:00", "2025-06-03 07:50:00", + "2025-06-03 00:00:00", "2025-06-03 07:50:00" + }); +#endif +} + +void SleepingModel::PrintSleepData(const SleepData *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "isSend: %s\n\n", data->isSend ? "true" : "false"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PrintSleepData Date: %s\n", data->date); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Sleep type: %u\n", data->type); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Start: %s\n", data->start); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "End: %s\n", data->end); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Sleep Start: %s\n", data->sleepStart); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Sleep End: %s\n", data->sleepEnd); +} + +SleepingModel &SleepingModel::GetInstance() +{ + static SleepingModel instance; + return instance; +} + +std::tuple SleepingModel::GetSoberingTime() +{ + return MinutesToHours(soberingTime); +} + +std::tuple SleepingModel::GetRapidEyeMovementTime() +{ + return MinutesToHours(eyeMoveTime); +} + +std::tuple SleepingModel::GetLightSleepTime() +{ + return MinutesToHours(lightTime); +} + +std::tuple SleepingModel::GetDeepSleepTime() +{ + return MinutesToHours(deepTime); +} + +std::tuple SleepingModel::GetSleepTime() +{ + return MinutesToHours(GetTotalSleepTime()); +} + +std::tuple SleepingModel::MinutesToHours(uint32_t minutes) +{ + if (minutes == 0) { + return std::make_tuple(0, 0); + } + int hours = minutes / SLEEPMODEL_MINUTE_HOUR; + int remainingMinutes = minutes % SLEEPMODEL_MINUTE_HOUR; + + if (hours > SLEEPMODEL_HOUR || remainingMinutes > SLEEPMODEL_MINUTE) { + return std::make_tuple(SLEEPMODEL_ERROR, 0); + } + + return std::make_tuple(hours, remainingMinutes); +} + +uint32_t SleepingModel::GetSleepTimeHours() +{ + std::tuple timeTuple = GetSleepTime(); + return std::get<0>(timeTuple); +} + +uint32_t SleepingModel::GetSleepTimeMinutes() +{ + std::tuple timeTuple = GetSleepTime(); + return std::get<1>(timeTuple); +} + +void SleepingModel::SetTime(uint32_t minute) +{ + sleepTarget = minute; +} + +std::tuple SleepingModel::GetTime() +{ + return MinutesToHours(sleepTarget); +} + +uint32_t SleepingModel::TimeDiffInMinutes(const std::string& timeStr1, const std::string& timeStr2) +{ + std::tm tm1 = {}; + std::tm tm2 = {}; + + std::istringstream iss1(timeStr1); + std::istringstream iss2(timeStr2); + + iss1 >> std::get_time(&tm1, "%Y-%m-%d %H:%M:%S"); + if (iss1.fail()) { + return -1; + } + + iss2 >> std::get_time(&tm2, "%Y-%m-%d %H:%M:%S"); + if (iss2.fail()) { + return -1; + } + + std::time_t t1 = std::mktime(&tm1); + std::time_t t2 = std::mktime(&tm2); + if (t1 == -1 || t2 == -1) { + return -1; + } + + double diff_seconds = std::difftime(t2, t1); + return static_cast(diff_seconds / SLEEPMODEL_MINUTE_HOUR); +} + +// 遍历vector中的结构体 获取对应类型的时间差 +uint32_t SleepingModel::GetDetailData(int type) +{ + uint32_t min = 0; + for (size_t i = 0; i < sleepDataVector.size(); ++i) { + if (sleepDataVector[i].type == type) { + min += TimeDiffInMinutes(sleepDataVector[i].start, sleepDataVector[i].end); + } + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetDetailData type: %d\n", type); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetDetailData min: %d\n", min); + return min; +} + +// 获取总睡觉时间的时间差 +uint32_t SleepingModel::GetTotalSleepTime() +{ + uint32_t time = TimeDiffInMinutes(sleepDataVector[0].sleepStart, sleepDataVector[0].sleepEnd); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetTotalSleepTime time: %d\n", time); + return time; +} + +void SleepingModel::SetSoberingTime() +{ + soberingTime = GetDetailData(SLEEPMODEL_DEEP); +} +void SleepingModel::SetRapidEyeMovementTime() +{ + eyeMoveTime=GetDetailData(SLEEPMODEL_LIGHT); +} +void SleepingModel::SetLightSleepTime() +{ + lightTime = GetDetailData(SLEEPMODEL_EYEMOVE); +} +void SleepingModel::SetDeepSleepTime() +{ + deepTime = GetDetailData(1); +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingPresenter.cpp new file mode 100644 index 000000000..e1b9bf839 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/SleepingPresenter.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SleepingPresenter + * Created: 2025-06-05 + */ + +#include "NativeRegisterManager.h" +#include "sleep/SleepingView.h" +#include "sleep/SleepingPresenter.h" + +namespace OHOS { +REGIST_MENU(VIEW_SLEEPING, SleepingView, SleepingPresenter, SLEEP_ICON, PNG_APPLIST_DEFAULT_IMG, "睡眠"); +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/TargetSleepTime.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/TargetSleepTime.cpp new file mode 100644 index 000000000..4eab1f32f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sleep/src/TargetSleepTime.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetSleepTime + * Created: 2025-06-05 + */ +#include +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "PageTransitionMgr.h" +#include "settings/SetDesktopModel.h" +#include "rebootdevice/RebootModel.h" +#include "common/image_cache_manager.h" +#include "sleep/TargetSleepTime.h" +#include "sleep/SleepingMainPage.h" +#include "sleep/SleepingPresenter.h" +#include "sleep/SleepingView.h" + +namespace OHOS { +constexpr uint8_t BACKGROUND_FONT = 40; +constexpr uint8_t HIGHTLIGHT_FONT = 50; +static constexpr int16_t TARGET_SLEEP_SETTARGET_X = 120; +static constexpr int16_t TARGET_SLEEP_SETTARGET_Y = 40; +static constexpr int16_t TARGET_SLEEP_SETTARGET_WIDTH = 200; +static constexpr int16_t TARGET_SLEEP_SETTARGET_HIGHT = 38; +static constexpr int16_t TARGET_SLEEP_SETTARGET_FONT_SIZE = 32; +static constexpr int16_t TARGET_SLEEP_START_X = 112; +static constexpr int16_t TARGET_SLEEP_START_Y = 347; +static constexpr int16_t TARGET_SLEEP_START_WIDTH = 232; +static constexpr int16_t TARGET_SLEEP_START_HIGHT = 76; +static constexpr int16_t TARGET_SLEEP_PICKER2_X = 270; +static constexpr int16_t TARGET_SLEEP_PICKER_Y = 132; +static constexpr int16_t TARGET_SLEEP_PICKER_WIDTH = 80; +static constexpr int16_t TARGET_SLEEP_PICKER_HIGHT = 188; +static constexpr int16_t TARGET_SLEEP_PICKER_BORDER = 3; +static constexpr int16_t TARGET_SLEEP_PICKER_RADIUS = 11; +static constexpr int16_t TARGET_SLEEP_PICKER_ITEM = 63; +static constexpr int16_t TARGET_SLEEP_PICKER_HOUR = 24; +static constexpr int16_t TARGET_SLEEP_PICKER_MINUTE = 60; +static constexpr int16_t TARGET_SLEEP_PICKER_HOUR_RANGE = 23; +static constexpr int16_t TARGET_SLEEP_PICKER_MINUTE_RANGE = 59; +static constexpr int16_t TARGET_SLEEP_TIMERLABEL_X = 131; +static constexpr int16_t TARGET_SLEEP_TIMERLABEL2_X = 273; +static constexpr int16_t TARGET_SLEEP_TIMERLABEL_Y = 99; +static constexpr int16_t TARGET_SLEEP_TIMERLABEL2_Y = 90; +static constexpr int16_t TARGET_SLEEP_TIMERLABEL_WIDTH = 55; +static constexpr int16_t TARGET_SLEEP_TIMERLABEL_HEIGHT = 30; +static constexpr uint8_t TIMERLABEL_FONT = 24; +static constexpr int16_t TARGET_SLEEP_COLOR_R = 181; +static constexpr int16_t TARGET_SLEEP_COLOR_G = 402; +static constexpr int16_t TARGET_SLEEP_COLOR_B = 255; +static constexpr int16_t NUM_PICKER = 2; +static constexpr int16_t TARGET_SLEEP_PICKER1_X = 115; +static constexpr int16_t TARGET_SLEEP_PICKER2_Y = 255; + +// 时间选择器分钟列 +const char *uiPickerMinute[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", + "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", + "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", + "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", + "51", "52", "53", "54", "55", "56", "57", "58", "59"}; + +// 时间选择器小时列 +const char *uiPickerHour[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", + "15", "16", "17", "18", "19", "20", "21", "22", "23"}; + +REGIST_SLICE_PAGE(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_TARGET_PAGE, TargetSleepTime, false); + +TargetSleepTime::~TargetSleepTime() +{ + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (setTraget != nullptr) { + delete setTraget; + setTraget = nullptr; + } + + if (timerLabel != nullptr) { + delete timerLabel; + timerLabel = nullptr; + } + + if (startButton != nullptr) { + delete startButton; + startButton = nullptr; + } + + if (backgroundImage != nullptr) { + delete backgroundImage; + backgroundImage = nullptr; + } + + for (int i = 0; i < NUM_PICKER; i++) { + if (timerPicker[i] != nullptr) { + delete timerPicker[i]; + timerPicker[i] = nullptr; + } + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetSleepTime::~TargetSleepTime"); +} + +void TargetSleepTime::OnStart(void* data) +{ + group = new UIScrollView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group is nullptr"); + return; + } + group->SetPosition(0, 0); + group->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + + backgroundImage = new UIImageView(); + if (backgroundImage == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backgroundImage is nullptr"); + return; + } + backgroundImage->SetPosition(0, 0); + LOADIMG::LoadImageViewImg(backgroundImage, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_BLACK_BG); + group->Add(backgroundImage); + + setTraget = new UILabel(); + if (setTraget == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "setTraget is nullptr"); + return; + } + setTraget->SetPosition(TARGET_SLEEP_SETTARGET_X, TARGET_SLEEP_SETTARGET_Y); + setTraget->Resize(TARGET_SLEEP_SETTARGET_WIDTH, TARGET_SLEEP_SETTARGET_HIGHT); + setTraget->SetText("设置目标"); + setTraget->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + setTraget->SetTextColor(Color::White()); + setTraget->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TARGET_SLEEP_SETTARGET_FONT_SIZE); + setTraget->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(setTraget); + + TargetTimeButton(); + CreateLabel(); + CreatePicker(); + + group->SetOnDragListener(this); + group->SetDraggable(true); + group->SetTouchable(true); + AddViewToPageContainer(group); +} + +void TargetSleepTime::TargetTimeButton() +{ + startButton = new UILabelButton(); + if (startButton == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "startButton is nullptr"); + return; + } + startButton->SetPosition(TARGET_SLEEP_START_X, TARGET_SLEEP_START_Y); + startButton->Resize(TARGET_SLEEP_START_WIDTH, TARGET_SLEEP_START_HIGHT); + startButton->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + startButton->SetAlign(TEXT_ALIGNMENT_CENTER); + startButton->SetViewId("start"); + + startButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TARGET_SLEEP_SETTARGET_FONT_SIZE); + startButton->SetStyle(STYLE_BACKGROUND_COLOR, Color::Purple().full); + startButton->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::White().full, UIButton::PRESSED); + startButton->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::White().full, UIButton::RELEASED); + startButton->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::INACTIVE); + LOADIMG::LoadBtnImage(startButton, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_SETTIMEBTN, IMAGE_CONVERTER_TOOL_SETTIMEBTN); + startButton->SetText("开始"); + startButton->SetTextColor(Color::White()); + startButton->Enable(); + startButton->SetOnClickListener(this); + group->Add(startButton); +} + +void TargetSleepTime::SetPickerTime() +{ + std::tuple time = SleepingModel::GetInstance().GetTime(); + uint32_t timeHours = std::get<0>(time); + uint32_t timeMinutes = std::get<1>(time); + timerPicker[0] -> SetSelected(timeHours); + timerPicker[1] -> SetSelected(timeMinutes); +} + +void TargetSleepTime::CreatePicker() +{ + int posX[NUM_PICKER] = {TARGET_SLEEP_PICKER1_X, TARGET_SLEEP_PICKER2_Y}; + int posY = TARGET_SLEEP_PICKER_Y; + for (int i = 0; i < NUM_PICKER; i++) { + if (timerPicker[i] == nullptr) { + timerPicker[i] = new UIPicker(); + } + timerPicker[i]->SetPosition(posX[i], posY); + timerPicker[i]->Resize(TARGET_SLEEP_PICKER_WIDTH, TARGET_SLEEP_PICKER_HIGHT); + timerPicker[i]->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + timerPicker[i]->SetStyle(STYLE_BORDER_WIDTH, TARGET_SLEEP_PICKER_BORDER); + timerPicker[i]->SetStyle(STYLE_BORDER_RADIUS, TARGET_SLEEP_PICKER_RADIUS); + timerPicker[i]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[i]->SetItemHeight(TARGET_SLEEP_PICKER_ITEM); + timerPicker[i]->SetLoopState(true); + timerPicker[i]->SetBackgroundFont(DEFAULT_VECTOR_FONT_FILENAME, BACKGROUND_FONT); + timerPicker[i]->SetHighlightFont(DEFAULT_VECTOR_FONT_FILENAME, HIGHTLIGHT_FONT); + timerPicker[i]->SetTextColor(Color::Gray(), Color::White()); + if (i == 0) { + timerPicker[i]->SetValues(uiPickerHour, TARGET_SLEEP_PICKER_HOUR); + timerPicker[i]->SetSelected(TARGET_SLEEP_PICKER_HOUR_RANGE); + } else { + timerPicker[i]->SetValues(uiPickerMinute, TARGET_SLEEP_PICKER_MINUTE); + timerPicker[i]->SetSelected(TARGET_SLEEP_PICKER_MINUTE_RANGE); + } + timerPicker[i]->SetOnClickListener(this); + timerPicker[i]->SetOnDragListener(this); + timerPicker[i]->RegisterSelectedListener(this); + timerPicker[i]->SetDraggable(true); + group->Add(timerPicker[i]); + } + + timerPicker[0]->SetViewId("hourPicker"); + timerPicker[1]->SetViewId("minPicker"); + SetPickerTime(); +} + +bool TargetSleepTime::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + std::string viewId = view.GetViewId(); + if (viewId == "start") { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerMainPage::OnClick viewId == ONE_MIN"); + int hour = std::stoi(uiPickerHour[timerPicker[0]->GetSelected()]); + uint8_t minute = std::stoi(uiPickerMinute[timerPicker[1]->GetSelected()]); + SleepingModel::GetInstance().SetTime((hour * TARGET_SLEEP_PICKER_MINUTE) + minute); + NativeAbility::GetInstance().SwitchSlice(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_MAIN_PAGE); + } + return false; +} + +void TargetSleepTime::CreateLabel() +{ + if (timerLabel == nullptr) { + timerLabel = new UILabel(); + } + timerLabel->SetPosition(TARGET_SLEEP_TIMERLABEL_X, TARGET_SLEEP_TIMERLABEL_Y); + timerLabel->Resize(TARGET_SLEEP_TIMERLABEL_WIDTH, TARGET_SLEEP_TIMERLABEL_HEIGHT); + timerLabel->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + timerLabel->SetText("小时"); + timerLabel->SetStyle(STYLE_BACKGROUND_COLOR, 0xFFB566FF); + timerLabel->SetTextColor(Color::Black()); + timerLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + timerLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIMERLABEL_FONT); + timerLabel->SetVisible(false); + + group->Add(timerLabel); +} + +bool TargetSleepTime::OnDrag(UIView& view, const DragEvent& event) +{ + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetSleepTime::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().SwitchSlice(VIEW_SLEEPING, SLEEPING_PAGES::SLEEPING_MAIN_PAGE); + } + if (view.GetViewId() == "hourPicker") { + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, + Color::GetColorFromRGB(TARGET_SLEEP_COLOR_R, TARGET_SLEEP_COLOR_G, TARGET_SLEEP_COLOR_B).full); + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerLabel->SetVisible(true); + timerLabel->SetPosition(TARGET_SLEEP_TIMERLABEL_X, TARGET_SLEEP_TIMERLABEL2_Y); + timerLabel->SetText("小时"); + timerLabel->Invalidate(); + } else if (view.GetViewId() == "minPicker") { + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, + Color::GetColorFromRGB(TARGET_SLEEP_COLOR_R, TARGET_SLEEP_COLOR_G, TARGET_SLEEP_COLOR_B).full); + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerLabel->SetVisible(true); + timerLabel->SetPosition(TARGET_SLEEP_TIMERLABEL2_X, TARGET_SLEEP_TIMERLABEL2_Y); + timerLabel->SetText("分钟"); + timerLabel->Invalidate(); + } + return true; +} + +void TargetSleepTime::OnPickerStoped(UIPicker& picker) +{ + if (picker.GetViewId() == "hourPicker") { + uint16_t hour = picker.GetSelected(); + picker.SetStyle(STYLE_BORDER_COLOR, + Color::GetColorFromRGB(TARGET_SLEEP_COLOR_R, TARGET_SLEEP_COLOR_G, TARGET_SLEEP_COLOR_B).full); + picker.Invalidate(); + if ((hour == 0) && (timerPicker[1]->GetSelected() == 0)) { + startButton->SetText(""); + startButton->Disable(); + LOADIMG::LoadBtnImage(startButton, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_START_GRAY, + IMAGE_CONVERTER_TOOL_START_GRAY); + } else { + startButton->SetText("开始"); + startButton->SetTextColor(Color::White()); + startButton->Enable(); + LOADIMG::LoadBtnImage(startButton, SLEEP_IMAGE, + IMAGE_CONVERTER_TOOL_SETTIMEBTN, IMAGE_CONVERTER_TOOL_SETTIMEBTN); + } + timerLabel->SetVisible(true); + timerLabel->SetPosition(TARGET_SLEEP_TIMERLABEL_X, TARGET_SLEEP_TIMERLABEL2_Y); + timerLabel->SetText("小时"); + timerLabel->Invalidate(); + } else { + uint16_t minute = picker.GetSelected(); + picker.SetStyle(STYLE_BORDER_COLOR, + Color::GetColorFromRGB(TARGET_SLEEP_COLOR_R, TARGET_SLEEP_COLOR_G, TARGET_SLEEP_COLOR_B).full); + picker.Invalidate(); + if ((minute == 0) && (timerPicker[0]->GetSelected() == 0)) { + startButton->SetText(""); + startButton->Disable(); + LOADIMG::LoadBtnImage(startButton, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_START_GRAY, + IMAGE_CONVERTER_TOOL_START_GRAY); + } else { + startButton->SetText("开始"); + startButton->SetTextColor(Color::White()); + startButton->Enable(); + LOADIMG::LoadBtnImage(startButton, SLEEP_IMAGE, IMAGE_CONVERTER_TOOL_SETTIMEBTN, + IMAGE_CONVERTER_TOOL_SETTIMEBTN); + } + timerLabel->SetVisible(true); + timerLabel->SetPosition(TARGET_SLEEP_TIMERLABEL2_X, TARGET_SLEEP_TIMERLABEL2_Y); + timerLabel->SetText("分钟"); + timerLabel->Invalidate(); + } +} +} + diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsModel.cpp new file mode 100644 index 000000000..4854d19a9 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsModel.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Sports Model + * Create: 2025-04-28 + */ + +#include "sports/SportsView.h" +#include "sports/SportsModel.h" +#include "samgr_lite.h" +#include "broadcast_feature.h" +#include "broadcast_service.h" +#include "wearable_log.h" +#include "heartrate/HeartModel.h" +#include "device_location.h" + +#ifdef __cplusplus +extern "C" { +#endif + +using namespace OHOS; +static sport_data_t g_sportData = {0}; +static void Notify(void *args, const Topic topic, Request *request); + +Subscriber sportsSubscirber = { + .identity = nullptr, + .args = nullptr, + .Notify = Notify, +}; + +void SportsSubscribeTopic(Topic topic) +{ +#if !defined(_WIN32) + BroadcastApi *broadcastApi = nullptr; + IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); + if (api == nullptr) { + return; + } + int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); + if (result != 0 || broadcastApi == nullptr) { + return; + } + int ret = broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic, &sportsSubscirber); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsSubscribeTopic ret = %d, topic = %u", ret, topic); + broadcastApi->Release((IUnknown *)broadcastApi); +#endif +} + +void SportsUnsubscribeTopic(Topic topic) +{ +#if !defined(_WIN32) + BroadcastApi *broadcastApi = nullptr; + IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); + if (api == nullptr) { + return; + } + int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); + if (result != 0 || broadcastApi == nullptr) { + return; + } + broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic, &sportsSubscirber); + broadcastApi->Release((IUnknown *)broadcastApi); +#endif +} + +static void Notify(void *args, const Topic topic, Request *request) +{ + UNUSED(args); + UNUSED(topic); + if (request == nullptr) { + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "topic=[%d,%d]\n", topic, request->msgId); + SportsView *sportView = SportsView::GetInstance(); + bool active = OHOS::SportsModel::GetInstance()->IsActive(); + if (sportView != nullptr && active) { + if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) { + HeartDatas *sportsInfo = (HeartDatas *)request->data; + g_sportData.heartrate = sportsInfo->perSec; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "heartrate=[%d]\n", g_sportData.heartrate); + sportView->SetHeartRate(g_sportData.heartrate); + } + if (request->msgId == TOPIC_EVENT_STEPDATA_UPDATE) { + g_sportData.step += *(uint32_t *)request->data; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "step=[%d]\n", g_sportData.step); + sportView->SetStep(g_sportData.step); + } + if (request->msgId == TOPIC_EVENT_SPORT_DISTANCE) { + g_sportData.distance += *(uint32_t *)request->data; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "distance=[%d]\n", g_sportData.distance); + sportView->SetDistance(g_sportData.distance); + uint32_t speed = OHOS::SportsModel::GetInstance()->CalculateSpeed(g_sportData.distance); + g_sportData.speed = speed; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "speed=[%d]\n", g_sportData.speed); + sportView->SetSpeed(speed); + } + if (request->msgId == TOPIC_EVENT_LOCATION) { + LocationInfo_t *locationData = (LocationInfo_t *)request->data; + g_sportData.lat = locationData->latitude_; + g_sportData.lng = locationData->longitude_; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "location=[%d,%d]\n", g_sportData.lat, g_sportData.lng); + } + } +} + +#ifdef __cplusplus +} +#endif + +namespace OHOS { + +static constexpr uint16_t MS_ONE_SECONDS = 1000; +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t NUM_TIME_MIN = 60; +static constexpr uint16_t NUM_TIME_HOUR = 3600; +static constexpr uint32_t NUM_TIME_DAY = 86400; + +SportsModel::SportsModel() +{ + InitSportsTimer(); +} + +SportsModel::~SportsModel() +{ + StopSportsTimer(true); + SportsUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); + SportsUnsubscribeTopic(TOPIC_EVENT_STEPDATA_UPDATE); + SportsUnsubscribeTopic(TOPIC_EVENT_SPORT_DISTANCE); + SportsUnsubscribeTopic(TOPIC_EVENT_LOCATION); +} + +SportsModel *SportsModel::GetInstance(void) +{ + static SportsModel instance; + return &instance; +} + +void SportsModel::Init() +{ + SportsSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); + SportsSubscribeTopic(TOPIC_EVENT_STEPDATA_UPDATE); + SportsSubscribeTopic(TOPIC_EVENT_SPORT_DISTANCE); + SportsSubscribeTopic(TOPIC_EVENT_LOCATION); +} + +std::string SportsModel::CountingSportsTime() +{ + std::string strSportTime; + std::string hours; + std::string minute; + std::string seconds; + if (uiSportTime_ >= NUM_TIME_DAY) { + uiSportTime_ = 0; + } + int hour = uiSportTime_ / NUM_TIME_HOUR; + int min = (uiSportTime_ % NUM_TIME_HOUR) / NUM_TIME_MIN; + int sec = (uiSportTime_ % NUM_TIME_HOUR) % NUM_TIME_MIN; + if (hour >= 0 && hour < NUM_TEN) { + hours = "0" + std::to_string(hour); + } else { + hours = std::to_string(hour); + } + if (min >= 0 && min < NUM_TEN) { + minute = "0" + std::to_string(min); + } else { + minute = std::to_string(min); + } + if (sec >= 0 && sec < NUM_TEN) { + seconds = "0" + std::to_string(sec); + } else { + seconds = std::to_string(sec); + } + + strSportTime = hours + ":" + minute + ":" + seconds; + return strSportTime; +} + +void SportsModel::IncrSportsTime() +{ + uiSportTime_++; +} + +/* 定时器回调函数 */ +static void SportsTimerCallback(void *data) +{ + (void)data; + SportsModel::GetInstance()->IncrSportsTime(); + SportsView *view = SportsView::GetInstance(); + if (view != nullptr) { + std::string sportTime = SportsModel::GetInstance()->CountingSportsTime(); + view->SetTime(sportTime.c_str()); + } +} + +/* 创建定时器 */ +void SportsModel::InitSportsTimer() +{ + if (pGraphicTimer_ != nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SportsModel::InitSportsTimer GraphicTimer already exists!!"); + return; + } + uint32_t tick = GetOSTick(MS_ONE_SECONDS); + pGraphicTimer_ = new GraphicTimer(tick, SportsTimerCallback, nullptr, true); + if (pGraphicTimer_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SportsModel::InitSportsTimer new GraphicTimer failed!!"); + return; + } +} + +/* 开启定时器 */ +bool SportsModel::StartSportsTimer() +{ + if (pGraphicTimer_ != nullptr) { + bool retTimer = pGraphicTimer_->Start(); + if (!retTimer) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StartSportsTimer GraphicTimer Start failed!!"); + if (pGraphicTimer_ != nullptr) { + delete pGraphicTimer_; + pGraphicTimer_ = nullptr; + } + return false; + } + isActive_ = true; + return true; + } + return false; +} + +/* 关闭定时器 */ +void SportsModel::StopSportsTimer(bool isDelete) +{ + if (pGraphicTimer_ != nullptr) { + pGraphicTimer_->Stop(); + isActive_ = false; + if (isDelete) { + delete pGraphicTimer_; + pGraphicTimer_ = nullptr; + uiSportTime_ = 0; + } + } +} + +bool SportsModel::IsActive() +{ + return isActive_; +} + +sport_data_t *SportsModel::GetSportsData() +{ + return &g_sportData; +} + +void SportsModel::ResetSportsData() +{ + uiSportTime_ = 0; + memset_s(&g_sportData, sizeof(sport_data_t), 0, sizeof(sport_data_t)); +} + +uint32_t SportsModel::CalculateSpeed(uint32_t distance) +{ + uint32_t speed_multiply100 = 0; + if (uiSportTime_ != 0) { + speed_multiply100 = (distance * NUM_TIME_HOUR) / (uiSportTime_ * NUM_TEN); + } + return speed_multiply100; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsPresenter.cpp new file mode 100644 index 000000000..363bf930f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsPresenter.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SPorts Presenter + * Create: 2025-04-28 + */ + +#include "sports/SportsPresenter.h" +#include "sports/SportsView.h" +#include "sports/SportsModel.h" +#include "wearable_log.h" +#include "NativeRegisterManager.h" + +namespace OHOS { + +REGIST_SLICE(VIEW_SPORTS, SportsView, SportsPresenter); + +static SportsPresenter *g_pSportsPresenter = nullptr; + +SportsPresenter::SportsPresenter() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsPresenter::SportsPresenter"); + g_pSportsPresenter = this; +} + +SportsPresenter::~SportsPresenter() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsPresenter::~SportsPresenter"); + g_pSportsPresenter = nullptr; +} + +SportsPresenter *SportsPresenter::GetInstance() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsPresenter GetInstance"); + return g_pSportsPresenter; +} + +bool SportsPresenter::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsPresenter::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsPresenter::OnDrag ChangeSlice"); + NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN_SAMPLE); + } + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsView.cpp new file mode 100644 index 000000000..2b3b50bff --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/sports/src/SportsView.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Sports View + * Create: 2025-04-28 + */ + +#include "sports/SportsView.h" +#include "sports/SportsModel.h" +#include "sports/SportsPresenter.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "uiservice/ui_service.h" + +namespace OHOS { +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t NUM_HUNDRED = 100; +static constexpr uint16_t NUM_THOUSAND = 1000; +static constexpr uint16_t LEFT1_X = 47; +static constexpr uint16_t LEFT1_Y = 100; +static constexpr uint16_t LEFT1_W = 180; +static constexpr uint16_t RIGHT1_X = 227; +static constexpr uint16_t RIGHT1_Y = 100; +static constexpr uint16_t RIGHT1_W = 180; +static constexpr uint16_t LEFT2_X = 47; +static constexpr uint16_t LEFT2_Y = 210; +static constexpr uint16_t LEFT2_W = 180; +static constexpr uint16_t RIGHT2_X = 227; +static constexpr uint16_t RIGHT2_Y = 210; +static constexpr uint16_t RIGHT2_W = 180; +static constexpr uint16_t BOTTOM_X = 92; +static constexpr uint16_t BOTTOM_Y = 320; +static constexpr uint16_t BOTTOM_W = 270; +static constexpr uint16_t LABLE_H = 70; +static constexpr uint16_t UNIT_LEFT1_Y = 150; +static constexpr uint16_t UNIT_RIGHT1_Y = 150; +static constexpr uint16_t UNIT_LEFT2_Y = 260; +static constexpr uint16_t UNIT_RIGHT2_Y = 260; +static constexpr uint16_t UNIT_BOTTOM_Y = 370; +static constexpr uint16_t UNIT_H = 50; +static constexpr uint16_t CONTENT_FONT = 40; +static constexpr uint16_t TITLE_FONT = 30; + +static SportsView *g_pSportsView{nullptr}; +SportsView::SportsView() +{ + ScreenTurnOn(-1); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsView::SportsView"); + g_pSportsView = this; +} + +SportsView::~SportsView() +{ + ScreenTurnOff(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SportsView::~SportsView"); + if (group != nullptr) { + group->RemoveAll(); + } + if (backGround != nullptr) { + delete backGround; + backGround = nullptr; + } + delete group; + group = nullptr; + g_pSportsView = nullptr; +} + +SportsView *SportsView::GetInstance() +{ + return g_pSportsView; +} + +bool SportsView::InitLableView(int index, const char *text, uint16_t x, uint16_t y1, uint16_t w, uint16_t y2) +{ + if (index < SPORT_TIME || index >= SPORT_MAX) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SportsView::InitLableView index param error"); + return false; + } + + ContentLabel[index].SetPosition(x, y1, w, LABLE_H); + ContentLabel[index].SetFont(DEFAULT_VECTOR_FONT_FILENAME, CONTENT_FONT); + ContentLabel[index].SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + ContentLabel[index].SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + group->Add(&ContentLabel[index]); + + TitleLabel[index].SetPosition(x, y2, w, UNIT_H); + TitleLabel[index].SetText(text); + TitleLabel[index].SetFont(DEFAULT_VECTOR_FONT_FILENAME, TITLE_FONT); + TitleLabel[index].SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + TitleLabel[index].SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + group->Add(&TitleLabel[index]); + return true; +} + +void SportsView::InitSportDataLabel() +{ + ContentLabel[SPORT_TIME].SetText("00:00:00"); + ContentLabel[SPORT_SETP].SetText("0"); + ContentLabel[SPORT_DISTANCE].SetText("0.00"); + ContentLabel[SPORT_HEARTRATE].SetText("0"); + ContentLabel[SPORT_SPEED].SetText("0.00"); +} + +bool SportsView::InitView() +{ + bool ret = false; + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return false; + } + group->SetPosition(0, 0); // 0:x; 0:y + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + group->SetStyle(STYLE_BACKGROUND_OPA, 0); + group->SetDraggable(true); + group->SetTouchable(true); + + backGround = new UIImageView(); + if (backGround == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backGroundFirst new fail"); + return false; + } + backGround->SetPosition(0, 0); // 0 : X; 0 : Y + backGround->SetSrc(PNG_WALK_BACK_GROUND); + group->Add(backGround); + + InitSportDataLabel(); + ret = InitLableView(SPORT_SETP, "步数", LEFT1_X, LEFT1_Y, LEFT1_W, UNIT_LEFT1_Y); + if (!ret) { + return false; + } + ret = InitLableView(SPORT_DISTANCE, "距离(km)", RIGHT1_X, RIGHT1_Y, RIGHT1_W, UNIT_RIGHT1_Y); + if (!ret) { + return false; + } + ret = InitLableView(SPORT_HEARTRATE, "心率(bpm)", LEFT2_X, LEFT2_Y, LEFT2_W, UNIT_LEFT2_Y); + if (!ret) { + return false; + } + ret = InitLableView(SPORT_SPEED, "速度(km/h)", RIGHT2_X, RIGHT2_Y, RIGHT2_W, UNIT_RIGHT2_Y); + if (!ret) { + return false; + } + ret = InitLableView(SPORT_TIME, "时间", BOTTOM_X, BOTTOM_Y, BOTTOM_W, UNIT_BOTTOM_Y); + if (!ret) { + return false; + } + UIView::OnDragListener *dragListener = static_cast(SportsPresenter::GetInstance()); + group->SetOnDragListener(dragListener); + + AddViewToRootContainer(group); + return true; +} + +void SportsView::OnStart() +{ + if (!InitView()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SportsView::OnStart InitView fail"); + } + return; +} + +void SportsView::SetStep(uint32_t step) +{ + ContentLabel[SPORT_SETP].SetText(std::to_string(step).c_str()); + ContentLabel[SPORT_SETP].Invalidate(); +} + +void SportsView::SetHeartRate(uint16_t heartrate) +{ + ContentLabel[SPORT_HEARTRATE].SetText(std::to_string(heartrate).c_str()); + ContentLabel[SPORT_HEARTRATE].Invalidate(); +} + +void SportsView::SetDistance(uint32_t distance) +{ + std::string distance_str; + uint32_t distance_int_part = distance / NUM_THOUSAND; + uint32_t distance_fractional_part = (distance % NUM_THOUSAND) / NUM_TEN; + if (distance_fractional_part < NUM_TEN) { + distance_str = std::to_string(distance_int_part) + ".0" + std::to_string(distance_fractional_part); + } else { + distance_str = std::to_string(distance_int_part) + "." + std::to_string(distance_fractional_part); + } + ContentLabel[SPORT_DISTANCE].SetText(distance_str.c_str()); + ContentLabel[SPORT_DISTANCE].Invalidate(); +} + +void SportsView::SetSpeed(uint32_t speed) +{ + std::string speed_str; + uint32_t speed_int_part = speed / NUM_HUNDRED; + uint32_t speed_fractional_part = speed % NUM_HUNDRED; + + if (speed_fractional_part < NUM_TEN) { + speed_str = std::to_string(speed_int_part) + ".0" + std::to_string(speed_fractional_part); + } else { + speed_str = std::to_string(speed_int_part) + "." + std::to_string(speed_fractional_part); + } + + ContentLabel[SPORT_SPEED].SetText(speed_str.c_str()); + ContentLabel[SPORT_SPEED].Invalidate(); +} + +void SportsView::SetTime(const char *time) +{ + ContentLabel[SPORT_TIME].SetText(time); + ContentLabel[SPORT_TIME].Invalidate(); +} + +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchAdapter.cpp new file mode 100644 index 000000000..41959502d --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchAdapter.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchAdapter + * Create: 2025-06-06 + */ +#include "stopwatch/StopwatchAdapter.h" +#include "stopwatch/StopwatchItemView.h" + +namespace OHOS { +StopwatchAdapter::StopwatchAdapter() {} + +StopwatchAdapter::~StopwatchAdapter() +{ + listData_.Clear(); +} + +uint16_t StopwatchAdapter::GetCount(void) +{ + return listData_.Size(); +} + +void StopwatchAdapter::SetData(const List &data) +{ + if (!listData_.IsEmpty()) { + listData_.Clear(); + } + ListNode *node = data.Head(); + while (node != data.End()) { + listData_.PushBack(node->data_); + node = node->next_; + } +} + +UIView *StopwatchAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData_.IsEmpty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData_.Size()) { + return nullptr; + } + + ListNode *node = listData_.Head(); + for (int i = 0; i < index; i++) { + node = node->next_; + } + StopwatchItem itemData = node->data_; + StopwatchItemView *item = nullptr; + if (inView == nullptr) { + item = new StopwatchItemView(); + } else { + item = static_cast(inView); + } + size_t rindex = listData_.Size() - index; + item->SetItemInfo(rindex, itemData); + return item; +} + +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchItemView.cpp new file mode 100644 index 000000000..80c4cfe9f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchItemView.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchItemView + * Create: 2025-06-06 + */ + +#include "UiConfig.h" +#include "stopwatch/StopwatchItemView.h" +#include "common/image_cache_manager.h" +#include "ui_stopwatch_resource.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr uint16_t STOPWATCH_ITEM_WIDTH = 312; +static constexpr uint16_t STOPWATCH_ITEM_HEIGHT = 60; +static constexpr uint16_t STOPWATCH_ITEM_BG_XPOS = 6; +static constexpr uint16_t STOPWATCH_ITEM_BG_YPOS = 8; +static constexpr uint16_t STOPWATCH_ITEM_BG_WIDTH = 300; +static constexpr uint16_t STOPWATCH_ITEM_BG_HEIGHT = 44; +static constexpr uint16_t STOPWATCH_ITEM_BG_OPA = 100; +static constexpr uint16_t STOPWATCH_ITEM_NAME_LABEL_XPOS = 33; +static constexpr uint16_t STOPWATCH_ITEM_RECORD_LABEL_XPOS = 154; +static constexpr uint16_t STOPWATCH_ITEM_LABEL_YPOS = 12; +static constexpr uint16_t STOPWATCH_ITEM_NAME_LABEL_WIDTH = 100; +static constexpr uint16_t STOPWATCH_ITEM_RECORD_LABEL_WIDTH = 126; +static constexpr uint16_t STOPWATCH_ITEM_LABEL_HEIGHT = 36; +static constexpr uint16_t STOPWATCH_ITEM_FONT_SIZE = 32; +static constexpr uint32_t STOPWATCH_ITEM_FONT_COLOR = 0xffff8530; + +StopwatchItemView::StopwatchItemView() +{ + SetPosition(0, 0, STOPWATCH_ITEM_WIDTH, STOPWATCH_ITEM_HEIGHT); + SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + SetTouchable(true); + + itemBg_.SetPosition(STOPWATCH_ITEM_BG_XPOS, STOPWATCH_ITEM_BG_YPOS); + itemBg_.Resize(STOPWATCH_ITEM_BG_WIDTH, STOPWATCH_ITEM_BG_HEIGHT); + itemBg_.SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + itemBg_.SetStyle(STYLE_BACKGROUND_OPA, STOPWATCH_ITEM_BG_OPA); + itemBg_.SetTouchable(false); + + nameLabel_.SetPosition(STOPWATCH_ITEM_NAME_LABEL_XPOS, STOPWATCH_ITEM_LABEL_YPOS); + nameLabel_.Resize(STOPWATCH_ITEM_NAME_LABEL_WIDTH, STOPWATCH_ITEM_LABEL_HEIGHT); + nameLabel_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, STOPWATCH_ITEM_FONT_SIZE); + nameLabel_.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + nameLabel_.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + nameLabel_.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + recordLabel_.SetPosition(STOPWATCH_ITEM_RECORD_LABEL_XPOS, STOPWATCH_ITEM_LABEL_YPOS); + recordLabel_.Resize(STOPWATCH_ITEM_RECORD_LABEL_WIDTH, STOPWATCH_ITEM_LABEL_HEIGHT); + recordLabel_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, STOPWATCH_ITEM_FONT_SIZE); + recordLabel_.SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER); + recordLabel_.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + recordLabel_.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + Add(&itemBg_); + Add(&nameLabel_); + Add(&recordLabel_); +} + +StopwatchItemView::~StopwatchItemView() +{ + Remove(&nameLabel_); + Remove(&recordLabel_); + Remove(&itemBg_); +} + +void StopwatchItemView::SetItemInfo(int16_t index, const StopwatchItem &itemInfo) +{ + nameLabel_.SetText(("分段" + std::to_string(index)).c_str()); + recordLabel_.SetText(itemInfo.record.c_str()); + if (itemInfo.isLatest) { + nameLabel_.SetStyle(STYLE_TEXT_COLOR, STOPWATCH_ITEM_FONT_COLOR); + recordLabel_.SetStyle(STYLE_TEXT_COLOR, STOPWATCH_ITEM_FONT_COLOR); + } else { + nameLabel_.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + recordLabel_.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + } +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchModel.cpp new file mode 100644 index 000000000..d73b785bc --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchModel.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchModel + * Create: 2025-06-06 + */ +#include +#include "stopwatch/StopwatchModel.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr uint16_t UNIT_SEC_TO_MSEC = 1000; +StopwatchModel::StopwatchModel() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchModel::StopwatchModel"); +} + +StopwatchModel::~StopwatchModel() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchModel::~StopwatchModel"); +} + +StopwatchModel &StopwatchModel::GetInstance() +{ + static StopwatchModel instance; + return instance; +} + +void StopwatchModel::SetStartTime() +{ +#ifdef _WIN32 + gettimeofday(&startTime_, NULL); +#else + gettimeofday64(&startTime_, NULL); +#endif +} + +void StopwatchModel::SaveElapsedTime() +{ + uiSavedElapsedTime_ += uiElapsedTime_; + uiElapsedTime_ = 0; +} + +uint64_t StopwatchModel::GetElapsedTime() +{ + return uiSavedElapsedTime_ + uiElapsedTime_; +} + +uint64_t StopwatchModel::UpdateElapsedTime() +{ +#ifdef _WIN32 + struct timeval currTime = {0}; + gettimeofday(&currTime, NULL); +#else + struct timeval64 currTime = {0}; + gettimeofday64(&currTime, NULL); +#endif + uiElapsedTime_ = (currTime.tv_sec * UNIT_SEC_TO_MSEC + currTime.tv_usec / UNIT_SEC_TO_MSEC) - + (startTime_.tv_sec * UNIT_SEC_TO_MSEC + startTime_.tv_usec / UNIT_SEC_TO_MSEC); + return uiSavedElapsedTime_ + uiElapsedTime_; +} + +void StopwatchModel::ResetCounter() +{ + uiElapsedTime_ = 0; + uiSavedElapsedTime_ = 0; + records_.Clear(); +} + +bool StopwatchModel::GetActiveState() +{ + return bIsActive_; +} + +void StopwatchModel::SetActiveState() +{ + bIsActive_ = true; +} + +void StopwatchModel::SetInactiveState() +{ + bIsActive_ = false; +} + +List &StopwatchModel::GetRecordsList() +{ + return records_; +} + +void StopwatchModel::AddRecordToList(const StopwatchItem &record) +{ + ListNode *node = records_.Head(); + while (node != records_.End()) { + StopwatchItem &itemData = node->data_; + itemData.isLatest = false; + node = node->next_; + } + records_.PushFront(record); +} + +bool StopwatchModel::IsInRecordView() +{ + return bIsRecordView_; +} + +void StopwatchModel::SetRecordViewState(bool state) +{ + bIsRecordView_ = state; +} + +void StopwatchModel::ClearData() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchModel::ClearData start"); + uiElapsedTime_ = 0; + uiSavedElapsedTime_ = 0; + bIsActive_ = false; + bIsRecordView_ = false; + startTime_ = {0}; + records_.Clear(); +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPage.cpp new file mode 100644 index 000000000..0652df389 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPage.cpp @@ -0,0 +1,588 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchPage + * Create: 2025-06-06 + */ + +#include +#include +#include "stopwatch/StopwatchPage.h" +#include "stopwatch/StopwatchView.h" +#include "stopwatch/StopwatchPresenter.h" +#include "stopwatch/StopwatchModel.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "NativeRegisterManager.h" +#include "UiConfig.h" +#include "common/image_cache_manager.h" +#include "ui_stopwatch_resource.h" +#include "main/LoadImg.h" +#ifdef BUILD_IN_LINUX +#include "localtime.h" +#endif + +namespace OHOS { +static constexpr char *STOPWATCH_START = "stopwatch_start"; +static constexpr char *STOPWATCH_RESET = "stopwatch_reset"; +static constexpr uint16_t OFFSET = 4; +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t UNIT_SEC_TO_MSEC = 1000; +static constexpr uint16_t UNIT_SECS_PER_MIN = 60; +static constexpr uint16_t UNIT_SECS_PER_HOUR = 3600; +static constexpr uint16_t MAX_RECORD_SIZE = 20; +static constexpr uint16_t STOPWATCH_CONTAINER_XPOS = 0; +static constexpr uint16_t STOPWATCH_CONTAINER_YPOS = 0; +static constexpr uint16_t STOPWATCH_HAND_POSITION_XPOS = 224; +static constexpr uint16_t STOPWATCH_HAND_POSITION_YPOS = 4; +static constexpr uint16_t STOPWATCH_HAND_CENTER_XPOS = 3; +static constexpr uint16_t STOPWATCH_HAND_CENTER_YPOS = 223; +static constexpr uint16_t STOPWATCH_HAND_WIDTH = 2; +static constexpr uint16_t STOPWATCH_HAND_HEIGHT = 5; +static constexpr uint16_t STOPWATCH_LABEL_CURTIME_XPOS = 199; +static constexpr uint16_t STOPWATCH_LABEL_CURTIME_YPOS = 54; +static constexpr uint16_t STOPWATCH_LABEL_CURTIME_WIDTH = 67; +static constexpr uint16_t STOPWATCH_LABEL_CURTIME_HEIGHT = 24; +static constexpr uint16_t STOPWATCH_LABEL_CURTIME_FONT_SIZE = 24; +static constexpr uint16_t STOPWATCH_LABEL_APPNAME_XPOS = 197; +static constexpr uint16_t STOPWATCH_LABEL_APPNAME_YPOS = 82; +static constexpr uint16_t STOPWATCH_LABEL_APPNAME_WIDTH = 64; +static constexpr uint16_t STOPWATCH_LABEL_APPNAME_HEIGHT = 38; +static constexpr uint16_t STOPWATCH_LABEL_APPNAME_FONT_SIZE = 32; +static constexpr uint16_t STOPWATCH_LABEL_ELSTIME_XPOS = 87; +static constexpr uint16_t STOPWATCH_LABEL_ELSTIME_YPOS1 = 176; +static constexpr uint16_t STOPWATCH_LABEL_ELSTIME_YPOS2 = 82; +static constexpr uint16_t STOPWATCH_LABEL_ELSTIME_WIDTH = 302; +static constexpr uint16_t STOPWATCH_LABEL_ELSTIME_HEIGHT = 90; +static constexpr uint16_t STOPWATCH_LABEL_ELSTIME_FONT_SIZE = 72; +static constexpr uint16_t STOPWATCH_BUTTON_SRART_XPOS = 250; +static constexpr uint16_t STOPWATCH_BUTTON_SRART_YPOS = 302; +static constexpr uint16_t STOPWATCH_BUTTON_PAUSE_XPOS = 110; +static constexpr uint16_t STOPWATCH_BUTTON_PAUSE_YPOS = 302; +static constexpr uint16_t STOPWATCH_BUTTON_WIDTH = 96; +static constexpr uint16_t STOPWATCH_BUTTON_HEIGHT = 96; +static constexpr uint16_t STOPWATCH_LIST_RECORD_XPOS = 73; +static constexpr uint16_t STOPWATCH_LIST_RECORD_YPOS = 170; +static constexpr uint16_t STOPWATCH_LIST_RECORD_WIDTH = 312; +static constexpr uint16_t STOPWATCH_LIST_RECORD_HEIGHT = 122; +static constexpr uint16_t STOPWATCH_LABEL_REBOUND_SIZE = 60; + +REGIST_SLICE_PAGE(VIEW_STOPWATCH, STOPWATCH_PAGES::STOPWATCH_MAIN_PAGE, StopwatchPage, true); + +static std::string GetCurrentTimeStr() +{ + struct tm localTime; + time_t seconds = time(nullptr); + localtime_r(&seconds, &localTime); + std::string currTime; + if (localTime.tm_hour < NUM_TEN) { + currTime += "0"; + } + currTime += std::to_string(localTime.tm_hour) + ":"; + if (localTime.tm_min < NUM_TEN) { + currTime += "0"; + } + currTime += std::to_string(localTime.tm_min); + return currTime; +} + +static uint64_t GetMilliSeconds(uint64_t uiElapsedTime) +{ + return (uiElapsedTime % (UNIT_SECS_PER_HOUR * UNIT_SEC_TO_MSEC)) % (UNIT_SECS_PER_MIN * UNIT_SEC_TO_MSEC); +} + +static std::string FormatElapsedTime(uint64_t uiElapsedTime) +{ + std::string strElapsedTime; + std::string hours; + std::string minute; + std::string seconds; + std::string centisecs; + uint64_t hour = uiElapsedTime / (UNIT_SECS_PER_HOUR * UNIT_SEC_TO_MSEC); + uiElapsedTime %= (UNIT_SECS_PER_HOUR * UNIT_SEC_TO_MSEC); + uint64_t min = uiElapsedTime / (UNIT_SECS_PER_MIN * UNIT_SEC_TO_MSEC); + uiElapsedTime %= (UNIT_SECS_PER_MIN * UNIT_SEC_TO_MSEC); + uint64_t sec = uiElapsedTime / UNIT_SEC_TO_MSEC; + uiElapsedTime %= UNIT_SEC_TO_MSEC; + uint64_t csec = uiElapsedTime / NUM_TEN; + if (hour >= 0 && hour < NUM_TEN) { + hours = "0" + std::to_string(hour); + } else { + hours = std::to_string(hour); + } + if (min >= 0 && min < NUM_TEN) { + minute = "0" + std::to_string(min); + } else { + minute = std::to_string(min); + } + if (sec >= 0 && sec < NUM_TEN) { + seconds = "0" + std::to_string(sec); + } else { + seconds = std::to_string(sec); + } + if (csec >= 0 && csec < NUM_TEN) { + centisecs = "0" + std::to_string(csec); + } else { + centisecs = std::to_string(csec); + } + strElapsedTime = minute + ":" + seconds + "." + centisecs; + return strElapsedTime; +} + +void StopwatchPage::StopwatchAnimatorCallback::Callback(UIView *view) +{ + UNUSED(view); + uint64_t uiElapsedTime = StopwatchModel::GetInstance().UpdateElapsedTime(); + uint64_t millisecs = GetMilliSeconds(uiElapsedTime); + stopwatchPage->GetSweepClock()->SetSweepTime24Hour(0, 0, millisecs); + stopwatchPage->GetSweepClock()->Invalidate(); + std::string strElapsedTime = FormatElapsedTime(uiElapsedTime); + stopwatchPage->GetElapsedTimeLabel()->SetText(strElapsedTime.c_str()); + if (uiElapsedTime >= UNIT_SECS_PER_HOUR * UNIT_SEC_TO_MSEC) { + stopwatchPage->Overflowing(); + } +} + +void StopwatchPage::TimeAnimatorCallback::Callback(UIView *view) +{ + UILabel *timeLabel = dynamic_cast(view); + if (timeLabel == nullptr) { + return; + } + std::string currTime = GetCurrentTimeStr(); + timeLabel->SetText(currTime.c_str()); + timeLabel->Invalidate(); +} + +StopwatchPage::StopwatchPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPage::StopwatchPage"); +} + +StopwatchPage::~StopwatchPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPage::~StopwatchPage"); + bool ret = ImageCacheManager::GetInstance().UnloadAllInMultiRes(PNG_APPLIST_STOPWATCH_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnloadStopwatchImage fail"); + } + if (sweepClock_ != nullptr) { + sweepClock_->RemoveAll(); + delete sweepClock_; + sweepClock_ = nullptr; + } + if (currentTime_ != nullptr) { + delete currentTime_; + currentTime_ = nullptr; + } + if (appName_ != nullptr) { + delete appName_; + appName_ = nullptr; + } + if (elapsedTime_ != nullptr) { + delete elapsedTime_; + elapsedTime_ = nullptr; + } + if (startButton_ != nullptr) { + delete startButton_; + startButton_ = nullptr; + } + if (resetButton_ != nullptr) { + delete resetButton_; + resetButton_ = nullptr; + } + if (recordsList_ != nullptr) { + delete recordsList_; + recordsList_ = nullptr; + } + if (listAdapter_ != nullptr) { + delete listAdapter_; + listAdapter_ = nullptr; + } + if (backGround_ != nullptr) { + delete backGround_; + backGround_ = nullptr; + } + if (imgScale_ != nullptr) { + delete imgScale_; + imgScale_ = nullptr; + } + if (secondHand_ != nullptr) { + delete secondHand_; + secondHand_ = nullptr; + } + if (animator_ != nullptr) { + delete animator_; + animator_ = nullptr; + } + if (animatorCallback_ != nullptr) { + delete animatorCallback_; + animatorCallback_ = nullptr; + } + if (timeAnimator_ != nullptr) { + delete timeAnimator_; + timeAnimator_ = nullptr; + } + if (timeCallback_ != nullptr) { + delete timeCallback_; + timeCallback_ = nullptr; + } +} + +void StopwatchPage::OnStart(void *data) +{ + bool ret = ImageCacheManager::GetInstance().LoadAllInMultiRes(PNG_APPLIST_STOPWATCH_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadStopwatchImage fail"); + return; + } + + sweepClock_ = new UISweepClock(); + if (sweepClock_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UISweepClock new fail"); + return; + } + sweepClock_->SetPosition(STOPWATCH_CONTAINER_XPOS, STOPWATCH_CONTAINER_YPOS); + sweepClock_->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + sweepClock_->SetDraggable(true); + sweepClock_->SetTouchable(true); + + secondHand_ = new Image(); + if (secondHand_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "secondHand new fail"); + return; + } + ImageInfo *second = + ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_STOPWATCH_STOPWATCH02, PNG_APPLIST_STOPWATCH_IMAGE); + + if (second == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::OnStart source fail"); + return; + } + secondHand_->SetSrc(second); + sweepClock_->SetHandImage(UISweepClock::HandType::SECOND_HAND, *secondHand_, + {STOPWATCH_HAND_POSITION_XPOS, STOPWATCH_HAND_POSITION_YPOS}, + {STOPWATCH_HAND_CENTER_XPOS, STOPWATCH_HAND_CENTER_YPOS}); + sweepClock_->SetHandLine(UISweepClock::HandType::HOUR_HAND, + {STOPWATCH_HAND_POSITION_XPOS, STOPWATCH_HAND_POSITION_YPOS}, + {STOPWATCH_HAND_CENTER_XPOS, STOPWATCH_HAND_CENTER_YPOS}, Color::White(), + STOPWATCH_HAND_WIDTH, STOPWATCH_HAND_HEIGHT, OPA_TRANSPARENT); + sweepClock_->SetHandLine(UISweepClock::HandType::MINUTE_HAND, + {STOPWATCH_HAND_POSITION_XPOS, STOPWATCH_HAND_POSITION_YPOS}, + {STOPWATCH_HAND_CENTER_XPOS, STOPWATCH_HAND_CENTER_YPOS}, Color::White(), + STOPWATCH_HAND_WIDTH, STOPWATCH_HAND_HEIGHT, OPA_TRANSPARENT); + + sweepClock_->SetWorkMode(UISweepClock::WorkMode::NORMAL); + uint64_t uiElapsedTime = StopwatchModel::GetInstance().GetElapsedTime(); + uint64_t millisecs = GetMilliSeconds(uiElapsedTime); + sweepClock_->SetSweepTime24Hour(0, 0, millisecs); + + backGround_ = new UIImageView(); + if (backGround_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backGroundFirst new fail"); + return; + } + backGround_->SetPosition(0, 0); + LOADIMG::LoadImageViewImg(backGround_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH06); + sweepClock_->Add(backGround_); + + imgScale_ = new UIImageView(); + if (imgScale_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backGroundFirst new fail"); + return; + } + imgScale_->SetPosition(OFFSET, OFFSET); + LOADIMG::LoadImageViewImg(imgScale_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH04); + sweepClock_->Add(imgScale_); + + currentTime_ = new UILabel(); + if (currentTime_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::SetupCurrentTime new Label currentTime_ fail"); + return; + } + currentTime_->SetPosition(STOPWATCH_LABEL_CURTIME_XPOS, STOPWATCH_LABEL_CURTIME_YPOS); + currentTime_->Resize(STOPWATCH_LABEL_CURTIME_WIDTH, STOPWATCH_LABEL_CURTIME_HEIGHT); + currentTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, STOPWATCH_LABEL_CURTIME_FONT_SIZE); + currentTime_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + currentTime_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + currentTime_->SetVisible(true); + sweepClock_->Add(currentTime_); + + appName_ = new UILabel(); + if (appName_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::SetupAppName new Label appName_ fail"); + return; + } + appName_->SetPosition(STOPWATCH_LABEL_APPNAME_XPOS, STOPWATCH_LABEL_APPNAME_YPOS); + appName_->Resize(STOPWATCH_LABEL_APPNAME_WIDTH, STOPWATCH_LABEL_APPNAME_HEIGHT); + appName_->SetText(STOPWATCH_APP_NAME); + appName_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + appName_->SetTextColor(Color::White()); + appName_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, STOPWATCH_LABEL_APPNAME_FONT_SIZE); + appName_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + appName_->SetVisible(true); + sweepClock_->Add(appName_); + + elapsedTime_ = new UILabel(); + if (elapsedTime_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::SetupElapsedTime new Label elapsedTime_ fail"); + return; + } + elapsedTime_->SetPosition(STOPWATCH_LABEL_ELSTIME_XPOS, STOPWATCH_LABEL_ELSTIME_YPOS1); + elapsedTime_->Resize(STOPWATCH_LABEL_ELSTIME_WIDTH, STOPWATCH_LABEL_ELSTIME_HEIGHT); + elapsedTime_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + elapsedTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, STOPWATCH_LABEL_ELSTIME_FONT_SIZE); + elapsedTime_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + elapsedTime_->SetVisible(true); + std::string strElapsedTime = FormatElapsedTime(uiElapsedTime); + elapsedTime_->SetText(strElapsedTime.c_str()); + sweepClock_->Add(elapsedTime_); + + startButton_ = new UILabelButton(); + if (startButton_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::SetupButton new UILabelButton startButton_ fail"); + return; + } + startButton_->SetPosition(STOPWATCH_BUTTON_SRART_XPOS, STOPWATCH_BUTTON_SRART_YPOS); + startButton_->Resize(STOPWATCH_BUTTON_WIDTH, STOPWATCH_BUTTON_HEIGHT); + startButton_->SetViewId(STOPWATCH_START); + startButton_->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::RELEASED); + startButton_->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + startButton_->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::INACTIVE); + startButton_->SetOnClickListener(this); + sweepClock_->Add(startButton_); + + resetButton_ = new UILabelButton(); + if (resetButton_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::SetupButton new UILabelButton resetButton_ fail"); + return; + } + resetButton_->SetPosition(STOPWATCH_BUTTON_PAUSE_XPOS, STOPWATCH_BUTTON_PAUSE_YPOS); + resetButton_->Resize(STOPWATCH_BUTTON_WIDTH, STOPWATCH_BUTTON_HEIGHT); + resetButton_->SetViewId(STOPWATCH_RESET); + resetButton_->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::RELEASED); + resetButton_->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::PRESSED); + resetButton_->SetStyleForState(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT, UIButton::INACTIVE); + resetButton_->SetOnClickListener(this); + sweepClock_->Add(resetButton_); + + listAdapter_ = new StopwatchAdapter(); + if (listAdapter_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "StopwatchPage::SetupRecordsList new StopwatchAdapter listAdapter_ fail"); + return; + } + recordsList_ = new UIList(); + if (recordsList_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::SetupRecordsList new UIList recordsList_ fail"); + return; + } + recordsList_->SetPosition(STOPWATCH_LIST_RECORD_XPOS, STOPWATCH_LIST_RECORD_YPOS); + recordsList_->Resize(STOPWATCH_LIST_RECORD_WIDTH, STOPWATCH_LIST_RECORD_HEIGHT); + recordsList_->SetThrowDrag(true); + recordsList_->SetDraggable(true); + recordsList_->SetReboundSize(STOPWATCH_LABEL_REBOUND_SIZE); + recordsList_->EnableAutoAlign(true); + recordsList_->SetElastic(true); + recordsList_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + recordsList_->SetAdapter(listAdapter_); + recordsList_->SetVisible(false); + sweepClock_->Add(recordsList_); + + animatorCallback_ = new StopwatchAnimatorCallback(this); + if (animatorCallback_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "callBack new fail\n"); + return; + } + + animator_ = new Animator(animatorCallback_, nullptr, 0, true); + if (animator_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::InitView new Animator animator_ fail"); + return; + } + + timeCallback_ = new TimeAnimatorCallback(); + if (timeCallback_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "callBack new fail\n"); + return; + } + + timeAnimator_ = new Animator(timeCallback_, currentTime_, 0, true); + if (timeAnimator_ == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopwatchPage::InitView new Animator timeAnimator_ fail"); + return; + } + timeAnimator_->Start(); + + sweepClock_->SetOnDragListener(this); + AddViewToPageContainer(sweepClock_); + + bool isActive = StopwatchModel::GetInstance().GetActiveState(); + DrawButtonStatusView(isActive); + bool state = StopwatchModel::GetInstance().IsInRecordView(); + if (StopwatchModel::GetInstance().GetOverflowState()) { + state = false; + } + DrawContainRecordListView(state); +} + +void StopwatchPage::OnStop() {} + +void StopwatchPage::OnPause() +{ + if (animator_ != nullptr) { + if (animator_->GetState() != Animator::STOP) { + animator_->Stop(); + } + } + if (timeAnimator_ != nullptr) { + if (timeAnimator_->GetState() != Animator::STOP) { + timeAnimator_->Stop(); + } + } +} + +void StopwatchPage::OnResume() +{ + if (animator_ != nullptr) { + bool isActive = StopwatchModel::GetInstance().GetActiveState(); + if (isActive && animator_->GetState() == Animator::STOP) { + animator_->Start(); + } + } + if (timeAnimator_ != nullptr) { + if (timeAnimator_->GetState() == Animator::STOP) { + timeAnimator_->Start(); + } + } +} + +void StopwatchPage::DrawButtonStatusView(bool isActive) +{ + if (isActive) { + LOADIMG::LoadBtnImage(startButton_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH08, + IMAGE_STOPWATCH_STOPWATCH08); + startButton_->Invalidate(); + + resetButton_->Enable(); + LOADIMG::LoadBtnImage(resetButton_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH14, + IMAGE_STOPWATCH_STOPWATCH14); + auto &recordList = StopwatchModel::GetInstance().GetRecordsList(); + if (recordList.Size() >= MAX_RECORD_SIZE) { + resetButton_->Disable(); + LOADIMG::LoadBtnImage(resetButton_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH20, + IMAGE_STOPWATCH_STOPWATCH20); + } + resetButton_->Invalidate(); + } else { + LOADIMG::LoadBtnImage(startButton_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH12, + IMAGE_STOPWATCH_STOPWATCH12); + startButton_->Invalidate(); + + resetButton_->Enable(); + // 复位 + LOADIMG::LoadBtnImage(resetButton_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH19, + IMAGE_STOPWATCH_STOPWATCH19); + uint64_t elapsedTime = StopwatchModel::GetInstance().GetElapsedTime(); + if (elapsedTime == 0) { + resetButton_->Disable(); + LOADIMG::LoadBtnImage(resetButton_, PNG_APPLIST_STOPWATCH_IMAGE, IMAGE_STOPWATCH_STOPWATCH10, + IMAGE_STOPWATCH_STOPWATCH10); + } + resetButton_->Invalidate(); + } +} + +void StopwatchPage::DrawContainRecordListView(bool isContainRecordList) +{ + if (isContainRecordList) { + appName_->SetVisible(false); + recordsList_->SetVisible(true); + elapsedTime_->SetPosition(STOPWATCH_LABEL_ELSTIME_XPOS, STOPWATCH_LABEL_ELSTIME_YPOS2); + } else { + appName_->SetVisible(true); + recordsList_->SetVisible(false); + elapsedTime_->SetPosition(STOPWATCH_LABEL_ELSTIME_XPOS, STOPWATCH_LABEL_ELSTIME_YPOS1); + } + RefreshRecordsList(); +} + +void StopwatchPage::RefreshRecordsList() +{ + auto &records = StopwatchModel::GetInstance().GetRecordsList(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPage::RefreshRecordsList"); + listAdapter_->SetData(records); + recordsList_->RefreshList(); +} + +bool StopwatchPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + bool isActive = StopwatchModel::GetInstance().GetActiveState(); + if (strcmp(view.GetViewId(), STOPWATCH_START) == 0) { + if (isActive) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPresenter::OnClick activeState = %d, pause counting click", + isActive); + StopwatchModel::GetInstance().SetInactiveState(); + DrawButtonStatusView(false); + animator_->Stop(); + StopwatchModel::GetInstance().SaveElapsedTime(); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPresenter::OnClick activeState = %d, start counting click", + isActive); + StopwatchModel::GetInstance().SetActiveState(); + if (StopwatchModel::GetInstance().GetOverflowState()) { + DrawContainRecordListView(false); + StopwatchModel::GetInstance().SetOverflowState(false); + } + DrawButtonStatusView(true); + StopwatchModel::GetInstance().SetStartTime(); + animator_->Start(); + } + } else if (strcmp(view.GetViewId(), STOPWATCH_RESET) == 0) { + if (isActive) { + StopwatchModel::GetInstance().SetRecordViewState(true); + uint64_t uiElapsedTime = StopwatchModel::GetInstance().GetElapsedTime(); + std::string strElapsedTime = FormatElapsedTime(uiElapsedTime); + StopwatchItem item = {strElapsedTime, true}; + StopwatchModel::GetInstance().AddRecordToList(item); + DrawContainRecordListView(true); + DrawButtonStatusView(true); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPresenter::OnClick save a record"); + } else { + StopwatchModel::GetInstance().SetRecordViewState(false); + StopwatchModel::GetInstance().ResetCounter(); + elapsedTime_->SetText("00:00.00"); + sweepClock_->SetInitTime24Hour(0, 0, 0); + sweepClock_->Invalidate(); + DrawContainRecordListView(false); + DrawButtonStatusView(false); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchPresenter::OnClick reset a record"); + } + } + return true; +} + +bool StopwatchPage::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchOnDragListener::OnDrag"); + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopwatchOnDragListener::OnDrag ChangeSlice(VIEW_APPLIST)"); + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } + return true; +} + +void StopwatchPage::Overflowing() +{ + animator_->Stop(); + elapsedTime_->SetText("59:59.99"); + sweepClock_->SetSweepTime24Hour(0, 0, 0); + sweepClock_->Invalidate(); + StopwatchModel::GetInstance().SetInactiveState(); + DrawButtonStatusView(false); + StopwatchModel::GetInstance().ResetCounter(); + StopwatchModel::GetInstance().SetOverflowState(true); +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPresenter.cpp new file mode 100644 index 000000000..90fcfe210 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/stopwatch/src/StopwatchPresenter.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: StopwatchPresenter + * Create: 2025-06-06 + */ +#include "stopwatch/StopwatchView.h" +#include "stopwatch/StopwatchPresenter.h" +#include "NativeRegisterManager.h" + +namespace OHOS { + +REGIST_MENU(VIEW_STOPWATCH, StopwatchView, StopwatchPresenter, PNG_APPLIST_STOPWATCH_LOGO, PNG_APPLIST_DEFAULT_IMG, + "秒表"); +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempClickMea.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempClickMea.cpp index f56dc3a88..45982b555 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempClickMea.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempClickMea.cpp @@ -8,7 +8,7 @@ #include "UiConfig.h" #include #include "font/ui_font.h" -#include "TempClickMea.h" +#include "temperature/TempClickMea.h" namespace OHOS { static TempClickMea *g_tempClickMea = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempContinueWarn.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempContinueWarn.cpp index 25acea9cd..e8f599deb 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempContinueWarn.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempContinueWarn.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempContinueWarn.h" +#include "temperature/TempContinueWarn.h" namespace OHOS { static TempContinueWarn *g_tempContinueWarn = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitInter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitInter.cpp index b2538b033..215e46833 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitInter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitInter.cpp @@ -9,7 +9,7 @@ #include "layout/grid_layout.h" #include "font/ui_font.h" #include -#include "TempExitInter.h" +#include "temperature/TempExitInter.h" namespace OHOS { static TempExitInter *g_tempExitInter = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitPrompt.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitPrompt.cpp index 34359aa4c..d4155fcb3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitPrompt.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempExitPrompt.cpp @@ -8,7 +8,7 @@ #include "UiConfig.h" #include "layout/grid_layout.h" #include -#include "TempExitPrompt.h" +#include "temperature/TempExitPrompt.h" namespace OHOS { static TempExitPrompt *g_tempExitPrompt = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempInitInter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempInitInter.cpp index dc00359c4..da8a03ad0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempInitInter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempInitInter.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempInitInter.h" +#include "temperature/TempInitInter.h" namespace OHOS { static TempInitInter *g_tempInitInter = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempJoinStudy.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempJoinStudy.cpp index bf089b5a1..22153997b 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempJoinStudy.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempJoinStudy.cpp @@ -8,7 +8,7 @@ #include "UiConfig.h" #include "layout/grid_layout.h" #include -#include "TempJoinStudy.h" +#include "temperature/TempJoinStudy.h" namespace OHOS { static TempJoinStudy *g_tempJoinStudy = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempLittleTip.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempLittleTip.cpp index 8c6c01873..5f4d4fa94 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempLittleTip.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempLittleTip.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempLittleTip.h" +#include "temperature/TempLittleTip.h" namespace OHOS { static TempLittleTip *g_tempJoinStudy = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMainView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMainView.cpp index 5c533c7d2..10cbbae6f 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMainView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMainView.cpp @@ -5,10 +5,10 @@ * Create: 2022-02-15 */ -#include "TempMainView.h" +#include "temperature/TempMainView.h" #include "UiConfig.h" -#include "TempMeaProcess.h" -#include "TempWarn.h" +#include "temperature/TempMeaProcess.h" +#include "temperature/TempWarn.h" namespace OHOS { static TempMainView *g_tempMainView = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeaProcess.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeaProcess.cpp index 76918d105..7a8fa1d8c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeaProcess.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeaProcess.cpp @@ -7,8 +7,8 @@ #include "UiConfig.h" #include -#include "TempMeaProcess.h" -#include "TempMainView.h" +#include "temperature/TempMeaProcess.h" +#include "temperature/TempMainView.h" namespace OHOS { static TempMeaProcess *g_tempMeaProcess = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeasure.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeasure.cpp index a3c01d99d..2ea184b71 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeasure.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempMeasure.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempMeasure.h" +#include "temperature/TempMeasure.h" namespace OHOS { static TempMeasure *g_tempMeasure = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempModel.cpp index b52c38cfd..2078ffda7 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempModel.cpp @@ -5,9 +5,9 @@ * Create: 2022-02-15 */ -#include "TempModel.h" +#include "temperature/TempModel.h" #include "UiConfig.h" -#include "TempModel.h" +#include "temperature/TempModel.h" namespace OHOS { TempModel::TempModel() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPresenter.cpp index b1b9fc6dd..9b9a81898 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPresenter.cpp @@ -5,11 +5,11 @@ * Create: 2022-02-15 */ -#include "TempPresenter.h" -#include "TempMainView.h" +#include "temperature/TempPresenter.h" +#include "temperature/TempMainView.h" #include "ChangeSliceListener.h" #include "graphic_service.h" -#include "ui_service.h" +#include "uiservice/ui_service.h" #include "string" #include "iostream" #include "sstream" @@ -45,7 +45,6 @@ TempPresenter *TempPresenter::GetInstance() void TempPresenter::OnResume(void) { - Presenter::OnResume(); SendMsgToUIService(UI_ADD_SLEEP_VETO, 0, nullptr, 0); } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPromptWear.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPromptWear.cpp index 47ec2b05c..856e77275 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPromptWear.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempPromptWear.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempPromptWear.h" +#include "temperature/TempPromptWear.h" namespace OHOS { static TempPromptWear *g_tempPromptWear = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempRemindWear.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempRemindWear.cpp index a6ffbf5c9..b44a8289c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempRemindWear.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempRemindWear.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempRemindWear.h" +#include "temperature/TempRemindWear.h" namespace OHOS { static TempRemindWear *g_tempRemindWear = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempReport.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempReport.cpp index 46cf911c3..2f7166d3c 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempReport.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempReport.cpp @@ -9,7 +9,7 @@ #include "layout/grid_layout.h" #include "font/ui_font.h" #include -#include "TempReport.h" +#include "temperature/TempReport.h" namespace OHOS { static TempReport *g_tempReport = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempStudyAbout.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempStudyAbout.cpp index 8db30bd09..b1fe71b1a 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempStudyAbout.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempStudyAbout.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempStudyAbout.h" +#include "temperature/TempStudyAbout.h" namespace OHOS { static TempStudyAbout *g_tempStudyAbout = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempWarn.cpp b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempWarn.cpp index 8df8eb975..879fd41c3 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempWarn.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/temperature/src/TempWarn.cpp @@ -7,7 +7,7 @@ #include "UiConfig.h" #include -#include "TempWarn.h" +#include "temperature/TempWarn.h" namespace OHOS { static TempWarn *g_tempWarn = nullptr; diff --git a/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerMainPage.cpp new file mode 100644 index 000000000..35f8c4b99 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerMainPage.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerMainPage + * Create: 2025-06-09 + */ + +#include +#include "timers/TimerMainPage.h" +#include "timers/TimerSettingPage.h" +#include "timers/TimerTimingPage.h" +#include "timers/TimerPresenter.h" +#include "SlicePageFactory.h" +#include "timers/TimerView.h" +#include "components/ui_scroll_view_nested.h" +#include "components/ui_arc_label.h" +#include "graphic_timer.h" +#include "ohos_timer.h" +#include "wearable_log.h" +#include "main/LoadImg.h" + +namespace OHOS { +static constexpr int16_t ADDBUTTON_MAX = 4; +static constexpr uint8_t MAIN_TITLE_FONT_SIZE = 40; +static constexpr int16_t MAIN_TITLE_SIZE_WIDTH = 160; +static constexpr int16_t MAIN_TITLE_SIZE_HEIGHT = 50; +static constexpr int16_t MAIN_TITLE_POSITION_X = 150; +static constexpr int16_t MAIN_TITLE_POSITION_Y = 20; +static constexpr int16_t MAIN_ADDBUTTON_POSITION_X = 111; +static constexpr int16_t MAIN_ADDBUTTON_POSITION_Y = 347; +static constexpr int16_t MAIN_ADDBUTTON_SIZE_WIDTH = 232; +static constexpr int16_t MAIN_ADDBUTTON_SIZE_HEIGHT = 76; +static constexpr int16_t SELECTMIN_POX = 86; +static constexpr int16_t SELECTMIN_POXS = 252; +static constexpr int16_t SELECTMIN_POY = 89; +static constexpr int16_t SELECTMIN_POYS = 220; +static constexpr int16_t SELECTMIN_SIZE = 100; +static constexpr int16_t MAX_SCR_DIS = 1000; +static constexpr uint8_t MIN = 60; + +REGIST_SLICE_PAGE(VIEW_TIMER, TIMER_PAGES::TIMER_MAIN_PAGE, TimerMainPage, true); + +TimerMainPage::~TimerMainPage() +{ + bool ret = ImageCacheManager::GetInstance().UnloadAllInMultiRes(TIMER_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnloadTimerImage fail"); + } + + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (addButton != nullptr) { + delete addButton; + addButton = nullptr; + } + + for (int i = 0; i < ADDBUTTON_MAX; i++) { + if (selectMin[i] != nullptr) { + delete selectMin[i]; + selectMin[i] = nullptr; + } + } + + if (backround != nullptr) { + delete backround; + backround = nullptr; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::~TimerMainPage()"); +} + +void TimerMainPage::OnStart(void* data) +{ + bool ret = ImageCacheManager::GetInstance().LoadAllInMultiRes(TIMER_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadTimerImage fail"); + return; + } + // 主界面 + if (group == nullptr) { + group = new UIScrollView(); + group->SetPosition(0, 0, VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + group->SetViewId("mainview"); + } + if (backround == nullptr) { + backround = new UIImageView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::OnStart new backround"); + } + LOADIMG::LoadImageViewImg(backround, TIMER_IMAGE, IMAGE_CONVERTER_TOOL_TIMER_BG); + backround->SetPosition(0, 0, RESOLUTION_WIDTH, RESOLUTION_WIDTH); + group->Add(backround); + InitView(); + LabelTitle(); + group->SetOnDragListener(this); + group->SetVisible(false); + AddViewToPageContainer(group); + if (TimerModel::GetInstance().GetExistTimer()) { + // 定时器存在,进入计时页面 + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_TIMING_PAGE); + } else { + group->SetVisible(true); + } +} + +void TimerMainPage::LabelTitle() +{ + // 标题 + if (title == nullptr) { + title = new UILabel(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::LabelTitle new title"); + } + title->SetPosition(MAIN_TITLE_POSITION_X, MAIN_TITLE_POSITION_Y); + title->SetText("计时器"); + title->Resize(MAIN_TITLE_SIZE_WIDTH, MAIN_TITLE_SIZE_HEIGHT); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, MAIN_TITLE_FONT_SIZE); + title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + title->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + title->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + title->SetVisible(true); + group->Add(title); +} + +void TimerMainPage::InitView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::InitView() Start!"); + if (addButton == nullptr) { + addButton = new UIImageView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::InitView new addButton"); + } + LOADIMG::LoadImageViewImg(addButton, TIMER_IMAGE, IMAGE_CONVERTER_TOOL_TIMER_USER); + addButton->SetPosition(MAIN_ADDBUTTON_POSITION_X, MAIN_ADDBUTTON_POSITION_Y); + addButton->Resize(MAIN_ADDBUTTON_SIZE_WIDTH, MAIN_ADDBUTTON_SIZE_HEIGHT); + addButton->SetViewId(SETTING_TIMER); + addButton->SetTouchable(true); + addButton->SetOnClickListener(this); + group->Add(addButton); + + int posX[ADDBUTTON_MAX] = {SELECTMIN_POX, SELECTMIN_POXS, SELECTMIN_POX, SELECTMIN_POXS}; + int posY[ADDBUTTON_MAX] = {SELECTMIN_POY, SELECTMIN_POY, SELECTMIN_POYS, SELECTMIN_POYS}; + const char* buttonViewId[ADDBUTTON_MAX] = {"1", "3", "15", "30"}; + ImageInfo *image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_TIMER_1, TIMER_IMAGE); + ImageInfo *image3 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_TIMER_3, TIMER_IMAGE); + ImageInfo *image15 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_TIMER_15, TIMER_IMAGE); + ImageInfo *image30 = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_TIMER_30, TIMER_IMAGE); + ImageInfo* buttonSrc[ADDBUTTON_MAX] = {image1, image3, image15, image30}; + // 一分钟按钮 + for (int i = 0;i < ADDBUTTON_MAX;i++) { + if (selectMin[i] == nullptr) { + selectMin[i] = new UIImageView(); + } + selectMin[i]->SetPosition(posX[i], posY[i]); + selectMin[i]->Resize(SELECTMIN_SIZE, SELECTMIN_SIZE); + selectMin[i]->SetTouchable(true); + selectMin[i]->SetOnClickListener(this); + selectMin[i]->SetViewId(buttonViewId[i]); + selectMin[i]->SetSrc(buttonSrc[i]); + group->Add(selectMin[i]); + } +} + +bool TimerMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + std::string viewId = view.GetViewId(); + if (viewId == SETTING_TIMER) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::OnClick viewId == SETTING_TIMER"); + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_SETTING_PAGE); + } else if (viewId == "1"|| viewId == "3" || viewId == "15" || viewId == "30") { + int num = std::stoi(viewId); + struct timeval start_time; + gettimeofday(&start_time, nullptr); + uint32_t s_time = start_time.tv_sec * MAX_SCR_DIS + start_time.tv_usec / MAX_SCR_DIS; // 转换成ms + TimerModel::GetInstance().SetStartTime(s_time); + TimerModel::GetInstance().SetSaveTime(true, 0); + TimerModel::GetInstance().SetDurationTime(num * MIN); + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_TIMING_PAGE); + } + return true; +} + +bool TimerMainPage::OnDrag(UIView& view, const DragEvent& event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerMainPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + } + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerModel.cpp new file mode 100644 index 000000000..83c3b843c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerModel.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerModel + * Create: 2025-06-09 + */ + +#include "timers/TimerModel.h" +#include "main/HealthModel.h" +#include "uiservice/ui_service.h" +#include "wearable_log.h" + +namespace OHOS { +static int g_motionTimes{0}; +static constexpr uint64_t MS_ONE_SECONDS = 1000; +TimerModel::TimerModel() +{ +} + +TimerModel::~TimerModel() +{ +} + +TimerModel &TimerModel::GetInstance() +{ + static TimerModel instance; + return instance; +} + +uint32_t TimerModel::GetSaveTime() +{ + return save_time; +} + +void TimerModel::SetSaveTime(bool falg, uint32_t value) +{ + if (falg) { + save_time = 0; + } else { + save_time += value; + } +} + +void TimerModel::SetDurationTime(uint32_t time) +{ + durationTime = time; +} + +uint32_t TimerModel::GetDurationTime() +{ + return durationTime; +} + +/* 定时器回调函数 */ +void TimerTimerCallback(void *data) +{ + (void)data; + uint32_t dura_time = TimerModel::GetInstance().GetDurationTime(); + uint32_t start_time = TimerModel::GetInstance().GetStartTime(); + uint32_t save_time = TimerModel::GetInstance().GetSaveTime(); + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + uint32_t remTime = dura_time * 1000 - (current_time.tv_usec - start_time) - save_time; + if (remTime == 0) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TimerTimerCallback: end :%d", time); + TimerModel::GetInstance().SetExistTimer(false); + TimerModel::GetInstance().DisableTimer(); + } +} + +/* 开启定时器 */ +void TimerModel::InitTimer() +{ + if (g_startCounting != nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerModel::InitTimer g_startCounting != nullptr!!"); + return; + } + uint32_t tick = GetOSTick(MS_ONE_SECONDS); + g_startCounting = new GraphicTimer(tick, TimerTimerCallback, nullptr, true); + if (g_startCounting == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerModel::InitTimer new GraphicTimer failed!!"); + return; + } + bool retTimer = g_startCounting->Start(); + if (!retTimer) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerModel::InitTimer Start failed!!"); + if (g_startCounting != nullptr) { + delete g_startCounting; + g_startCounting = nullptr; + } + return; + } +} + +/* 关闭定时器 */ +void TimerModel::DisableTimer() +{ + if (g_startCounting != nullptr) { + delete g_startCounting; + g_startCounting = nullptr; + g_motionTimes = 0; + } +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerPresenter.cpp new file mode 100644 index 000000000..b7390642f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerPresenter.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerPresenter + * Create: 2025-06-09 + */ + +#include "timers/TimerView.h" +#include "timers/TimerModel.h" +#include "timers/TimerPresenter.h" +#include "NativeRegisterManager.h" +#include "ohos_timer.h" + +namespace OHOS { + REGIST_MENU(VIEW_TIMER, TimerView, TimerPresenter, TIMER_MAIN_ICON, PNG_APPLIST_DEFAULT_IMG, "计时器"); +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerSettingPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerSettingPage.cpp new file mode 100644 index 000000000..0f01e9354 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerSettingPage.cpp @@ -0,0 +1,386 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerSettingPage + * Create: 2025-06-09 + */ + +#include +#include +#include "timers/TimerSettingPage.h" +#include "timers/TimerPresenter.h" +#include "components/ui_arc_label.h" +#include "wearable_log.h" +#include "timers/TimerView.h" +#include "SlicePageFactory.h" +#include "common/image_cache_manager.h" + +namespace OHOS { +static constexpr uint8_t BACKGROUND_FONT = 40; +static constexpr uint8_t HIGHTLIGHT_FONT = 50; +static constexpr uint8_t TIMERPICKER_MAX = 3; +static constexpr uint16_t PADDING = 3; +static constexpr uint16_t BORDER_RADIUS = 5; +static constexpr uint16_t TEXT_FONT = 24; +static constexpr uint16_t SETTING_TITLE_POSITION_X = 100; +static constexpr uint16_t SETTING_TITLE_POSITION_Y = 31; +static constexpr uint16_t SETTING_TITLE_SIZE_WIDTH = 253; +static constexpr uint16_t SETTING_TITLE_SIZE_HEIGHT = 53; +static constexpr uint16_t SETTING_TITLE_TEXT_SIZE = 38; +static constexpr uint16_t SETTING_TIMERLABEL_POSITION_X = 86; +static constexpr uint16_t SETTING_TIMERLABEL_POSITION_Y = 88; +static constexpr uint16_t SETTING_TIMERLABEL_SIZE_WIDTH = 48; +static constexpr uint16_t SETTING_TIMERLABEL_SIZE_HEIGHT = 42; +static constexpr uint16_t SETTING_TIMERLABEL_FONT = 18; +static constexpr uint16_t SETTING_START_POSITION_X = 112; +static constexpr uint16_t SETTING_START_POSITION_Y = 347; +static constexpr uint16_t SETTING_START_SIZE_WIDTH = 232; +static constexpr uint16_t SETTING_START_SIZE_HEIGHT = 76; +static constexpr uint16_t SETTING_START_FONT = 40; +static constexpr uint16_t TIMERPICKER_POSX1 = 61; +static constexpr uint16_t TIMERPICKER_POSX2 = 183; +static constexpr uint16_t TIMERPICKER_POSX3 = 305; +static constexpr uint16_t TIMERPICKER_POSY = 119; +static constexpr uint16_t SETTING_TIMERPICKER_SIZE_WIDTH = 88; +static constexpr uint16_t SETTING_TIMERPICKER_SIZE_HEIGHT = 189; +static constexpr uint16_t TIMERPICKER_RADIUS = 11; +static constexpr uint16_t SETTING_TIMERPICKER_ITEM_HEIGHT = 70; +static constexpr uint16_t SETTING_TIMERPICKER_HOUR = 24; +static constexpr uint16_t SETTING_TIMERPICKER_HOURS = 23; +static constexpr uint16_t SETTING_TIMERPICKER_MIN = 60; +static constexpr uint16_t SETTING_TIMERPICKER_MINS = 59; +static constexpr uint16_t SETTING_PICKERGROUP_POSX = 70; +static constexpr uint16_t SETTING_PICKERGROUP_POSY = 132; +static constexpr uint16_t SETTING_PICKERGROUP_SIZE_WIDTH = 80; +static constexpr uint16_t SETTING_PICKERGROUP_SIZE_HEIGHT = 208; +static constexpr uint16_t HOUR_TIME = 3600; +static constexpr uint16_t MIN_TIME = 60; +static constexpr uint16_t POX1_MIN = 86; +static constexpr uint16_t POX1_MAX = 174; +static constexpr uint16_t POX2_MIN = 206; +static constexpr uint16_t POX2_MAX = 294; +static constexpr uint16_t POX3_MIN = 332; +static constexpr uint16_t POX3_MAX = 420; +static constexpr uint16_t POY_MIN = 119; +static constexpr uint16_t POY_MAX = 308; +static constexpr uint16_t SLEEP = 500; +static constexpr uint16_t SUM_2 = 2; + +REGIST_SLICE_PAGE(VIEW_TIMER, TIMER_PAGES::TIMER_SETTING_PAGE, TimerSettingPage, false); + +TimerSettingPage::~TimerSettingPage() +{ + bool ret = ImageCacheManager::GetInstance().UnloadAllInMultiRes(TIMER_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnloadTimerImage fail"); + } + + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (back != nullptr) { + delete back; + back = nullptr; + } + + for (int i = 0; i < TIMERPICKER_MAX; i++) { + if (timerPicker[i] != nullptr) { + delete timerPicker[i]; + timerPicker[i] = nullptr; + } + } + + if (start != nullptr) { + delete start; + start = nullptr; + } + + if (timerLabel != nullptr) { + delete timerLabel; + timerLabel = nullptr; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerSettingPage::~TimerSettingPage"); +} + +void TimerSettingPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerSettingPage::OnStart() Start"); + bool ret = ImageCacheManager::GetInstance().LoadAllInMultiRes(TIMER_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadTimerImage fail"); + return; + } + image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_BEGIN_GRAY, TIMER_IMAGE); + if (image1 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadTimerImage image1 fail"); + return; + } + image2 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_BEGIN_ORANGE, TIMER_IMAGE); + if (image2 == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadTimerImage image2 fail"); + return; + } + // 标题 + if (title == nullptr) { + title = new UILabel(); + } + title->SetPosition(SETTING_TITLE_POSITION_X, SETTING_TITLE_POSITION_Y); + title->Resize(SETTING_TITLE_SIZE_WIDTH, SETTING_TITLE_SIZE_HEIGHT); + title->SetText("设置时间"); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTING_TITLE_TEXT_SIZE); + title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + title->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + title->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + title->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + if (group == nullptr) { + group = new UIScrollView(); + } + group->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + group->SetThrowDrag(true); + CreateLabel(); + CreateStartButton(); + CreatePicker(); + group->Add(title); + group->SetOnDragListener(this); + AddViewToPageContainer(group); +} + +void TimerSettingPage::CreateLabel(void) +{ + // Add Label to App + if (timerLabel == nullptr) { + timerLabel = new UILabel(); + } + timerLabel->SetPosition(SETTING_TIMERLABEL_POSITION_X, + SETTING_TIMERLABEL_POSITION_Y); // widget's left position and top position + timerLabel->Resize(SETTING_TIMERLABEL_SIZE_WIDTH, + SETTING_TIMERLABEL_SIZE_HEIGHT); // widget's width and height + timerLabel->SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFBF00); + timerLabel->SetStyle(STYLE_BACKGROUND_OPA, 0xef); + timerLabel->SetStyle(STYLE_BORDER_RADIUS, BORDER_RADIUS); + timerLabel->SetStyle(STYLE_PADDING_TOP, PADDING); + timerLabel->SetStyle(STYLE_PADDING_BOTTOM, PADDING); + timerLabel->SetStyle(STYLE_TEXT_FONT, TEXT_FONT); + + // Set additional property + timerLabel->SetText("小时"); + timerLabel->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + timerLabel->SetTextColor(Color::GetColorFromRGBA(0x00, 0x00, 0x00, 0xff)); + timerLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + timerLabel->SetDirect(TEXT_DIRECT_MIXED); + timerLabel->SetRollSpeed(0); + timerLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTING_TIMERLABEL_FONT); + timerLabel->SetVisible(false); + // Add to rootView + group->Add(timerLabel); +} + +void TimerSettingPage::CreateStartButton(void) +{ + // 开始按钮 + if (start == nullptr) { + start = new UIImageView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage:: new start UIImageView"); + } + start->SetPosition(SETTING_START_POSITION_X, SETTING_START_POSITION_Y); + start->Resize(SETTING_START_SIZE_WIDTH, SETTING_START_SIZE_HEIGHT); + start->SetViewId(START_TIMING); + start->SetTouchable(false); + start->SetOnClickListener(this); + start->SetSrc(image1); + group->Add(start); +} + +// 时间选择器分钟与秒钟列 +const char *uiPickerData[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", + "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", + "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", + "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", + "51", "52", "53", "54", "55", "56", "57", "58", "59", "00"}; + +// 时间选择器小时列 +const char *uiPicker5Data[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", + "15", "16", "17", "18", "19", "20", "21", "22", "23", "00"}; + +void TimerSettingPage::CreatePicker() +{ + // Add Picker to App + int posX[TIMERPICKER_MAX] = {TIMERPICKER_POSX1, TIMERPICKER_POSX2, TIMERPICKER_POSX3}; + int posY = TIMERPICKER_POSY; + for (int i = 0; i < TIMERPICKER_MAX; i++) { + if (timerPicker[i] == nullptr) { + timerPicker[i] = new UIPicker(); + } + timerPicker[i]->SetPosition(posX[i], posY); // widget's left position and top position + timerPicker[i]->Resize(SETTING_TIMERPICKER_SIZE_WIDTH, SETTING_TIMERPICKER_SIZE_HEIGHT); + timerPicker[i]->SetViewId("hourPicker"); // Set style + timerPicker[i]->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + timerPicker[i]->SetStyle(STYLE_BORDER_WIDTH, TIMERPICKER_MAX); + timerPicker[i]->SetStyle(STYLE_BORDER_RADIUS, TIMERPICKER_RADIUS); + timerPicker[i]->SetStyle(STYLE_BORDER_COLOR, 0xffb9b9b9); + timerPicker[i]->SetItemHeight(SETTING_TIMERPICKER_ITEM_HEIGHT); + timerPicker[i]->SetLoopState(true); + timerPicker[i]->SetBackgroundFont(DEFAULT_VECTOR_FONT_FILENAME, BACKGROUND_FONT); + timerPicker[i]->SetHighlightFont(DEFAULT_VECTOR_FONT_FILENAME, HIGHTLIGHT_FONT); + timerPicker[i]->SetTextColor(Color::GetColorFromRGBA(0x64, 0x69, 0x6e, 0xff), + Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0xff)); + if (i == 0) { + timerPicker[i]->SetValues(uiPicker5Data, SETTING_TIMERPICKER_HOUR); + timerPicker[i]->SetSelected(SETTING_TIMERPICKER_HOURS); + } else { + timerPicker[i]->SetValues(uiPickerData, SETTING_TIMERPICKER_MIN); + timerPicker[i]->SetSelected(SETTING_TIMERPICKER_MINS); + } + timerPicker[i]->SetOnClickListener(this); + timerPicker[i]->SetDraggable(true); + timerPicker[i]->SetOnDragListener(this); + timerPicker[i]->RegisterSelectedListener(this); + group->Add(timerPicker[i]); + } + + timerPicker[0]->SetViewId("hourPicker"); // Set style + timerPicker[1]->SetViewId("minPicker"); // Set style + timerPicker[SUM_2]->SetViewId("secPicker"); // Set style +} + +bool TimerSettingPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + std::string viewId = view.GetViewId(); + if (viewId == START_TIMING) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerSettingPage::OnClick viewId == START_TIMING"); + TimerModel::GetInstance().SetSaveTime(true, 0); + uint8_t hour = std::stoi(uiPicker5Data[timerPicker[0]->GetSelected()]); + uint8_t minute = std::stoi(uiPickerData[timerPicker[1]->GetSelected()]); + uint8_t second = std::stoi(uiPickerData[timerPicker[SUM_2]->GetSelected()]); + uint32_t durationTime = (hour * HOUR_TIME) + (minute * MIN_TIME) + (second); + TimerModel::GetInstance().SetDurationTime(durationTime); + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_TIMING_PAGE); + } + timerLabel->Invalidate(); + return true; +} + +bool TimerSettingPage::OnDrag(UIView &view, const DragEvent &event) +{ + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_MAIN_PAGE); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerSettingPage::OnDrag SwitchSlice(TIMER_MAIN_PAGE)"); + } + if (view.GetViewId() == "hourPicker") { + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Orange().full); + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[SUM_2]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerPicker[SUM_2]->Invalidate(); + timerLabel->SetVisible(true); + timerLabel->SetPosition(POX1_MIN, SETTING_TIMERLABEL_POSITION_Y); + timerLabel->SetText("小时"); + timerLabel->Invalidate(); + } else if (view.GetViewId() == "minPicker") { + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Orange().full); + timerPicker[SUM_2]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerPicker[SUM_2]->Invalidate(); + timerLabel->SetVisible(true); + timerLabel->SetPosition(POX2_MIN, SETTING_TIMERLABEL_POSITION_Y); + timerLabel->SetText("分钟"); + timerLabel->Invalidate(); + } else if (view.GetViewId() == "secPicker") { + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[SUM_2]->SetStyle(STYLE_BORDER_COLOR, Color::Orange().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerPicker[SUM_2]->Invalidate(); + timerLabel->SetVisible(true); + timerLabel->SetPosition(POX3_MIN, SETTING_TIMERLABEL_POSITION_Y); + timerLabel->SetText("秒"); + timerLabel->Invalidate(); + } + return true; +} + +void TimerSettingPage::OnPickerStoped(UIPicker& picker) +{ + if (picker.GetViewId() == "hourPicker") { + uint16_t hour = picker.GetSelected(); + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Orange().full); + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[SUM_2]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerPicker[SUM_2]->Invalidate(); + if ((hour == SETTING_TIMERPICKER_HOURS) && (timerPicker[1]->GetSelected() == SETTING_TIMERPICKER_MINS) && + (timerPicker[SUM_2]->GetSelected() == SETTING_TIMERPICKER_MINS)) { + start->SetTouchable(false); + start->SetSrc(image1); + } else { + start->SetTouchable(true); + start->SetSrc(image2); + } + timerLabel->SetVisible(true); + timerLabel->SetPosition(POX1_MIN, SETTING_TIMERLABEL_POSITION_Y); + timerLabel->SetText("小时"); + timerLabel->Invalidate(); + } else if (picker.GetViewId() == "minPicker") { + uint16_t minute = picker.GetSelected(); + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Orange().full); + timerPicker[SUM_2]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerPicker[SUM_2]->Invalidate(); + if ((timerPicker[0]->GetSelected() == SETTING_TIMERPICKER_HOURS) && (minute == SETTING_TIMERPICKER_MINS) && + (timerPicker[SUM_2]->GetSelected() == SETTING_TIMERPICKER_MINS)) { + start->SetTouchable(false); + start->SetSrc(image1); + } else { + start->SetTouchable(true); + start->SetSrc(image2); + } + timerLabel->SetVisible(true); + timerLabel->SetPosition(POX2_MIN, SETTING_TIMERLABEL_POSITION_Y); + timerLabel->SetText("分钟"); + timerLabel->Invalidate(); + } else { + uint16_t sec = picker.GetSelected(); + timerPicker[0]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[1]->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + timerPicker[SUM_2]->SetStyle(STYLE_BORDER_COLOR, Color::Orange().full); + timerPicker[0]->Invalidate(); + timerPicker[1]->Invalidate(); + timerPicker[SUM_2]->Invalidate(); + if ((timerPicker[0]->GetSelected() == SETTING_TIMERPICKER_HOURS) && + (timerPicker[1]->GetSelected() == SETTING_TIMERPICKER_MINS) && (sec == SETTING_TIMERPICKER_MINS)) { + start->SetTouchable(false); + start->SetSrc(image1); + } else { + start->SetTouchable(true); + start->SetSrc(image2); + } + timerLabel->SetVisible(true); + timerLabel->SetPosition(POX3_MIN, SETTING_TIMERLABEL_POSITION_Y); + timerLabel->SetText("秒"); + timerLabel->Invalidate(); + } +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerTimingPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerTimingPage.cpp new file mode 100644 index 000000000..f9da1e9bd --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/timers/src/TimerTimingPage.cpp @@ -0,0 +1,548 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TimerTimingPage + * Create: 2025-06-09 + */ + +#include +#include +#include "timers/TimerTimingPage.h" +#include "ui_test_group.h" +#include "timers/TimerPresenter.h" +#include "wearable_log.h" +#include "timers/TimerView.h" +#include "SlicePageFactory.h" +#include "common/image_cache_manager.h" +#include "pwm.h" +#include "main/LoadImg.h" +#ifdef BUILD_IN_LINUX +#include "localtime.h" +#endif + +namespace OHOS { +static constexpr uint16_t NUM_TEN = 10; +static constexpr uint16_t TIMING_TITLE_POSITION_X = 170; +static constexpr uint16_t TIMING_TITLE_POSITION_Y = 110; +static constexpr uint16_t TIMING_TITLE_SIZE_WIDTH = 114; +static constexpr uint16_t TIMING_TITLE_SIZE_HEIGHT = 38; +static constexpr uint16_t TIMING_TITLE_FONT = 38; +static constexpr uint16_t TIMING_LABEL_CURTIME_XPOS = 199; +static constexpr uint16_t TIMING_LABEL_CURTIME_YPOS = 54; +static constexpr uint16_t TIMING_LABEL_CURTIME_WIDTH = 67; +static constexpr uint16_t TIMING_LABEL_CURTIME_HEIGHT = 24; +static constexpr uint16_t TIMING_LABEL_CURTIME_FONT_SIZE = 24; +static constexpr uint16_t TIMING_START_IMAGE_XPOS = 251; +static constexpr uint16_t TIMING_START_IMAGE_YPOS = 306; +static constexpr uint16_t TIMING_START_IMAGE_SIZE = 96; +static constexpr uint16_t TIMING_RESET_IMAGE_XPOS = 107; +static constexpr uint16_t TIMING_RESET_IMAGE_YPOS = 306; +static constexpr uint16_t TIMING_RESET_IMAGE_SIZE = 96; +static constexpr uint16_t TIMING_TIMER_TIME_XPOS = 85; +static constexpr uint16_t TIMING_TIMER_TIME_YPOS = 182; +static constexpr uint16_t TIMING_TIMER_TIME_WIDTH = 322; +static constexpr uint16_t TIMING_TIMER_TIME_HEIGHT = 90; +static constexpr uint16_t TIMING_TIMER_TIME_FONT_SIZE = 72; +static constexpr uint16_t HOUR_TIME = 3600; +static constexpr uint16_t MIN_TIME = 60; +static constexpr uint16_t TIMING_CIRCLE_LINE_WIDTH = 10; +static constexpr uint16_t TIMING_CIRCLE = 227; +static constexpr uint16_t CIRCLE_RADIUS = 222; +static constexpr uint16_t TIMING_CIRCLE_END = 360; +static constexpr uint32_t TIMING_CIRCLE_RANGE = 100000; +static constexpr uint16_t MAX_SCR_DIS = 1000; +static constexpr uint32_t HOUR_RANGE = 60000; +static constexpr uint16_t TIMING_HAND_POSITION_XPOS = 224; +static constexpr uint16_t TIMING_HAND_POSITION_YPOS = 4; +static constexpr uint16_t TIMING_HAND_CENTER_XPOS = 3; +static constexpr uint16_t TIMING_HAND_CENTER_YPOS = 223; +static constexpr uint16_t TIMING_HAND_WIDTH = 2; +static constexpr uint16_t TIMING_HAND_HEIGHT = 5; + +REGIST_SLICE_PAGE(VIEW_TIMER, TIMER_PAGES::TIMER_TIMING_PAGE, TimerTimingPage, false); + +static std::string GetCurrentTimeStr() +{ + struct tm localTime; + time_t seconds = time(nullptr); + localtime_r(&seconds, &localTime); + std::string currTime; + if (localTime.tm_hour < NUM_TEN) { + currTime += "0"; + } + currTime += std::to_string(localTime.tm_hour) + ":"; + if (localTime.tm_min < NUM_TEN) { + currTime += "0"; + } + currTime += std::to_string(localTime.tm_min); + return currTime; +} + +TimerTimingPage::~TimerTimingPage() +{ + bool ret = ImageCacheManager::GetInstance().UnloadAllInMultiRes(TIMER_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnloadTimerImage fail"); + } + + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (sweepClock_ != nullptr) { + sweepClock_->RemoveAll(); + delete sweepClock_; + sweepClock_ = nullptr; + } + + if (dClock != nullptr) { + delete dClock; + dClock = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (timerTime != nullptr) { + delete timerTime; + timerTime = nullptr; + } + + if (reset != nullptr) { + delete reset; + reset = nullptr; + } + + if (start != nullptr) { + delete start; + start = nullptr; + } + + if (circleProgress != nullptr) { + delete circleProgress; + circleProgress = nullptr; + } + + if (currentTime_ != nullptr) { + delete currentTime_; + currentTime_ = nullptr; + } + + if (timeCallback_ != nullptr) { + delete timeCallback_; + timeCallback_ = nullptr; + } + + if (timeAnimator_ != nullptr) { + delete timeAnimator_; + timeAnimator_ = nullptr; + } + + if (callBack_ != nullptr) { + delete callBack_; + callBack_ = nullptr; + } + + if (animator_ != nullptr) { + delete animator_; + animator_ = nullptr; + } + + if (secondHand_ != nullptr) { + delete secondHand_; + secondHand_ = nullptr; + } + + if (backround != nullptr) { + delete backround; + backround = nullptr; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::~TimerTimingPage"); +} + +void TimerTimingPage::OnStart(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart() Start!"); + bool ret = ImageCacheManager::GetInstance().LoadAllInMultiRes(TIMER_IMAGE); + if (ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadTimerImage fail"); + return; + } + if (group == nullptr) { + group = new UIScrollView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new group"); + } + group->SetPosition(0, 0, VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + group->SetThrowDrag(true); + + if (backround == nullptr) { + backround = new UIImageView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new backround"); + } + ImageInfo *image = + ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_TIMER_BG, TIMER_IMAGE); + if (image == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart backround source fail"); + return; + } + backround->SetSrc(image); + backround->SetPosition(0, 0, VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + + if (sweepClock_ == nullptr) { + sweepClock_ = new UISweepClock(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new sweepClock_"); + } + sweepClock_->SetPosition(0, 0); + sweepClock_->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + sweepClock_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + if (secondHand_ == nullptr) { + secondHand_ = new Image(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new secondHand_"); + } + ImageInfo *second = + ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_TIMER_POINTER, TIMER_IMAGE); + if (second == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart second source fail"); + return; + } + secondHand_->SetSrc(second); + sweepClock_->SetHandImage(UISweepClock::HandType::SECOND_HAND, *secondHand_, + {TIMING_HAND_POSITION_XPOS, TIMING_HAND_POSITION_YPOS}, {TIMING_HAND_CENTER_XPOS, TIMING_HAND_CENTER_YPOS}); + sweepClock_->SetHandLine(UISweepClock::HandType::HOUR_HAND, {TIMING_HAND_POSITION_XPOS, TIMING_HAND_POSITION_YPOS}, + {TIMING_HAND_CENTER_XPOS, TIMING_HAND_CENTER_YPOS}, Color::White(), TIMING_HAND_WIDTH, TIMING_HAND_HEIGHT, + OPA_TRANSPARENT); + sweepClock_->SetHandLine(UISweepClock::HandType::MINUTE_HAND, + {TIMING_HAND_POSITION_XPOS, TIMING_HAND_POSITION_YPOS}, {TIMING_HAND_CENTER_XPOS, TIMING_HAND_CENTER_YPOS}, + Color::White(), TIMING_HAND_WIDTH, TIMING_HAND_HEIGHT, OPA_TRANSPARENT); + + // 标题 + if (title == nullptr) { + title = new UILabel(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new title"); + } + title->SetPosition(TIMING_TITLE_POSITION_X, TIMING_TITLE_POSITION_Y); + title->Resize(TIMING_TITLE_SIZE_WIDTH, TIMING_TITLE_SIZE_HEIGHT); + title->SetText("计时器"); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIMING_TITLE_FONT); + title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + title->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + title->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + if (currentTime_ == nullptr) { + currentTime_ = new UILabel(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new currentTime_"); + } + currentTime_->SetPosition(TIMING_LABEL_CURTIME_XPOS, TIMING_LABEL_CURTIME_YPOS); + currentTime_->Resize(TIMING_LABEL_CURTIME_WIDTH, TIMING_LABEL_CURTIME_HEIGHT); + currentTime_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIMING_LABEL_CURTIME_FONT_SIZE); + currentTime_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + currentTime_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + currentTime_->SetVisible(true); + + group->Add(backround); + CircleProgress(); + group->Add(sweepClock_); + CreateButton(); + CreateTimerTime(); + group->Add(title); + group->Add(currentTime_); + group->SetOnDragListener(this); + AddViewToPageContainer(group); + + if (timeCallback_ == nullptr) { + timeCallback_ = new TimeAnimatorCallback(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new timeCallback_"); + } + + if (timeAnimator_ == nullptr) { + timeAnimator_ = new Animator(timeCallback_, currentTime_, 0, true); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnStart new Animator timeAnimator_"); + } + timeAnimator_->Start(); +} + +void TimerTimingPage::OnResume() +{ + if (TimerModel::GetInstance().GetExistTimer()) { + SetAnimatorStatus(true); + TimerModel::GetInstance().SetExistTimer(false); + } + if (timeAnimator_ != nullptr) { + if (timeAnimator_->GetState() == Animator::STOP) { + timeAnimator_->Start(); + } + } + if (!start->IsTouchable()) { + LOADIMG::LoadImageViewImg(start, TIMER_IMAGE, IMAGE_CONVERTER_TOOL_TIMER_PAUSE); + } +} + +void TimerTimingPage::OnPause() +{ + if (TimerModel::GetInstance().GetIsTiming()) { + TimerModel::GetInstance().SetExistTimer(true); + } + if (timeAnimator_ != nullptr) { + if (timeAnimator_->GetState() != Animator::STOP) { + timeAnimator_->Stop(); + } + } + SetAnimatorStatus(false); +} + +void TimerTimingPage::CreateButton() +{ + ImageInfo *image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_PLAY, TIMER_IMAGE); + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_EXIT, TIMER_IMAGE); + // 开始/暂停按钮 + if (start == nullptr) { + start = new UIImageView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::CreateButton new start"); + } + start->SetPosition(TIMING_START_IMAGE_XPOS, TIMING_START_IMAGE_YPOS); + start->Resize(TIMING_START_IMAGE_SIZE, TIMING_START_IMAGE_SIZE); + start->SetViewId(START_PAUSE); + start->SetTouchable(true); + start->SetOnClickListener(this); + start->SetSrc(image1); + group->Add(start); + + // 复位按钮 + ImageInfo *image2 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_EXIT, TIMER_IMAGE); + if (reset == nullptr) { + reset = new UIImageView(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::CreateButton new reset"); + } + reset->SetPosition(TIMING_RESET_IMAGE_XPOS, TIMING_RESET_IMAGE_YPOS); + reset->Resize(TIMING_RESET_IMAGE_SIZE, TIMING_RESET_IMAGE_SIZE); + reset->SetViewId(RESET); + reset->SetTouchable(true); + reset->SetOnClickListener(this); + reset->SetSrc(image2); + group->Add(reset); +} + +void TimerTimingPage::CreateTimerTime() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::CreateTimerTime() Start!"); + if (timerTime == nullptr) { + timerTime = new UIDigitalClock(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::CreateTimerTime() new timerTime!"); + } + timerTime->SetPosition(TIMING_TIMER_TIME_XPOS, TIMING_TIMER_TIME_YPOS); + timerTime->Resize(TIMING_TIMER_TIME_WIDTH, TIMING_TIMER_TIME_HEIGHT); + timerTime->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIMING_TIMER_TIME_FONT_SIZE); + timerTime->SetDisplayMode(UIDigitalClock::DISPLAY_24_HOUR); + timerTime->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + uint32_t durationTime = TimerModel::GetInstance().GetDurationTime(); + uint8_t hour = durationTime / HOUR_TIME; + uint8_t minute = durationTime % HOUR_TIME / MIN_TIME; + uint8_t second = durationTime % MIN_TIME; + timerTime->SetTime24Hour(hour, minute, second); + group->Add(timerTime); +} + +void TimerTimingPage::CircleProgress() +{ + // 动态计时圈 + if (circleProgress == nullptr) { + circleProgress = new UICircleProgress(); + } + circleProgress->SetPosition(0, 0); // widget's left position and top position + circleProgress->Resize(RESOLUTION_WIDTH, RESOLUTION_HEIGHT); // widget's width and height + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_BG_CIR, TIMER_IMAGE); + ImageInfo *image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_PBG, TIMER_IMAGE); + circleProgress->SetImage(image1, image); + circleProgress->EnableBackground(true); + circleProgress->SetBackgroundStyle(STYLE_LINE_WIDTH, TIMING_CIRCLE_LINE_WIDTH); + circleProgress->SetForegroundStyle(STYLE_LINE_WIDTH, TIMING_CIRCLE_LINE_WIDTH); + circleProgress->EnableBackground(true); + circleProgress->SetCenterPosition(TIMING_CIRCLE, TIMING_CIRCLE); + circleProgress->SetRadius(CIRCLE_RADIUS); + circleProgress->SetStartAngle(0); + circleProgress->SetEndAngle(TIMING_CIRCLE_END); + circleProgress->SetRange(TIMING_CIRCLE_RANGE, 0); + circleProgress->SetValue(TIMING_CIRCLE_RANGE); + // Add to rootView + SetupAnimator(); + group->Add(circleProgress); +} + +// 单位为毫秒计算 +void TimerTimingPage::SetTimerTime(uint32_t onTime) +{ + uint64_t time = onTime / MAX_SCR_DIS; + uint8_t hour = time / HOUR_TIME; + uint8_t minute = time % HOUR_TIME / MIN_TIME; + uint8_t second = time % MIN_TIME; + timerTime->SetTime24Hour(hour, minute, second); + uint32_t totalTime = TimerModel::GetInstance().GetDurationTime(); + double percentage = static_cast(onTime) / (totalTime * MAX_SCR_DIS); + double value = round(percentage * TIMING_CIRCLE_RANGE); + circleProgress->SetValue(value); + sweepClock_->SetSweepTime24Hour(0, 0, percentage * HOUR_RANGE); + + if (onTime <= 0) { + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_PAUSE, TIMER_IMAGE); + ImageInfo *image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_EXIT, TIMER_IMAGE); + start->SetSrc(image); + start->SetTouchable(false); + reset->SetSrc(image1); + TimerModel::GetInstance().SetIsPause(false); + TimerModel::GetInstance().SetIsTiming(false); + start->Invalidate(); + reset->Invalidate(); + } + circleProgress->Invalidate(); + timerTime->Invalidate(); +} + +void TimerTimingPage::SetupAnimator() +{ + callBack_ = new TimerTimingCallback(this); + animator_ = new Animator(callBack_, nullptr, 0, true); +} + +void TimerTimingPage::TimerTimingCallback::Callback(UIView *view) +{ + (void)view; + static int count = 0; + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + + uint32_t overTime = TimerModel::GetInstance().GetDurationTime(); + uint32_t s_time = TimerModel::GetInstance().GetStartTime(); + uint32_t saveTime = TimerModel::GetInstance().GetSaveTime(); + uint64_t c_time = current_time.tv_sec * MAX_SCR_DIS + current_time.tv_usec / MAX_SCR_DIS; + int32_t remTime = overTime * MAX_SCR_DIS - (c_time - s_time) - saveTime; + + page_->SetTimerTime(remTime); + if (remTime <= 0) { + page_->animator_->Stop(); + page_->SetTimerTime(0); + // 调用pwm接口实现马达震动,客户自实现 + } +} + +void TimerTimingPage::SetAnimatorStatus(bool status) +{ + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_PAUSE_ORANGE, TIMER_IMAGE); + ImageInfo *image1 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_PLAY, TIMER_IMAGE); + ImageInfo *image2 = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_RESTART, TIMER_IMAGE); + if (status) { + start->SetSrc(image); + reset->SetSrc(image2); + animator_->Start(); + TimerModel::GetInstance().InitTimer(); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::SetAnimatorStatus status == false"); + animator_->Stop(); + start->SetSrc(image1); + TimerModel::GetInstance().DisableTimer(); + } +} + +bool TimerTimingPage::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && + (event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + if (TimerModel::GetInstance().GetIsTiming()) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnDrag ChangeSlice(VIEW_APPLIST)"); + } else { + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_MAIN_PAGE); + } + } + return true; +} + +bool TimerTimingPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + std::string viewId = view.GetViewId(); + if (viewId == RESET) { + if (TimerModel::GetInstance().GetIsTiming()) { + // 停止计时器 修改复位图标 重新将时间复原 + SetAnimatorStatus(false); + TimerModel::GetInstance().SetIsTiming(false); + uint32_t durationTime = TimerModel::GetInstance().GetDurationTime(); + uint8_t hour = durationTime / HOUR_TIME; + uint8_t minute = durationTime % HOUR_TIME / MIN_TIME; + uint8_t second = durationTime % MIN_TIME; + timerTime->SetTime24Hour(hour, minute, second); + TimerModel::GetInstance().SetSaveTime(true, 0); + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_EXIT, TIMER_IMAGE); + reset->SetSrc(image); + circleProgress->SetValue(TIMING_CIRCLE_RANGE); + sweepClock_->SetSweepTime24Hour(0, 0, 0); + } else if (! TimerModel::GetInstance().GetIsTiming() && TimerModel::GetInstance().GetIsPause()) { + TimerModel::GetInstance().SetIsTiming(false); + uint32_t durationTime = TimerModel::GetInstance().GetDurationTime(); + uint8_t hour = durationTime / HOUR_TIME; + uint8_t minute = durationTime % HOUR_TIME / MIN_TIME; + uint8_t second = durationTime % MIN_TIME; + timerTime->SetTime24Hour(hour, minute, second); + TimerModel::GetInstance().SetSaveTime(true, 0); + ImageInfo *image = ImageCacheManager::GetInstance().LoadOneInMultiRes( + IMAGE_CONVERTER_TOOL_TIMER_EXIT, TIMER_IMAGE); + reset->SetSrc(image); + circleProgress->SetValue(TIMING_CIRCLE_RANGE); + sweepClock_->SetSweepTime24Hour(0, 0, 0); + TimerModel::GetInstance().SetIsPause(false); + } else { + NativeAbility::GetInstance().SwitchSlice(VIEW_TIMER, TIMER_PAGES::TIMER_MAIN_PAGE); + } + } else if (viewId == START_PAUSE) { + if (TimerModel::GetInstance().GetIsTiming()) { + SetAnimatorStatus(false); + TimerModel::GetInstance().SetIsTiming(false); + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + uint32_t time = (current_time.tv_sec * MAX_SCR_DIS + current_time.tv_usec / MAX_SCR_DIS) - + TimerModel::GetInstance().GetStartTime(); + TimerModel::GetInstance().SetSaveTime(false, time); + TimerModel::GetInstance().SetIsPause(true); + } else { + SetAnimatorStatus(true); + TimerModel::GetInstance().SetIsTiming(true); + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + uint32_t s_time = current_time.tv_sec * MAX_SCR_DIS + current_time.tv_usec / MAX_SCR_DIS; // 转换成ms + TimerModel::GetInstance().SetStartTime(s_time); + TimerModel::GetInstance().SetIsPause(false); + } + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TimerTimingPage::OnClick"); + return false; + } + return true; +} + +void TimerTimingPage::TimeAnimatorCallback::Callback(UIView *view) +{ + UILabel *timeLabel = dynamic_cast(view); + if (timeLabel == nullptr) { + return; + } + std::string currTime = GetCurrentTimeStr(); + timeLabel->SetText(currTime.c_str()); + timeLabel->Invalidate(); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/DataView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/DataView.cpp new file mode 100644 index 000000000..0abd0f6d3 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/DataView.cpp @@ -0,0 +1,363 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Data View + * Create: 2025-03-22 + */ +#include "training/DataView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t TOP_VALUE_LABEL_FONT = 80; +static constexpr uint16_t VALUE_LABEL_FONT = 60; +static constexpr uint16_t UNIT_LABEL_FONT = 30; +static constexpr uint16_t TOP_VALUE_LABEL_X = 164; +static constexpr uint16_t TOP_VALUE_LABEL_Y = 45; +static constexpr uint16_t TOP_VALUE_LABEL_W = 200; +static constexpr uint16_t TOP_VALUE_LABEL_H = 60; +static constexpr uint16_t TOP_UNIT_LABEL_X = 184; +static constexpr uint16_t TOP_UNIT_LABEL_Y = 135; +static constexpr uint16_t TOP_UNIT_LABEL_W = 200; +static constexpr uint16_t TOP_UNIT_LABEL_H = 60; +static constexpr uint16_t LEFT_VALUE_LABEL_X = 52; +static constexpr uint16_t LEFT_VALUE_LABEL_Y = 176; +static constexpr uint16_t LEFT_VALUE_LABEL_W = 200; +static constexpr uint16_t LEFT_VALUE_LABEL_H = 60; +static constexpr uint16_t LEFT_UNIT_LABEL_X = 71; +static constexpr uint16_t LEFT_UNIT_LABEL_Y = 247; +static constexpr uint16_t LEFT_UNIT_LABEL_W = 200; +static constexpr uint16_t LEFT_UNIT_LABEL_H = 60; +static constexpr uint16_t RIGHT_VALUE_LABEL_X = 310; +static constexpr uint16_t RIGHT_VALUE_LABEL_Y = 181; +static constexpr uint16_t RIGHT_VALUE_LABEL_W = 200; +static constexpr uint16_t RIGHT_VALUE_LABEL_H = 60; +static constexpr uint16_t RIGHT_UNIT_LABEL_X = 323; +static constexpr uint16_t RIGHT_UNIT_LABEL_Y = 253; +static constexpr uint16_t RIGHT_UNIT_LABEL_W = 200; +static constexpr uint16_t RIGHT_UNIT_LABEL_H = 60; +static constexpr uint16_t BOTTOM_VALUE_LABEL_X = 113; +static constexpr uint16_t BOTTOM_VALUE_LABEL_Y = 297; +static constexpr uint16_t BOTTOM_VALUE_LABEL_W = 200; +static constexpr uint16_t BOTTOM_VALUE_LABEL_H = 60; +static constexpr uint16_t BOTTOM_UNIT_LABEL_X = 217; +static constexpr uint16_t BOTTOM_UNIT_LABEL_Y = 374; +static constexpr uint16_t BOTTOM_UNIT_LABEL_W = 200; +static constexpr uint16_t BOTTOM_UNIT_LABEL_H = 60; +static constexpr uint16_t SEP_LINE_X = 234; +static constexpr uint16_t SEP_LINE_Y = 181; +static constexpr uint16_t SEP_LINE_W = 4; +static constexpr uint16_t SEP_LINE_H = 85; + +static DataView *g_pDataView{nullptr}; + +DataView::DataView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DataView::DataView"); + g_pDataView = this; +} + +DataView::~DataView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DataView::~DataView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (backGround != nullptr) { + delete backGround; + backGround = nullptr; + } + if (heartrate != nullptr) { + delete heartrate; + heartrate = nullptr; + } + if (sepLine != nullptr) { + delete sepLine; + sepLine = nullptr; + } + if (topValueLabel != nullptr) { + delete topValueLabel; + topValueLabel = nullptr; + } + if (topUnitLabel != nullptr) { + delete topUnitLabel; + topUnitLabel = nullptr; + } + if (leftValueLabel != nullptr) { + delete leftValueLabel; + leftValueLabel = nullptr; + } + if (leftUnitLabel != nullptr) { + delete leftUnitLabel; + leftUnitLabel = nullptr; + } + if (rightValueLabel != nullptr) { + delete rightValueLabel; + rightValueLabel = nullptr; + } + if (rightUnitLabel != nullptr) { + delete rightUnitLabel; + rightUnitLabel = nullptr; + } + if (bottomValueLabel != nullptr) { + delete bottomValueLabel; + bottomValueLabel = nullptr; + } + if (bottomUnitLabel != nullptr) { + delete bottomUnitLabel; + bottomUnitLabel = nullptr; + } + g_pDataView = nullptr; +} + +DataView *DataView::GetInstance() +{ + return g_pDataView; +} + +void DataView::ShowupBackgroup() +{ + backGround = new UIImageView(); + if (backGround == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backGroundFirst new fail"); + return; + } + backGround->SetPosition(0, 0); + backGround->SetSrc(PNG_WALK_BACK_GROUND); + group->Add(backGround); +} + +void DataView::ShowupTopView() +{ + // Add Label to App + if (topValueLabel == nullptr) { + topValueLabel = new UILabel(); + } + topValueLabel->SetPosition(TOP_VALUE_LABEL_X, TOP_VALUE_LABEL_Y); + topValueLabel->Resize(TOP_VALUE_LABEL_W, TOP_VALUE_LABEL_H); + + // Set additional property + topValueLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + topValueLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + topValueLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, VALUE_LABEL_FONT); + + // Add to rootView + group->Add(topValueLabel); + + // Add Label to App + if (topUnitLabel == nullptr) { + topUnitLabel = new UILabel(); + } + topUnitLabel->SetPosition(TOP_UNIT_LABEL_X, TOP_UNIT_LABEL_Y); + topUnitLabel->Resize(TOP_UNIT_LABEL_W, TOP_UNIT_LABEL_H); + + // Set additional property + topUnitLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + topUnitLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + topUnitLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, UNIT_LABEL_FONT); + + // Add to rootView + group->Add(topUnitLabel); +} + +void DataView::ShowupLeftView() +{ + // Add Label to App + if (leftValueLabel == nullptr) { + leftValueLabel = new UILabel(); + } + leftValueLabel->SetPosition(LEFT_VALUE_LABEL_X, LEFT_VALUE_LABEL_Y); + leftValueLabel->Resize(LEFT_VALUE_LABEL_W, LEFT_VALUE_LABEL_H); + + // Set additional property + leftValueLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + leftValueLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + leftValueLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, VALUE_LABEL_FONT); + + // Add to rootView + group->Add(leftValueLabel); + + // Add Label to App + if (leftUnitLabel == nullptr) { + leftUnitLabel = new UILabel(); + } + leftUnitLabel->SetPosition(LEFT_UNIT_LABEL_X, LEFT_UNIT_LABEL_Y); + leftUnitLabel->Resize(LEFT_UNIT_LABEL_W, LEFT_UNIT_LABEL_H); + + // Set additional property + leftUnitLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + leftUnitLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + leftUnitLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, UNIT_LABEL_FONT); + + // Add to rootView + group->Add(leftUnitLabel); +} + +void DataView::ShowupRightView() +{ + // Add Label to App + if (rightValueLabel == nullptr) { + rightValueLabel = new UILabel(); + } + rightValueLabel->SetPosition(RIGHT_VALUE_LABEL_X, RIGHT_VALUE_LABEL_Y); + rightValueLabel->Resize(RIGHT_VALUE_LABEL_W, RIGHT_VALUE_LABEL_H); + + // Set additional property + rightValueLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + rightValueLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + rightValueLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, VALUE_LABEL_FONT); + + // Add to rootView + group->Add(rightValueLabel); + + // Add Label to App + if (rightUnitLabel == nullptr) { + rightUnitLabel = new UILabel(); + } + rightUnitLabel->SetPosition(RIGHT_UNIT_LABEL_X, RIGHT_UNIT_LABEL_Y); + rightUnitLabel->Resize(RIGHT_UNIT_LABEL_W, RIGHT_UNIT_LABEL_H); + + // Set additional property + rightUnitLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + rightUnitLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + rightUnitLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, UNIT_LABEL_FONT); + + // Add to rootView + group->Add(rightUnitLabel); +} + +void DataView::ShowupBottomView() +{ + // Add Label to App + if (bottomValueLabel == nullptr) { + bottomValueLabel = new UILabel(); + } + bottomValueLabel->SetPosition(BOTTOM_VALUE_LABEL_X, BOTTOM_VALUE_LABEL_Y); + bottomValueLabel->Resize(BOTTOM_VALUE_LABEL_W, BOTTOM_VALUE_LABEL_H); + + // Set additional property + bottomValueLabel->SetText("00:12:15"); + bottomValueLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + bottomValueLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + bottomValueLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, VALUE_LABEL_FONT); + + // Add to rootView + group->Add(bottomValueLabel); + + // Add Label to App + if (bottomUnitLabel == nullptr) { + bottomUnitLabel = new UILabel(); + } + bottomUnitLabel->SetPosition(BOTTOM_UNIT_LABEL_X, BOTTOM_UNIT_LABEL_Y); + bottomUnitLabel->Resize(BOTTOM_UNIT_LABEL_W, BOTTOM_UNIT_LABEL_H); + + // Set additional property + bottomUnitLabel->SetText("时间"); + bottomUnitLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + bottomUnitLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + bottomUnitLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, UNIT_LABEL_FONT); + + // Add to rootView + group->Add(bottomUnitLabel); +} + +void DataView::ShowupSepLine() +{ + sepLine = new UICanvas(); + if (sepLine == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ShowupSepLine new fail"); + return; + } + sepLine->SetPosition(SEP_LINE_X, SEP_LINE_Y, SEP_LINE_W, SEP_LINE_H); + sepLine->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + sepLine->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + group->Add(sepLine); +} + +UIViewGroup *DataView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DataView init"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + ShowupBackgroup(); + ShowupTopView(); + ShowupLeftView(); + ShowupRightView(); + ShowupBottomView(); + ShowupSepLine(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(DATA_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} + +void DataView::UpdateDataViewByType() +{ + uint8_t trainingType = TrainingModel::GetInstance().GetCurTrainingType(); + if (trainingType == TRAINING_TYPE_OUTDOOR_RUNNING) { + topValueLabel->SetText("105"); + topUnitLabel->SetText("心率(次/分钟)"); + leftValueLabel->SetText("00'35\""); + leftUnitLabel->SetText("配速(/km)"); + rightValueLabel->SetText("3.25"); + rightUnitLabel->SetText("距离(km)"); + } else if (trainingType == TRAINING_TYPE_INDOOR_RUNNING) { + topValueLabel->SetText("105"); + topUnitLabel->SetText("心率(次/分钟)"); + leftValueLabel->SetText("00'35\""); + leftUnitLabel->SetText("配速(/km)"); + rightValueLabel->SetText("3.25"); + rightUnitLabel->SetText("距离(km)"); + } else if (trainingType == TRAINING_TYPE_CYCLING) { + topValueLabel->SetText("105"); + topUnitLabel->SetText("心率(次/分钟)"); + leftValueLabel->SetText("00'35\""); + leftUnitLabel->SetText("配速(/km)"); + rightValueLabel->SetText("3.25"); + rightUnitLabel->SetText("距离(km)"); + } else if (trainingType == TRAINING_TYPE_CLIMBING) { + topValueLabel->SetText("198"); + topUnitLabel->SetText("海拔(m)"); + leftValueLabel->SetText("535"); + leftUnitLabel->SetText("累计上升(m)"); + rightValueLabel->SetText("180"); + rightUnitLabel->SetText("累计下降(m)"); + } else if (trainingType == TRAINING_TYPE_INDOOR_SWIMMING) { + topValueLabel->SetText("105"); + topUnitLabel->SetText("心率(次/分钟)"); + leftValueLabel->SetText("235"); + leftUnitLabel->SetText("热量(kcal)"); + rightValueLabel->SetText("125"); + rightUnitLabel->SetText("距离(km)"); + } else if (trainingType == TRAINING_TYPE_OUTDOOR_SWIMMING) { + topValueLabel->SetText("105"); + topUnitLabel->SetText("心率(次/分钟)"); + leftValueLabel->SetText("235"); + leftUnitLabel->SetText("热量(kcal)"); + rightValueLabel->SetText("125"); + rightUnitLabel->SetText("距离(km)"); + } + topValueLabel->Invalidate(); + topUnitLabel->Invalidate(); + leftValueLabel->Invalidate(); + leftUnitLabel->Invalidate(); + rightValueLabel->Invalidate(); + rightUnitLabel->Invalidate(); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/MenuView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/MenuView.cpp new file mode 100644 index 000000000..e313fd6d2 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/MenuView.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Menu View + * Create: 2025-03-22 + */ +#include "training/MenuView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t TITLI_LABEL_FONT = 50; +static constexpr uint16_t TITLI_LABEL_X = 133; +static constexpr uint16_t TITLI_LABEL_Y = 36; +static constexpr uint16_t TITLI_LABEL_W = 200; +static constexpr uint16_t TITLI_LABEL_H = 60; +static constexpr uint16_t LIST_X = 42; +static constexpr uint16_t LIST_Y = 95; +static constexpr uint16_t LIST_W = 420; +static constexpr uint16_t LIST_H = 305; + +static MenuView *g_pMenuView{nullptr}; + +MenuView::MenuView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MenuView::MenuView"); + g_pMenuView = this; +} + +MenuView::~MenuView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MenuView::~MenuView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (titleLabel != nullptr) { + delete titleLabel; + titleLabel = nullptr; + } + if (trainingList != nullptr) { + delete trainingList; + trainingList = nullptr; + } + if (listAdapter_ != nullptr) { + delete listAdapter_; + listAdapter_ = nullptr; + } + g_pMenuView = nullptr; +} + +MenuView *MenuView::GetInstance() +{ + return g_pMenuView; +} + +void MenuView::CreateUILabel() +{ + // Add Label to App + if (titleLabel == nullptr) { + titleLabel = new UILabel(); + } + titleLabel->SetPosition(TITLI_LABEL_X, TITLI_LABEL_Y); + titleLabel->Resize(TITLI_LABEL_W, TITLI_LABEL_H); + + // Set additional property + titleLabel->SetText("体能训练"); + titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + titleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TITLI_LABEL_FONT); + + // Add to rootView + group->Add(titleLabel); +} + +void MenuView::CreateUIList() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return; + } + + // Add List to App + if (trainingList == nullptr) { + trainingList = new UIList(); + } + trainingList->SetPosition(LIST_X, LIST_Y); + trainingList->Resize(LIST_W, LIST_H); + + // Set additional property + if (listAdapter_ == nullptr) { + listAdapter_ = new TrainingAdapter(); + } + listAdapter_->SetItemClickListener(clickListener); + std::list trainingItemList(trainings, trainings + TRAINING_TYPE_MAX); + listAdapter_->SetData(trainingItemList); + + trainingList->SetAdapter(listAdapter_); + trainingList->RefreshList(); + + // Add to rootView + group->Add(trainingList); +} + +UIViewGroup *MenuView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MenuView init"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + CreateUILabel(); + CreateUIList(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(MENU_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/PauseView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/PauseView.cpp new file mode 100644 index 000000000..17e343462 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/PauseView.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +/* + * Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. + * Description: Pause View + * Create: 2025-03-22 + */ +#include "training/PauseView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t TIME_LABEL_FONT = 30; +static constexpr uint16_t TIME_LABEL_X = 194; +static constexpr uint16_t TIME_LABEL_Y = 42; +static constexpr uint16_t TIME_LABEL_W = 200; +static constexpr uint16_t TIME_LABEL_H = 60; +static constexpr uint16_t TEXT_LABEL_FONT = 70; +static constexpr uint16_t TEXT_LABEL_X = 128; +static constexpr uint16_t TEXT_LABEL_Y = 133; +static constexpr uint16_t TEXT_LABEL_W = 337; +static constexpr uint16_t TEXT_LABEL_H = 152; +static constexpr uint16_t BUTTON_FONT = 40; +static constexpr uint16_t BUTTON_X = 136; +static constexpr uint16_t BUTTON_Y1 = 236; +static constexpr uint16_t BUTTON_Y2 = 329; +static constexpr uint16_t BUTTON_W = 193; +static constexpr uint16_t BUTTON_H = 75; + +#define BUTTON_TEXT_CONTINUE "ç»§ç»­" +#define BUTTON_TEXT_FINISH "结束" + +static PauseView *g_pPauseView{nullptr}; + +PauseView::PauseView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PauseView::PauseView"); + g_pPauseView = this; +} + +PauseView::~PauseView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PauseView::~PauseView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (timeLabel != nullptr) { + delete timeLabel; + timeLabel = nullptr; + } + if (textLabel != nullptr) { + delete textLabel; + textLabel = nullptr; + } + if (continueButton != nullptr) { + delete continueButton; + continueButton = nullptr; + } + if (finishButton != nullptr) { + delete finishButton; + finishButton = nullptr; + } + g_pPauseView = nullptr; +} + +PauseView *PauseView::GetInstance() +{ + return g_pPauseView; +} + +void PauseView::CreateUILabel() +{ + // Add Label to App + if (timeLabel == nullptr) { + timeLabel = new UILabel(); + } + timeLabel->SetPosition(TIME_LABEL_X, TIME_LABEL_Y); + timeLabel->Resize(TIME_LABEL_W, TIME_LABEL_H); + + // Set additional property + timeLabel->SetText("11:59"); + timeLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + timeLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + timeLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIME_LABEL_FONT); + + // Add to rootView + group->Add(timeLabel); + + // Add Label to App + if (textLabel == nullptr) { + textLabel = new UILabel(); + } + textLabel->SetPosition(TEXT_LABEL_X, TEXT_LABEL_Y); + textLabel->Resize(TEXT_LABEL_W, TEXT_LABEL_H); + + // Set additional property + textLabel->SetText("已暂停"); + textLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + textLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + textLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TEXT_LABEL_FONT); + + // Add to rootView + group->Add(textLabel); +} + +void PauseView::CreateUIButton() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return; + } + // Add LabelButtonExt to App + if (continueButton == nullptr) { + continueButton = new UILabelButton(); + } + continueButton->SetPosition(BUTTON_X, BUTTON_Y1); + continueButton->Resize(BUTTON_W, BUTTON_H); + continueButton->SetViewId(TRAINING_PAUSE_CONTINUE_BUTTON); + + // Set additional property + continueButton->SetText(BUTTON_TEXT_CONTINUE); + continueButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_FONT); + continueButton->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + continueButton->SetOnClickListener(clickListener); + + // Add to rootView + group->Add(continueButton); + + // Add LabelButtonExt to App + if (finishButton == nullptr) { + finishButton = new UILabelButton(); + } + finishButton->SetPosition(BUTTON_X, BUTTON_Y2); + finishButton->Resize(BUTTON_W, BUTTON_H); + finishButton->SetViewId(TRAINING_PAUSE_FINISH_BUTTON); + finishButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffbc321e); + + // Set additional property + finishButton->SetText(BUTTON_TEXT_FINISH); + finishButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_FONT); + finishButton->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + finishButton->SetOnClickListener(clickListener); + + // Add to rootView + group->Add(finishButton); +} + +UIViewGroup *PauseView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PauseView init"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + CreateUILabel(); + CreateUIButton(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(PAUSE_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/PrepareView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/PrepareView.cpp new file mode 100644 index 000000000..1e2e14af0 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/PrepareView.cpp @@ -0,0 +1,345 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Prepare View + * Create: 2025-03-22 + */ +#include "training/PrepareView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" +#include "screensetting/ScreenModels.h" +#include "ui_resource_image.h" + +namespace OHOS { + +static constexpr uint16_t HEARTBEAT_IMAGE_X = 366; +static constexpr uint16_t HEARTBEAT_IMAGE_Y = 165; +static constexpr uint16_t HEARTBEAT_IMAGE_W = 56; +static constexpr uint16_t HEARTBEAT_IMAGE_H = 56; +static constexpr uint16_t HEARTBEAT_IMAGE_NUM = 19; +static constexpr uint16_t HEARTBEAT_DELAY = 50; +static constexpr uint16_t HEARTBEAT_LABEL_X = 363; +static constexpr uint16_t HEARTBEAT_LABEL_Y = 241; +static constexpr uint16_t HEARTBEAT_LABEL_W = 86; +static constexpr uint16_t HEARTBEAT_LABEL_H = 30; +static constexpr uint16_t HEARTBEAT_LABEL_FONT = 30; +static constexpr uint16_t BATTERY_X = 175; +static constexpr uint16_t BATTERY_Y = 84; +static constexpr uint16_t BATTERY_LABEL_FONT = 30; +static constexpr uint16_t BATTERY_LABEL_X = 232; +static constexpr uint16_t BATTERY_LABEL_Y = 75; +static constexpr uint16_t BATTERY_LABEL_W = 86; +static constexpr uint16_t BATTERY_LABEL_H = 30; +static constexpr uint16_t GPS_X = 30; +static constexpr uint16_t GPS_Y = 167; +static constexpr uint16_t GPS_W = 56; +static constexpr uint16_t GPS_H = 56; +static constexpr uint16_t GPS_LABEL_FONT = 30; +static constexpr uint16_t GPS_LABEL_X = 29; +static constexpr uint16_t GPS_LABEL_Y = 227; +static constexpr uint16_t GPS_LABEL_W = 200; +static constexpr uint16_t GPS_LABEL_H = 60; +static constexpr uint16_t TIME_LABEL_FONT = 30; +static constexpr uint16_t TIME_LABEL_X = 177; +static constexpr uint16_t TIME_LABEL_Y = 36; +static constexpr uint16_t TIME_LABEL_W = 100; +static constexpr uint16_t TIME_LABEL_H = 30; +static constexpr uint16_t LOCATING_LABEL_FONT = 25; +static constexpr uint16_t LOCATING_LABEL_X = 127; +static constexpr uint16_t LOCATING_LABEL_Y = 348; +static constexpr uint16_t LOCATING_LABEL_W = 200; +static constexpr uint16_t LOCATING_LABEL_H = 80; +static constexpr uint16_t WALK_BUTTON_X = 138; +static constexpr uint16_t WALK_BUTTON_Y = 136; +static constexpr uint16_t WALK_BUTTON_W = 180; +static constexpr uint16_t WALK_BUTTON_H = 180; +static constexpr uint16_t START_BUTTON_X = 196; +static constexpr uint16_t START_BUTTON_Y = 373; +static constexpr uint16_t START_BUTTON_W = 73; +static constexpr uint16_t START_BUTTON_H = 73; +static constexpr uint16_t START_BUTTON_FONT = 30; + +static PrepareView *g_pPrepareView{nullptr}; + +PrepareView::PrepareView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PrepareView::PrepareView"); + g_pPrepareView = this; +} + +PrepareView::~PrepareView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PrepareView::~PrepareView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (timeLabel != nullptr) { + delete timeLabel; + timeLabel = nullptr; + } + if (battery != nullptr) { + delete battery; + battery = nullptr; + } + if (batteryLabel != nullptr) { + delete batteryLabel; + batteryLabel = nullptr; + } + if (gpsImageView != nullptr) { + delete gpsImageView; + gpsImageView = nullptr; + } + if (gpsLabel != nullptr) { + delete gpsLabel; + gpsLabel = nullptr; + } + if (heartRateImageView != nullptr) { + delete heartRateImageView; + heartRateImageView = nullptr; + } + if (heartRateLabel != nullptr) { + delete heartRateLabel; + heartRateLabel = nullptr; + } + if (locatingLabel != nullptr) { + delete locatingLabel; + locatingLabel = nullptr; + } + if (startButton != nullptr) { + delete startButton; + startButton = nullptr; + } + if (iconImageView != nullptr) { + delete iconImageView; + iconImageView = nullptr; + } + g_pPrepareView = nullptr; +} + +PrepareView *PrepareView::GetInstance() +{ + return g_pPrepareView; +} + +bool PrepareView::InitTimeLableVIew() +{ + timeLabel = new UILabel(); + if (timeLabel == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timeLabel new fail"); + return false; + } + timeLabel->SetPosition(TIME_LABEL_X, TIME_LABEL_Y, TIME_LABEL_W, TIME_LABEL_H); + timeLabel->SetText("11:59"); + timeLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIME_LABEL_FONT); + timeLabel->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + timeLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + group->Add(timeLabel); + return true; +} + +bool PrepareView::InitLocatingLableVIew() +{ + locatingLabel = new UILabel(); + if (locatingLabel == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locatingLabel new fail"); + return false; + } + locatingLabel->SetPosition(LOCATING_LABEL_X, LOCATING_LABEL_Y, LOCATING_LABEL_W, LOCATING_LABEL_H); + locatingLabel->SetText("定位中\n请在空旷处等待"); + locatingLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LOCATING_LABEL_FONT); + locatingLabel->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + locatingLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + group->Add(locatingLabel); + return true; +} + +bool PrepareView::InitBatteryView() // 加载电量 +{ + battery = new UIImageView(); // 电量状态显示 + if (battery == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "battery new fail"); + return false; + } + battery->SetPosition(BATTERY_X, BATTERY_Y); + ScreenModels::GetInstance()->LoadAppImages(DROPDOWN_IAMGES, battery, DROPDOWN_DROPDOWN_BATTERY); + group->Add(battery); + + batteryLabel = new UILabel(); + if (batteryLabel == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryLabel new fail"); + return false; + } + batteryLabel->SetPosition(BATTERY_LABEL_X, BATTERY_LABEL_Y, BATTERY_LABEL_W, BATTERY_LABEL_H); + batteryLabel->SetText("30%"); + batteryLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BATTERY_LABEL_FONT); + batteryLabel->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT); + group->Add(batteryLabel); + return true; +} + +bool PrepareView::InitCenterView() +{ + iconImageView = new UIButton(); // 步行状态显示 + if (iconImageView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "iconImageView new fail"); + return false; + } + + iconImageView->SetPosition(WALK_BUTTON_X, WALK_BUTTON_Y, WALK_BUTTON_W, WALK_BUTTON_H); + + group->Add(iconImageView); + return true; +} + +bool PrepareView::InitGPSView() +{ + // Add ImageView to App + if (gpsImageView == nullptr) { + gpsImageView = new UIImageView(); + } + gpsImageView->SetPosition(GPS_X, GPS_Y); + gpsImageView->Resize(GPS_W, GPS_H); + + // Set additional property + + // Add to rootView + group->Add(gpsImageView); + + // Add Label to App + if (gpsLabel == nullptr) { + gpsLabel = new UILabel(); + } + gpsLabel->SetPosition(GPS_LABEL_X, GPS_LABEL_Y); + gpsLabel->Resize(GPS_LABEL_W, GPS_LABEL_H); + + // Set additional property + gpsLabel->SetText("GPS"); + gpsLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + gpsLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + gpsLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, GPS_LABEL_FONT); + + // Add to rootView + group->Add(gpsLabel); + return true; +} + +bool PrepareView::InitHeartrateView() +{ + // Add ImageView to App + if (heartRateImageView == nullptr) { + heartRateImageView = new UIImageView(); + } + heartRateImageView->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y); + heartRateImageView->Resize(HEARTBEAT_IMAGE_W, HEARTBEAT_IMAGE_H); + + // Add to rootView + group->Add(heartRateImageView); + + heartRateLabel = new UILabel(); + if (heartRateLabel == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartRateLabel new fail"); + return false; + } + heartRateLabel->SetPosition(HEARTBEAT_LABEL_X, HEARTBEAT_LABEL_Y, HEARTBEAT_LABEL_W, HEARTBEAT_LABEL_H); + heartRateLabel->SetText("95"); + heartRateLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, HEARTBEAT_LABEL_FONT); + heartRateLabel->SetStyle(STYLE_BACKGROUND_COLOR, OPA_OPAQUE); + group->Add(heartRateLabel); + return true; +} + +bool PrepareView::InitStartButtonView() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return false; + } + + // Add LabelButtonExt to App + if (startButton == nullptr) { + startButton = new UILabelButton(); + } + startButton->SetPosition(START_BUTTON_X, START_BUTTON_Y); // widget's left position and top position + startButton->Resize(START_BUTTON_W, START_BUTTON_H); // widget's width and height + startButton->SetViewId(TRAINING_PREPARE_START_BUTTON); // Set style + startButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffff1500); + + // Set additional property + startButton->SetText("开始"); + startButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, START_BUTTON_FONT); + startButton->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED); + startButton->SetOnClickListener(clickListener); + + // Add to rootView + group->Add(startButton); + return true; +} + +UIViewGroup *PrepareView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PrepareView init"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + InitTimeLableVIew(); + InitBatteryView(); + // InitLocatingLableVIew(); + InitCenterView(); + InitGPSView(); + InitHeartrateView(); + InitStartButtonView(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(PREPARE_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} + +void PrepareView::UpdateViewByTrainingType(uint8_t trainingType) +{ + if (trainingType == TRAINING_TYPE_OUTDOOR_RUNNING) { + gpsImageView->SetVisible(true); + gpsLabel->SetVisible(true); + iconImageView->SetImageSrc(PNG_WALK_IMAGE, PNG_WALK_IMAGE); + } else if (trainingType == TRAINING_TYPE_INDOOR_RUNNING) { + gpsImageView->SetVisible(false); + gpsLabel->SetVisible(false); + iconImageView->SetImageSrc(PNG_WALK_IMAGE, PNG_WALK_IMAGE); + } else if (trainingType == TRAINING_TYPE_CYCLING) { + gpsImageView->SetVisible(true); + gpsLabel->SetVisible(true); + iconImageView->SetImageSrc(PNG_WALK_IMAGE, PNG_WALK_IMAGE); + } else if (trainingType == TRAINING_TYPE_CLIMBING) { + gpsImageView->SetVisible(true); + gpsLabel->SetVisible(true); + iconImageView->SetImageSrc(PNG_WALK_IMAGE, PNG_WALK_IMAGE); + } else if (trainingType == TRAINING_TYPE_INDOOR_SWIMMING) { + gpsImageView->SetVisible(false); + gpsLabel->SetVisible(false); + iconImageView->SetImageSrc(PNG_WALK_IMAGE, PNG_WALK_IMAGE); + } else if (trainingType == TRAINING_TYPE_OUTDOOR_SWIMMING) { + gpsImageView->SetVisible(true); + gpsLabel->SetVisible(true); + iconImageView->SetImageSrc(PNG_WALK_IMAGE, PNG_WALK_IMAGE); + } + iconImageView->Invalidate(); + gpsImageView->Invalidate(); + gpsLabel->Invalidate(); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/PromptView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/PromptView.cpp new file mode 100644 index 000000000..581a2c555 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/PromptView.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Prompt View + * Create: 2025-03-22 + */ +#include "training/PromptView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t LABELS_X = 65; +static constexpr uint16_t LABELS_Y = 100; +static constexpr uint16_t LABELS_W = 324; +static constexpr uint16_t LABELS_H = 160; +static constexpr uint16_t LABELS_FONT = 35; +static constexpr uint16_t BUTTON_X1 = 85; +static constexpr uint16_t BUTTON_X2 = 279; +static constexpr uint16_t BUTTON_Y = 320; +static constexpr uint16_t BUTTON_W = 90; +static constexpr uint16_t BUTTON_H = 90; +static const char *PROMPT_CONTENT = "本次运动距离过短,不会记录数据。是否结束?"; +static PromptView *g_pPromptView{nullptr}; + +PromptView::PromptView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PromptView::PromptView"); + g_pPromptView = this; +} + +PromptView::~PromptView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PromptView::~PromptView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (titleLabel != nullptr) { + delete titleLabel; + titleLabel = nullptr; + } + if (cancelButton != nullptr) { + delete cancelButton; + cancelButton = nullptr; + } + if (confirmButton != nullptr) { + delete confirmButton; + confirmButton = nullptr; + } + g_pPromptView = nullptr; +} + +PromptView *PromptView::GetInstance() +{ + return g_pPromptView; +} + +void PromptView::CreateUILabel() +{ + if (titleLabel == nullptr) { + titleLabel = new UILabel(); + if (titleLabel == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PromptView titleLabel new fail"); + return; + } + titleLabel->SetPosition(LABELS_X, LABELS_Y, LABELS_W, LABELS_H); + titleLabel->SetText(PROMPT_CONTENT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABELS_FONT); + titleLabel->SetStyle(STYLE_BACKGROUND_COLOR, OPA_OPAQUE); + titleLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + group->Add(titleLabel); + } +} + +void PromptView::CreateUIButton() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return; + } + + if (cancelButton == nullptr) { + cancelButton = new UIButton(); + if (cancelButton == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PromptView cancelButton new fail"); + return; + } + cancelButton->SetPosition(BUTTON_X1, BUTTON_Y, BUTTON_W, BUTTON_H); + cancelButton->SetViewId(TRAINING_PROMPT_CANCEL_BUTTON); + cancelButton->SetImageSrc(ALARM_DELETE_ADD_PATH, ALARM_DELETE_ADD_PATH); + cancelButton->SetOnClickListener(clickListener); + group->Add(cancelButton); + } + if (confirmButton == nullptr) { + confirmButton = new UIButton(); + if (confirmButton == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PromptView confirmButton new fail"); + return; + } + confirmButton->SetPosition(BUTTON_X2, BUTTON_Y, BUTTON_W, BUTTON_H); + confirmButton->SetViewId(TRAINING_PROMPT_CONFIRM_BUTTON); + confirmButton->SetImageSrc(ALARM_TRUE_ADD_PATH, ALARM_TRUE_ADD_PATH); + confirmButton->SetOnClickListener(clickListener); + group->Add(confirmButton); + } +} + +UIViewGroup *PromptView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PromptView InitShowUpView"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + CreateUILabel(); + CreateUIButton(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(PROMPT_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetAdapter.cpp new file mode 100644 index 000000000..a19958b65 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetAdapter.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetAdapter + * Author: + * Create: 2025-11-23 + */ +#include "training/TargetAdapter.h" +#include "training/TargetItemView.h" + +namespace OHOS { +TargetAdapter::TargetAdapter() {} + +TargetAdapter::~TargetAdapter() +{ + listData_.clear(); +} + +uint16_t TargetAdapter::GetCount(void) +{ + return listData_.size(); +} + +void TargetAdapter::SetData(const std::list &data) +{ + if (!listData_.empty()) { + listData_.clear(); + } + listData_ = data; +} + +UIView *TargetAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData_.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData_.size()) { + return nullptr; + } + + std::list::iterator it = listData_.begin(); + for (int i = 0; i < index; i++) { + it++; + } + TargetItem itemData = *it; + TargetItemView *item = nullptr; + if (inView == nullptr) { + item = new TargetItemView(); + } else { + item = static_cast(inView); + } + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void TargetAdapter::AddListItem(const TargetItem &item) +{ + listData_.push_back(item); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetItemView.cpp new file mode 100644 index 000000000..6814bb1b5 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetItemView.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetItemView + * Author: + * Create: 2025-02-15 + */ + +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TargetItemView.h" + +namespace OHOS { +static constexpr uint16_t ITEM_X = 0; +static constexpr uint16_t ITEM_Y = 0; +static constexpr uint16_t ITEM_W = 382; +static constexpr uint16_t ITEM_H = 100; +static constexpr uint16_t ICON_X = 0; +static constexpr uint16_t ICON_Y = 0; +static constexpr uint16_t LABEL_X = 100; +static constexpr uint16_t LABEL_Y = 0; +static constexpr uint16_t LABEL_W = 200; +static constexpr uint16_t LABEL_H = 100; +static constexpr uint16_t LABEL_FONT = 35; +static constexpr uint16_t IMAGE_W = 300; +static constexpr uint16_t IMAGE_H = 0; + +TargetItemView::TargetItemView() +{ + InitView(); +} + +TargetItemView::~TargetItemView() +{ + Remove(&sIcon); + Remove(&sLabel); + Remove(&sNextImage); +} + +bool TargetItemView::InitView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetItemView::InitView"); + SetPosition(ITEM_X, ITEM_Y, ITEM_W, ITEM_H); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + SetTouchable(true); + + sIcon.SetPosition(ICON_X, ICON_Y); + sIcon.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + sLabel.SetPosition(LABEL_X, LABEL_Y); + sLabel.Resize(LABEL_W, LABEL_H); + sLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_FONT); + sLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + sLabel.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sNextImage.SetSrc(PNG_SETTING_NEXT_IMAGE); + sNextImage.SetPosition(IMAGE_W, IMAGE_H); + sNextImage.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + Add(&sIcon); + Add(&sLabel); + Add(&sNextImage); + return true; +} + +void TargetItemView::SetItemInfo(const TargetItem itemInfo) +{ + sItemInfo = itemInfo; + sIcon.SetSrc(itemInfo.icon); + sLabel.SetText(itemInfo.label); + SetViewId(itemInfo.viewId); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetSettingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetSettingView.cpp new file mode 100644 index 000000000..1e2eee87c --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetSettingView.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TargetSetting View + * Create: 2025-03-22 + */ +#include "training/TargetSettingView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t LABELS_X = 153; +static constexpr uint16_t LABELS_Y = 30; +static constexpr uint16_t LABELS_W = 200; +static constexpr uint16_t LABELS_H = 50; +static constexpr uint16_t LABELS_FONT = 40; +static constexpr uint16_t PICKER_X = 160; +static constexpr uint16_t PICKER_Y = 85; +static constexpr uint16_t PICKER_W = 199; +static constexpr uint16_t PICKER_H = 241; +static constexpr uint16_t PICKER_ITEM_H = 50; +static constexpr uint16_t BUTTON_X = 87; +static constexpr uint16_t BUTTON_Y = 351; +static constexpr uint16_t BUTTON_W = 279; +static constexpr uint16_t BUTTON_H = 116; +static constexpr uint16_t BUTTON_FONT = 40; +static constexpr uint8_t BACKGROUND_FONT = 40; +static constexpr uint8_t HIGHTLIGHT_FONT = 50; + +static TargetSettingView *g_pTargetSettingView{nullptr}; + +TargetSettingView::TargetSettingView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetSettingView::TargetSettingView"); + g_pTargetSettingView = this; +} + +TargetSettingView::~TargetSettingView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetSettingView::~TargetSettingView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (titleLabel != nullptr) { + delete titleLabel; + titleLabel = nullptr; + } + if (picker != nullptr) { + delete picker; + picker = nullptr; + } + if (confirmButton != nullptr) { + delete confirmButton; + confirmButton = nullptr; + } + g_pTargetSettingView = nullptr; +} + +TargetSettingView *TargetSettingView::GetInstance() +{ + return g_pTargetSettingView; +} + +void TargetSettingView::CreateUILabel() +{ + // Add Label to App + if (titleLabel == nullptr) { + titleLabel = new UILabel(); + } + titleLabel->SetPosition(LABELS_X, LABELS_Y); + titleLabel->Resize(LABELS_W, LABELS_H); + titleLabel->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + // Set additional property + titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + titleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABELS_FONT); + + // Add to rootView + group->Add(titleLabel); +} + +void TargetSettingView::CreateUIPicker() +{ + // Add Picker to App + if (picker == nullptr) { + picker = new UIPicker(); + } + picker->SetPosition(PICKER_X, PICKER_Y); + picker->Resize(PICKER_W, PICKER_H); + picker->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + // Set additional property + picker->SetItemHeight(PICKER_ITEM_H); + + picker->SetBackgroundFont(DEFAULT_VECTOR_FONT_FILENAME, BACKGROUND_FONT); + picker->SetHighlightFont(DEFAULT_VECTOR_FONT_FILENAME, HIGHTLIGHT_FONT); + + // Add to rootView + group->Add(picker); +} + +void TargetSettingView::CreateUIButton() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return; + } + + // Add LabelButtonExt to App + if (confirmButton == nullptr) { + confirmButton = new UILabelButton(); + } + confirmButton->SetPosition(BUTTON_X, BUTTON_Y); + confirmButton->Resize(BUTTON_W, BUTTON_H); + confirmButton->SetViewId(TARGET_SETTING_CONFIRM_BUTTON); + confirmButton->SetTouchable(true); + + // Set additional property + confirmButton->SetText("确定"); + confirmButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_FONT); + + confirmButton->SetOnClickListener(clickListener); + + // Add to rootView + group->Add(confirmButton); +} + +UIViewGroup *TargetSettingView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetSettingView InitShowUpView"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + CreateUILabel(); + CreateUIPicker(); + CreateUIButton(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(TARGET_SETTING_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} + +void TargetSettingView::UpdateViewByTargetType(uint8_t targetType) +{ + if (targetType == TRAINING_TARGET_DISTANCE) { + titleLabel->SetText("距离"); + const char *uiDistanceData[] = {"1km", "3km", "5km", "10km"}; + picker->SetValues(uiDistanceData, sizeof(uiDistanceData) / sizeof(uiDistanceData[0])); + picker->SetTextColor(Color::Gray(), Color::Teal()); + confirmButton->SetStyle(STYLE_BACKGROUND_COLOR, Color::Teal().full); + } else if (targetType == TRAINING_TARGET_TIME) { + titleLabel->SetText("时间"); + const char *uiTimeData[] = {"10分钟", "20分钟", "30分钟", "60分钟"}; + picker->SetValues(uiTimeData, sizeof(uiTimeData) / sizeof(uiTimeData[0])); + picker->SetTextColor(Color::Gray(), Color::Orange()); + confirmButton->SetStyle(STYLE_BACKGROUND_COLOR, Color::Orange().full); + } else if (targetType == TRAINING_TARGET_CALORIE) { + titleLabel->SetText("热量"); + const char *uiCalorieData[] = {"100千卡", "200千卡", "300千卡", "500千卡", "1000千卡"}; + picker->SetValues(uiCalorieData, sizeof(uiCalorieData) / sizeof(uiCalorieData[0])); + picker->SetTextColor(Color::Gray(), Color::Magenta()); + confirmButton->SetStyle(STYLE_BACKGROUND_COLOR, Color::Magenta().full); + } + titleLabel->Invalidate(); + picker->Invalidate(); + confirmButton->Invalidate(); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetView.cpp new file mode 100644 index 000000000..46d55c0d8 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TargetView.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: Target View + * Create: 2025-03-22 + */ +#include "training/TargetView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t LABELS_X = 133; +static constexpr uint16_t LABELS_Y = 36; +static constexpr uint16_t LABELS_W = 200; +static constexpr uint16_t LABELS_H = 60; +static constexpr uint16_t LABELS_FONT = 50; +static constexpr uint16_t LIST_X = 42; +static constexpr uint16_t LIST_Y = 95; +static constexpr uint16_t LIST_W = 382; +static constexpr uint16_t LIST_H = 305; + +static TargetView *g_pTargetView{nullptr}; + +TargetView::TargetView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetView::TargetView"); + g_pTargetView = this; +} + +TargetView::~TargetView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetView::~TargetView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (titleLabel != nullptr) { + delete titleLabel; + titleLabel = nullptr; + } + if (targetList != nullptr) { + delete targetList; + targetList = nullptr; + } + if (listAdapter_ != nullptr) { + delete listAdapter_; + listAdapter_ = nullptr; + } + g_pTargetView = nullptr; +} + +TargetView *TargetView::GetInstance() +{ + return g_pTargetView; +} + +void TargetView::CreateUILabel() +{ + // Add Label to App + if (titleLabel == nullptr) { + titleLabel = new UILabel(); + } + titleLabel->SetPosition(LABELS_X, LABELS_Y); + titleLabel->Resize(LABELS_W, LABELS_H); + + // Set additional property + titleLabel->SetText("目标"); + titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + titleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABELS_FONT); + + // Add to rootView + group->Add(titleLabel); +} + +void TargetView::CreateUIList() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return; + } + + // Add List to App + if (targetList == nullptr) { + targetList = new UIList(); + } + targetList->SetPosition(LIST_X, LIST_Y); + targetList->Resize(LIST_W, LIST_H); + targetList->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000); + + // Set additional property + if (listAdapter_ == nullptr) { + listAdapter_ = new TargetAdapter(); + } + listAdapter_->SetItemClickListener(clickListener); + std::list targetItemList(targets, targets + TRAINING_TARGET_MAX); + listAdapter_->SetData(targetItemList); + + targetList->SetAdapter(listAdapter_); + targetList->RefreshList(); + + // Add to rootView + group->Add(targetList); +} + +UIViewGroup *TargetView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TargetView InitShowUpView"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + CreateUILabel(); + CreateUIList(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(TARGET_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingAdapter.cpp new file mode 100644 index 000000000..9ae2d4c94 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingAdapter.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingAdapter.cpp + * Author: + * Create: 2025-11-23 + */ +#include "training/TrainingAdapter.h" +#include "training/TrainingItemView.h" + +namespace OHOS { +TrainingAdapter::TrainingAdapter() {} + +TrainingAdapter::~TrainingAdapter() +{ + listData_.clear(); +} + +uint16_t TrainingAdapter::GetCount(void) +{ + return listData_.size(); +} + +void TrainingAdapter::SetData(const std::list &data) +{ + if (!listData_.empty()) { + listData_.clear(); + } + listData_ = data; +} + +UIView *TrainingAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData_.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData_.size()) { + return nullptr; + } + + std::list::iterator it = listData_.begin(); + for (int i = 0; i < index; i++) { + it++; + } + TrainingItem itemData = *it; + TrainingItemView *item = nullptr; + if (inView == nullptr) { + item = new TrainingItemView(); + } else { + item = static_cast(inView); + } + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void TrainingAdapter::AddListItem(const TrainingItem &item) +{ + listData_.push_back(item); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingItemView.cpp new file mode 100644 index 000000000..ff03e79b8 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingItemView.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: temperature + * Author: + * Create: 2025-02-15 + */ + +#include "wearable_log.h" +#include "UiConfig.h" +#include "ui_resource_image.h" +#include "training/TrainingItemView.h" +#include "screensetting/ScreenModels.h" + +namespace OHOS { +static constexpr uint16_t ITEM_X = 0; +static constexpr uint16_t ITEM_Y = 0; +static constexpr uint16_t ITEM_W = 382; +static constexpr uint16_t ITEM_H = 100; +static constexpr uint16_t ICON_X = 0; +static constexpr uint16_t ICON_Y = 0; +static constexpr uint16_t LABEL_X = 100; +static constexpr uint16_t LABEL_Y = 0; +static constexpr uint16_t LABEL_W = 200; +static constexpr uint16_t LABEL_H = 100; +static constexpr uint16_t LABEL_FONT = 35; +static constexpr uint16_t IMAGE_W = 300; +static constexpr uint16_t IMAGE_H = 0; + +TrainingItemView::TrainingItemView() +{ + InitView(); +} + +TrainingItemView::~TrainingItemView() +{ + Remove(&sIcon); + Remove(&sLabel); + Remove(&sSettingImage); +} + +bool TrainingItemView::InitView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingItemView::InitView"); + SetPosition(ITEM_X, ITEM_Y, ITEM_W, ITEM_H); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + SetTouchable(true); + + sIcon.SetPosition(ICON_X, ICON_Y); + sIcon.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + sLabel.SetPosition(LABEL_X, LABEL_Y); + sLabel.Resize(LABEL_W, LABEL_H); + sLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_FONT); + sLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + sLabel.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + ScreenModels::GetInstance()->LoadAppImages(DROPDOWN_IAMGES, &sSettingImage, DROPDOWN_DROPDOWN_SETTING); + sSettingImage.SetPosition(IMAGE_W, IMAGE_H); + sSettingImage.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + Add(&sIcon); + Add(&sLabel); + Add(&sSettingImage); + return true; +} + +void TrainingItemView::SetItemInfo(const TrainingItem itemInfo) +{ + sItemInfo = itemInfo; + sIcon.SetSrc(itemInfo.icon); + sLabel.SetText(itemInfo.label); + SetViewId(itemInfo.viewId); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingModel.cpp new file mode 100644 index 000000000..9efb70247 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingModel.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingModel.cpp + * Author: + * Create: 2025-11-23 + */ + +#include "training/TrainingModel.h" + +namespace OHOS { +TrainingModel::TrainingModel() {} + +TrainingModel::~TrainingModel() {} + +TrainingModel &TrainingModel::GetInstance() +{ + static TrainingModel instance; + return instance; +} + +void TrainingModel::SetCurView(int16_t viewNum) +{ + curView_ = viewNum; +} + +int16_t TrainingModel::GetCurView(void) +{ + return curView_; +} + +void TrainingModel::SetCurTrainingType(int8_t trainingType) +{ + trainingType_ = trainingType; +} + +int8_t TrainingModel::GetCurTrainingType(void) +{ + return trainingType_; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingPresenter.cpp new file mode 100644 index 000000000..5c34aa19f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingPresenter.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: SettingPresenter.cpp + * Author: + * Create: 2025-11-23 + */ + +#include "training/TrainingModel.h" +#include "training/TrainingPresenter.h" +#include "NativeRegisterManager.h" +namespace OHOS { + +REGIST_MENU(VIEW_TRAINING, TrainingView, TrainingPresenter, PNG_APPLIST_WALK_IMAGE, PNG_APPLIST_DEFAULT_IMG, + "体能训练"); + +static TrainingPresenter *g_trainingPresenter = nullptr; +TrainingPresenter::TrainingPresenter() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::TrainingPresenter"); + trainingModel_ = &TrainingModel::GetInstance(); + g_trainingPresenter = this; +} + +TrainingPresenter::~TrainingPresenter() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::~TrainingPresenter"); + g_trainingPresenter = nullptr; +} + +TrainingPresenter *TrainingPresenter::GetInstance(void) +{ + return g_trainingPresenter; +} + +void TrainingPresenter::OnResume(void) +{ + Presenter::OnResume(); +} + +void TrainingPresenter::OnPause(void) +{ + Presenter::OnPause(); + return; +} + +void TrainingPresenter::ClickStartButton(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick ClickStartButton"); + view_->ChangeView(TRAINING_VIEW_PREPARE, TRAINING_VIEW_DATA); + DataView::GetInstance()->UpdateDataViewByType(); +} + +void TrainingPresenter::ClickCountineButton(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick ClickCountineButton"); + view_->ChangeView(TRAINING_VIEW_PAUSE, TRAINING_VIEW_DATA); + DataView::GetInstance()->UpdateDataViewByType(); +} + +void TrainingPresenter::ClickFinishButton(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick ClickFinishButton"); + view_->ChangeView(TRAINING_VIEW_PAUSE, TRAINING_VIEW_PROMPT); +} + +void TrainingPresenter::ClickCancelButton(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick ClickCancelButton"); + view_->ChangeView(TRAINING_VIEW_PROMPT, TRAINING_VIEW_PAUSE); +} + +void TrainingPresenter::ClickConfirmButton(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick ClickConfirmButton"); + view_->ChangeView(TRAINING_VIEW_PROMPT, TRAINING_VIEW_MENU); +} + +void TrainingPresenter::TrainingSetting(uint8_t trainingType) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick TrainingSetting, type = %d", trainingType); + view_->ChangeView(TRAINING_VIEW_MENU, TRAINING_VIEW_SETTING); +} + +void TrainingPresenter::StartTraining(uint8_t trainingType) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick TrainingSetting, type = %d", trainingType); + view_->ChangeView(TRAINING_VIEW_MENU, TRAINING_VIEW_PREPARE); + trainingModel_->SetCurTrainingType(trainingType); + PrepareView::GetInstance()->UpdateViewByTrainingType(trainingType); +} + +void TrainingPresenter::EnterTarget(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick EnterTarget"); + view_->ChangeView(TRAINING_VIEW_SETTING, TRAINING_VIEW_TARGET); +} + +void TrainingPresenter::SettingTarget(uint8_t targetType) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick SettingTarget, type = %d", targetType); + view_->ChangeView(TRAINING_VIEW_TARGET, TRAINING_VIEW_TARGET_SETTING); + TargetSettingView::GetInstance()->UpdateViewByTargetType(targetType); +} + +void TrainingPresenter::ConfirmTargetSetting(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresenter::OnClick ConfirmTargetSetting"); + view_->ChangeView(TRAINING_VIEW_TARGET_SETTING, TRAINING_VIEW_SETTING); +} + +bool TrainingPresenter::OnClick(UIView &view, const ClickEvent &event) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingPresent::OnClick view:%s", view.GetViewId()); + bool isSettingClicked = event.GetCurrentPos().x > 350 ? true : false; + if (strcmp(view.GetViewId(), TRAINING_PREPARE_START_BUTTON) == 0) { + ClickStartButton(); + } else if (strcmp(view.GetViewId(), TRAINING_PAUSE_CONTINUE_BUTTON) == 0) { + ClickCountineButton(); + } else if (strcmp(view.GetViewId(), TRAINING_PAUSE_FINISH_BUTTON) == 0) { + ClickFinishButton(); + } else if (strcmp(view.GetViewId(), TRAINING_PROMPT_CANCEL_BUTTON) == 0) { + ClickCancelButton(); + } else if (strcmp(view.GetViewId(), TRAINING_PROMPT_CONFIRM_BUTTON) == 0) { + ClickConfirmButton(); + } else if (strcmp(view.GetViewId(), TRAINING_SETTING_ITEM_TARGET) == 0) { + EnterTarget(); + } else if (strcmp(view.GetViewId(), TRAINING_TARGET_ITEM_DISTANCE) == 0) { + SettingTarget(TRAINING_TARGET_DISTANCE); + } else if (strcmp(view.GetViewId(), TRAINING_TARGET_ITEM_TIME) == 0) { + SettingTarget(TRAINING_TARGET_TIME); + } else if (strcmp(view.GetViewId(), TRAINING_TARGET_ITEM_CALORIE) == 0) { + SettingTarget(TRAINING_TARGET_CALORIE); + } else if (strcmp(view.GetViewId(), TARGET_SETTING_CONFIRM_BUTTON) == 0) { + ConfirmTargetSetting(); + } else if (strcmp(view.GetViewId(), TRAINING_ITEM_OUTDOOR_RUNNING) == 0) { + if (isSettingClicked) { + TrainingSetting(TRAINING_TYPE_OUTDOOR_RUNNING); + } else { + StartTraining(TRAINING_TYPE_OUTDOOR_RUNNING); + } + } else if (strcmp(view.GetViewId(), TRAINING_ITEM_INDOOR_RUNNING) == 0) { + if (isSettingClicked) { + TrainingSetting(TRAINING_TYPE_INDOOR_RUNNING); + } else { + StartTraining(TRAINING_TYPE_INDOOR_RUNNING); + } + } else if (strcmp(view.GetViewId(), TRAINING_ITEM_CYCLING) == 0) { + if (isSettingClicked) { + TrainingSetting(TRAINING_TYPE_CYCLING); + } else { + StartTraining(TRAINING_TYPE_CYCLING); + } + } else if (strcmp(view.GetViewId(), TRAINING_ITEM_CLIMBING) == 0) { + if (isSettingClicked) { + TrainingSetting(TRAINING_TYPE_CLIMBING); + } else { + StartTraining(TRAINING_TYPE_CLIMBING); + } + } else if (strcmp(view.GetViewId(), TRAINING_ITEM_INDOOR_SWIMMING) == 0) { + if (isSettingClicked) { + TrainingSetting(TRAINING_TYPE_INDOOR_SWIMMING); + } else { + StartTraining(TRAINING_TYPE_INDOOR_SWIMMING); + } + } else if (strcmp(view.GetViewId(), TRAINING_ITEM_OUTDOOR_SWIMMING) == 0) { + if (isSettingClicked) { + TrainingSetting(TRAINING_TYPE_OUTDOOR_SWIMMING); + } else { + StartTraining(TRAINING_TYPE_OUTDOOR_SWIMMING); + } + } + return true; +} + +bool TrainingPresenter::OnDrag(UIView &view, const DragEvent &event) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingOnDragListener::OnDrag"); + if (event.GetDragDirection() == DragEvent::DIRECTION_RIGHT_TO_LEFT) { + if (strcmp(view.GetViewId(), MENU_VIEW_ID) == 0) { + // view_->ChangeView(TRAINING_VIEW_MENU, TRAINING_VIEW_PREPARE); + } else if (strcmp(view.GetViewId(), PREPARE_VIEW_ID) == 0) { + // view_->ChangeView(TRAINING_VIEW_PREPARE, TRAINING_VIEW_DATA); + // DataView::GetInstance()->UpdateDataViewByType(); + } else if (strcmp(view.GetViewId(), DATA_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_DATA, TRAINING_VIEW_PAUSE); + } else if (strcmp(view.GetViewId(), PAUSE_VIEW_ID) == 0) { + // view_->ChangeView(TRAINING_VIEW_PAUSE, TRAINING_VIEW_PROMPT); + } else if (strcmp(view.GetViewId(), PROMPT_VIEW_ID) == 0) { + // view_->ChangeView(TRAINING_VIEW_PROMPT, TRAINING_VIEW_MENU); + } + } else if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) { + if (strcmp(view.GetViewId(), MENU_VIEW_ID) == 0) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + } else if (strcmp(view.GetViewId(), PREPARE_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_PREPARE, TRAINING_VIEW_MENU); + } else if (strcmp(view.GetViewId(), DATA_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_DATA, TRAINING_VIEW_PREPARE); + } else if (strcmp(view.GetViewId(), PAUSE_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_PAUSE, TRAINING_VIEW_DATA); + } else if (strcmp(view.GetViewId(), PROMPT_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_PROMPT, TRAINING_VIEW_PAUSE); + } else if (strcmp(view.GetViewId(), SETTING_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_SETTING, TRAINING_VIEW_MENU); + } else if (strcmp(view.GetViewId(), TARGET_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_TARGET, TRAINING_VIEW_SETTING); + } else if (strcmp(view.GetViewId(), TARGET_SETTING_VIEW_ID) == 0) { + view_->ChangeView(TRAINING_VIEW_TARGET_SETTING, TRAINING_VIEW_TARGET); + } + } + return false; +} + +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingAdapter.cpp new file mode 100644 index 000000000..f7fa89945 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingAdapter.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingSettingAdapter.cpp + * Author: + * Create: 2025-11-23 + */ +#include "training/TrainingSettingAdapter.h" +#include "training/TrainingSettingItemView.h" + +namespace OHOS { +TrainingSettingAdapter::TrainingSettingAdapter() {} + +TrainingSettingAdapter::~TrainingSettingAdapter() +{ + listData_.clear(); +} + +uint16_t TrainingSettingAdapter::GetCount(void) +{ + return listData_.size(); +} + +void TrainingSettingAdapter::SetData(const std::list &data) +{ + if (!listData_.empty()) { + listData_.clear(); + } + listData_ = data; +} + +UIView *TrainingSettingAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData_.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData_.size()) { + return nullptr; + } + + std::list::iterator it = listData_.begin(); + for (int i = 0; i < index; i++) { + it++; + } + TrainingSettingItem itemData = *it; + TrainingSettingItemView *item = nullptr; + if (inView == nullptr) { + item = new TrainingSettingItemView(); + } else { + item = static_cast(inView); + } + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void TrainingSettingAdapter::AddListItem(const TrainingSettingItem &item) +{ + listData_.push_back(item); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingItemView.cpp new file mode 100644 index 000000000..4d135b462 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingItemView.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingSettingItemView.cpp + * Author: + * Create: 2025-02-15 + */ + +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingSettingItemView.h" + +namespace OHOS { +static constexpr uint16_t ITEM_X = 0; +static constexpr uint16_t ITEM_Y = 0; +static constexpr uint16_t ITEM_W = 382; +static constexpr uint16_t ITEM_H = 100; +static constexpr uint16_t ICON_X = 0; +static constexpr uint16_t ICON_Y = 0; +static constexpr uint16_t LABEL_X = 100; +static constexpr uint16_t LABEL_Y = 0; +static constexpr uint16_t LABEL_W = 200; +static constexpr uint16_t LABEL_H = 100; +static constexpr uint16_t LABEL_FONT = 35; +static constexpr uint16_t IMAGE_W = 300; +static constexpr uint16_t IMAGE_H = 0; + +TrainingSettingItemView::TrainingSettingItemView() +{ + InitView(); +} + +TrainingSettingItemView::~TrainingSettingItemView() +{ + Remove(&sIcon); + Remove(&sLabel); + Remove(&sNextImage); +} + +bool TrainingSettingItemView::InitView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingSettingItemView::InitView"); + SetPosition(ITEM_X, ITEM_Y, ITEM_W, ITEM_H); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + SetTouchable(true); + + sIcon.SetPosition(ICON_X, ICON_Y); + sIcon.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + + sLabel.SetPosition(LABEL_X, LABEL_Y); + sLabel.Resize(LABEL_W, LABEL_H); + sLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_FONT); + sLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + sLabel.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sNextImage.SetSrc(PNG_SETTING_NEXT_IMAGE); + sNextImage.SetPosition(IMAGE_W, IMAGE_H); + sNextImage.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + Add(&sIcon); + Add(&sLabel); + Add(&sNextImage); + return true; +} + +void TrainingSettingItemView::SetItemInfo(const TrainingSettingItem itemInfo) +{ + sItemInfo = itemInfo; + sIcon.SetSrc(itemInfo.icon); + sLabel.SetText(itemInfo.label); + SetViewId(itemInfo.viewId); +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingView.cpp new file mode 100644 index 000000000..04d868651 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingSettingView.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingSettingView + * Create: 2025-03-22 + */ +#include "training/TrainingSettingView.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "training/TrainingPresenter.h" + +namespace OHOS { +static constexpr uint16_t LABELS_X = 133; +static constexpr uint16_t LABELS_Y = 36; +static constexpr uint16_t LABELS_W = 200; +static constexpr uint16_t LABELS_H = 60; +static constexpr uint16_t LABELS_FONT = 50; +static constexpr uint16_t LIST_X = 42; +static constexpr uint16_t LIST_Y = 95; +static constexpr uint16_t LIST_W = 382; +static constexpr uint16_t LIST_H = 305; + +static TrainingSettingView *g_pSettingView{nullptr}; + +TrainingSettingView::TrainingSettingView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingSettingView::TrainingSettingView"); + g_pSettingView = this; +} + +TrainingSettingView::~TrainingSettingView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingSettingView::~TrainingSettingView"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (titleLabel != nullptr) { + delete titleLabel; + titleLabel = nullptr; + } + if (settingList != nullptr) { + delete settingList; + settingList = nullptr; + } + if (listAdapter_ != nullptr) { + delete listAdapter_; + listAdapter_ = nullptr; + } + g_pSettingView = nullptr; +} + +TrainingSettingView *TrainingSettingView::GetInstance() +{ + return g_pSettingView; +} + +void TrainingSettingView::CreateUILabel() +{ + // Add Label to App + if (titleLabel == nullptr) { + titleLabel = new UILabel(); + } + titleLabel->SetPosition(LABELS_X, LABELS_Y); + titleLabel->Resize(LABELS_W, LABELS_H); + + // Set additional property + titleLabel->SetText("设置"); + titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + titleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABELS_FONT); + + // Add to rootView + group->Add(titleLabel); +} + +void TrainingSettingView::CreateUIList() +{ + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::TrainingPresenter::GetInstance(); + if (clickListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener nullptr"); + return; + } + + // Add List to App + if (settingList == nullptr) { + settingList = new UIList(); + } + settingList->SetPosition(LIST_X, LIST_Y); + settingList->Resize(LIST_W, LIST_H); + settingList->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000); + + // Set additional property + if (listAdapter_ == nullptr) { + listAdapter_ = new TrainingSettingAdapter(); + } + listAdapter_->SetItemClickListener(clickListener); + std::list trainingSettingItemList(settings, settings + TRAINING_SETTING_MAX); + listAdapter_->SetData(trainingSettingItemList); + + settingList->SetAdapter(listAdapter_); + settingList->RefreshList(); + + // Add to rootView + group->Add(settingList); +} + +UIViewGroup *TrainingSettingView::InitShowUpView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingSettingView InitShowUpView"); + if (group == nullptr) { + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group new fail"); + return nullptr; + } + group->SetPosition(0, 0); + group->SetWidth(HORIZONTAL_RESOLUTION); + group->SetHeight(VERTICAL_RESOLUTION); + } + CreateUILabel(); + CreateUIList(); + UIView::OnDragListener *trainingDragListener = (UIView::OnDragListener *)OHOS::TrainingPresenter::GetInstance(); + if (trainingDragListener == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "trainingDragListener GetInstance fail"); + return nullptr; + } + group->SetOnDragListener(trainingDragListener); + group->SetViewId(SETTING_VIEW_ID); + group->SetDraggable(true); + group->SetTouchable(true); + return group; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingView.cpp new file mode 100644 index 000000000..0b2d1fa55 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/training/src/TrainingView.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: TrainingView.cpp + * Author: + * Create: 2025-11-23 + */ + +#include "training/TrainingView.h" +#include "training/TrainingPresenter.h" +#include "wearable_log.h" + +namespace OHOS { +static TrainingView *g_pTrainingView = nullptr; + +TrainingView::TrainingView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingView::TrainingView"); + preProcessView[TRAINING_VIEW_MENU] = &TrainingView::ChangeMenuView; + preProcessView[TRAINING_VIEW_PREPARE] = &TrainingView::ChangePrepareView; + preProcessView[TRAINING_VIEW_DATA] = &TrainingView::ChangeDataView; + preProcessView[TRAINING_VIEW_PAUSE] = &TrainingView::ChangePauseView; + preProcessView[TRAINING_VIEW_PROMPT] = &TrainingView::ChangePromptView; + preProcessView[TRAINING_VIEW_SETTING] = &TrainingView::ChangeSettingView; + preProcessView[TRAINING_VIEW_TARGET] = &TrainingView::ChangeTargetView; + preProcessView[TRAINING_VIEW_TARGET_SETTING] = &TrainingView::ChangeTargetSettingView; + g_pTrainingView = this; +} + +TrainingView::~TrainingView() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingView::~TrainingView"); + g_pTrainingView = nullptr; +} + +TrainingView *TrainingView::GetInstance() +{ + return g_pTrainingView; +} + +void TrainingView::OnStart() +{ + ChangeView(TRAINING_VIEW_MAX, TRAINING_VIEW_MENU); +} + +void TrainingView::OnStop() +{ + if (menuView != nullptr) { + delete menuView; + menuView = nullptr; + } + if (prepareView != nullptr) { + delete prepareView; + prepareView = nullptr; + } + if (dataView != nullptr) { + delete dataView; + dataView = nullptr; + } + if (pauseView != nullptr) { + delete pauseView; + pauseView = nullptr; + } + if (promptView != nullptr) { + delete promptView; + promptView = nullptr; + } + if (settingView != nullptr) { + delete settingView; + settingView = nullptr; + } + if (targetView != nullptr) { + delete targetView; + targetView = nullptr; + } + if (targetSettingView != nullptr) { + delete targetSettingView; + targetSettingView = nullptr; + } +} + +bool TrainingView::ChangeMenuView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangeMenuView"); + menuView = new MenuView(); + if (menuView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = menuView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangePrepareView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangePrepareView"); + prepareView = new PrepareView(); + if (prepareView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = prepareView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangeDataView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangeDataView"); + dataView = new DataView(); + if (dataView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = dataView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangePauseView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangePauseView"); + pauseView = new PauseView(); + if (pauseView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = pauseView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangePromptView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangePromptView"); + promptView = new PromptView(); + if (promptView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = promptView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangeSettingView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangeSettingView"); + settingView = new TrainingSettingView(); + if (settingView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = settingView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangeTargetView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangeTargetView"); + targetView = new TargetView(); + if (targetView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = targetView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::ChangeTargetSettingView(int16_t hideView, int16_t thisView) +{ + UNUSED(hideView); + if (container[thisView] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChangeTargetSettingView"); + targetSettingView = new TargetSettingView(); + if (targetSettingView == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView new fail"); + return false; + } + // init view + UIViewGroup *group = targetSettingView->InitShowUpView(); + if (group == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "group nullptr fail"); + return false; + } + container[thisView] = group; + AddViewToRootContainer(container[thisView]); + } + return true; +} + +bool TrainingView::CheckViewParam(int16_t hideView, int16_t showView) +{ + if (showView < 0 || showView >= TRAINING_VIEW_MAX) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView::CheckViewParam showView err."); + return false; + } + + if (hideView < 0 || hideView > TRAINING_VIEW_MAX) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView::CheckViewParam hideView err."); + return false; + } + + return true; +} + +void TrainingView::ChangeView(int16_t hideView, int16_t showView) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingView::ChangeView %d, %d", hideView, showView); + + if (!CheckViewParam(hideView, showView)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView::CheckViewParam failed."); + return; + } + + PreprosssChangeView tmpPreProcessView = preProcessView[showView]; + + if (!(this->*tmpPreProcessView)(hideView, showView)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrainingView::ChangeView %d %dfailed", showView, hideView); + return; + } + if (hideView != TRAINING_VIEW_MAX) { + if (container[hideView] == nullptr) { + return; + } + container[hideView]->SetVisible(false); + } + container[showView]->SetVisible(true); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TrainingView:: ChangeView end!!!%d", showView); + Draw(); +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleModel.cpp index 433648409..68a75729e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleModel.cpp @@ -5,7 +5,7 @@ * Create: 2021-11-23 */ -#include "UISampleModel.h" +#include "uisample/UISampleModel.h" namespace OHOS { UISampleModel::UISampleModel() {} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISamplePresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISamplePresenter.cpp index ff790b626..7d42911b9 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISamplePresenter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISamplePresenter.cpp @@ -5,10 +5,10 @@ * Create: 2021-11-23 */ -#include "UISampleView.h" -#include "UISampleModel.h" -#include "UISamplePresenter.h" -#include "ui_service.h" +#include "uisample/UISampleView.h" +#include "uisample/UISampleModel.h" +#include "uisample/UISamplePresenter.h" +#include "uiservice/ui_service.h" #include "NativeRegisterManager.h" namespace OHOS { @@ -25,13 +25,11 @@ REGIST_MENU(VIEW_UISAMPLE, UISampleView, UISamplePresenter, PNG_APPLIST_UI_SAMPL void UISamplePresenter::OnResume(void) { - Presenter::OnResume(); SendMsgToUIService(UI_ADD_SLEEP_VETO, 0, nullptr, 0); } void UISamplePresenter::OnPause(void) { - Presenter::OnPause(); SendMsgToUIService(UI_RM_SLEEP_VETO, 0, nullptr, 0); return; } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleView.cpp index d2d7777ed..4dbb8092e 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleView.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/uisample/src/UISampleView.cpp @@ -7,8 +7,8 @@ #include -#include "UISampleView.h" -#include "UISamplePresenter.h" +#include "uisample/UISampleView.h" +#include "uisample/UISamplePresenter.h" #include "ui_test_group.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/test_case_list_adapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/test_case_list_adapter.cpp index d2161b62d..4f652b307 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/test_case_list_adapter.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/test_case_list_adapter.cpp @@ -19,7 +19,7 @@ #include "components/ui_label_button.h" #include "gfx_utils/list.h" #include "ui_test.h" -#include "UISampleView.h" +#include "uisample/UISampleView.h" #include "ui_test_group.h" #include "wearable_log.h" diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/ui_test_group.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/ui_test_group.cpp index e47e34e38..c2188a499 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/ui_test_group.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/uisample/uitest/framework/src/ui_test_group.cpp @@ -40,6 +40,7 @@ #include "ui_test_sphere_view/ui_test_sphere_view.h" #include "ui_test_nested/ui_test_nested.h" #include "ui_test_particle/ui_test_particle.h" +#include "ui_test_lottie/ui_test_lottie.h" namespace OHOS { void UITestGroup::AddTestCase(TestCaseInfo testCaseInfo) { @@ -81,6 +82,7 @@ void UITestGroup::SetUpTestCase() testCaseList_->PushBack(TestCaseInfo{"足球效果", new UITestIcosahedron()}); testCaseList_->PushBack(TestCaseInfo{"滑动冲突", new UITestNested()}); testCaseList_->PushBack(TestCaseInfo{"粒子效果", new UITestParticle()}); + testCaseList_->PushBack(TestCaseInfo{"Lottie", new UITestLottie()}); } List& UITestGroup::GetTestCase() diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_language.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_language.cpp new file mode 100644 index 000000000..60adfc133 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_language.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#include "uiservice/ui_language.h" +#include "ui_resource_string.h" +#include "font/font_global_manager.h" +#include "nv.h" +#include "wearable_log.h" + +#include "nv_config/include/key_id.h" +#include "nv_config/include/common.h" +#include "nv.h" + +namespace OHOS { +static constexpr const char *BIN_LANG_EN = "/music/font/en.lang"; +static constexpr const char *BIN_LANG_ZH = "/music/font/zh.lang"; + +const char* UILanguage::GetText(uint16_t textId) +{ + if (RegisterGlobalManager()) { + return FontGlobalManager::GetInstance()->GetText(textId); + } + return nullptr; +} +void UILanguage::SetLanguage(uint8_t id) +{ + sys_language_id_t lang_id = {.language_id = id}; + + errcode_t ret = uapi_nv_write(NV_ID_SYS_LANGUAGE_ID, (uint8_t*)&lang_id, sizeof(sys_language_id_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "nv set language id error, ret=%u", ret); + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "set language id = %u", lang_id.language_id); + UpdateLanguage(); +} +void UILanguage::UpdateLanguage() +{ + sys_language_id_t lang_id = {0}; + uint16_t nvsize = 0; + + errcode_t ret = uapi_nv_read(NV_ID_SYS_LANGUAGE_ID, sizeof(sys_language_id_t), &nvsize, (uint8_t*)&lang_id); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "nv get language id error, ret=%u", ret); + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "language nvsize=%u id = %u", nvsize, lang_id.language_id); + if (RegisterGlobalManager()) { + if (lang_id.language_id<0 || lang_id.language_id > OHOS::LANGUAGE_ID_MAX) { + lang_id.language_id = OHOS::LANGUAGE_ID_ZH; + } + FontGlobalManager::GetInstance()->SetCurrentLangId(lang_id.language_id); + } +} +bool UILanguage::RegisterGlobalManager() +{ + static bool isRegister = false; + if (!isRegister) { + const char *resFiles[] = {BIN_LANG_ZH, BIN_LANG_EN}; + if (!FontGlobalManager::GetInstance()->RegisterLanguageInfo( + resFiles, OHOS::LANGUAGE_ID_MAX, OHOS::LANGUAGE_ID_ZH)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "register global manager error"); + return isRegister; + } + isRegister = true; + } + return isRegister; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_service.cpp b/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_service.cpp index 955c25d2f..ef81ce75d 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_service.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/uiservice/src/ui_service.cpp @@ -13,28 +13,33 @@ * limitations under the License. */ -#include "ui_service.h" +#include "uiservice/ui_service.h" #include "wearable_log.h" #include "samgr_lite.h" -#include "SettingModel.h" -#include "UiServersMsg.h" +#include "settings/SettingModel.h" +#include "main/UiServersMsg.h" #include "ohos_init.h" #include "memory_adapter.h" #include #include "service_id_define.h" #include "bundle_install_msg.h" #include "graphic_service.h" -#include "ApplistModel.h" +#include "applist/ApplistModel.h" #if defined(SUPPORT_POWER_MANAGER) #include "power_display_service.h" #endif -#include "ui_screennotify.h" -#include "HealthModel.h" +#include "screennotify/ui_screennotify.h" +#include "main/HealthModel.h" #include "bts_br_gap.h" #include "bts_le_gap.h" +#include "uiservice/ui_language.h" + #include "errcode.h" #include "pm_definition.h" +#include "NativeAbility.h" +#include "TransitionType.h" + extern "C" errcode_t uapi_pm_add_sleep_veto(pm_id_t veto_id); extern "C" errcode_t uapi_pm_remove_sleep_veto(pm_id_t veto_id); @@ -194,6 +199,14 @@ void ServiceMsgProcess(Request *request) case CONNECT_NEW_PHONE: ConnectNewPhone(); break; + case UI_UPDATE_LANGUAGE: + OHOS::UILanguage::UpdateLanguage(); + break; + case UI_OTA_UPDATE: + power_display_svr_get_api()->turn_on_screen(); + OHOS::NativeAbility::GetInstance().ChangeSlice(VIEW_SET_OTA, + OHOS::TransitionType::TRANSITION_INVALID, OHOS::gSliceDefaultPriority, true); + break; } } diff --git a/code/sdk/application/wearable/nativeapp/nativeui/videocard/src/VideoCard.cpp b/code/sdk/application/wearable/nativeapp/nativeui/videocard/src/VideoCard.cpp index 4bd5cc73d..e97fa8fe0 100644 --- a/code/sdk/application/wearable/nativeapp/nativeui/videocard/src/VideoCard.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/videocard/src/VideoCard.cpp @@ -1,17 +1,17 @@ #include #include -#include "VideoCard.h" +#include "videocard/VideoCard.h" #include "NativeAbility.h" #include "msg_center.h" #include "securec.h" -#include "DialBinParser.h" -#include "ModelDialDataFactory.h" +#include "main/DialBinParser.h" +#include "main/dial/ModelDialDataFactory.h" #include "common/low_power_manager.h" #include "common/image_cache_manager.h" #ifdef SUPPORT_OHOSFWK -#include "ui_screennotify.h" +#include "screennotify/ui_screennotify.h" #endif -#include "MainPresenterSample.h" +#include "main/MainPresenterSample.h" #include "common/graphic_utils.h" namespace OHOS { diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherAdapter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherAdapter.cpp new file mode 100644 index 000000000..65aae4f0b --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherAdapter.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherAdapter + * Create: 2025-03-23 + */ + +#include "weather/WeatherAdapter.h" + +namespace OHOS { +WeatherAdapter::WeatherAdapter() {} + +WeatherAdapter::~WeatherAdapter() +{ + listData.clear(); +} + +uint16_t WeatherAdapter::GetCount(void) +{ + return listData.size(); +} + +void WeatherAdapter::SetData(std::list &data) +{ + if (!listData.empty()) { + listData.clear(); + } + std::list::iterator it; + for (it = data.begin(); it != data.end(); it++) { + listData.push_back(*it); + } +} + +UIView *WeatherAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData.size()) { + return nullptr; + } + + std::list::iterator it = listData.begin(); + for (int i = 0; i < index; i++) { + it++; + } + WeatherItem itemData = *it; + WeatherItemView *item = nullptr; + if (inView == nullptr) { + item = new WeatherItemView(); + } else { + item = static_cast(inView); + } + + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void WeatherAdapter::AddListItem(const WeatherItem &item) +{ + listData.push_back(item); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherItemView.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherItemView.cpp new file mode 100644 index 000000000..e417f9f1f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherItemView.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherItemView + * Create: 2025-03-23 + */ + +#include "wearable_log.h" +#include "weather/WeatherItemView.h" +#include "weather/WeatherModel.h" + +namespace OHOS { +static constexpr int16_t WEATHER_ICON_X = 155; +static constexpr int16_t WEATHER_LABEL_X = 10; +static constexpr int16_t WEATHER_LABEL2_X = 220; +static constexpr int16_t WEATHER_CHARTLINE_X = 20; +static constexpr int16_t WEATHER_CHARTLINE_Y = 78; +static constexpr int16_t WEATHER_CHARTLINE_WIDTH = 450; +static constexpr int16_t WEATHER_CHARTLINE_HEIGHT = 2; +static constexpr int16_t WEATHER_ITEM_BUTTON_WIDTH = 390; +static constexpr int16_t WEATHER_ITEM_BUTTON_HEIGHT = 83; +static constexpr int16_t WEATHER_ITEM_LABEL_WIDTH = 155; +static constexpr int16_t WEATHER_ITEM_LABEL_HEIGHT = 80; +static constexpr int16_t WEATHER_ITEM_FONT_SIZE = 35; +static constexpr int16_t WEATHER_IMAGE_SIZE = 300; +static constexpr int16_t WEATHER_ICON_Y = 15; +static constexpr int16_t NUMS_50 = 50; + +WeatherItemView::WeatherItemView() +{ + SetPosition(0, 0, WEATHER_ITEM_BUTTON_WIDTH, WEATHER_ITEM_BUTTON_HEIGHT); + SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + SetTouchable(true); + SetUpChild(); + + Add(&sNextImage); + Add(&sLabel_1); + Add(&sIcon); + Add(&sLabel_2); + Add(&chartLine); +} + +WeatherItemView::~WeatherItemView() +{ + Remove(&sIcon); + Remove(&sLabel_1); + Remove(&sLabel_2); + Remove(&chartLine); +} + +void WeatherItemView::SetItemInfo(const WeatherItem itemInfo) +{ + sItemInfo = itemInfo; + sLabel_1.SetText(itemInfo.label_1); + sIcon.SetSrc(itemInfo.icon); + sLabel_2.SetText(itemInfo.label_2); + chartLine.SetVisible(itemInfo.hasSecondMenu); +} + +void WeatherItemView::SetUpChild() +{ + sNextImage.SetPosition(0, 0); + sNextImage.Resize(WEATHER_IMAGE_SIZE, WEATHER_IMAGE_SIZE); + bool index = WeatherModel::GetInstance().GetDayStatus(); + ImageInfo *img = nullptr; + if (index) { + img = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_WEATHER71, WEATHER_IMAGE); + } else { + img = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_WEATHER72, WEATHER_IMAGE); + } + if (img == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherMainPage::LoadOneInMultiRes fail"); + } + sNextImage.SetSrc(img); + + sLabel_1.SetPosition(WEATHER_LABEL_X, 0); + sLabel_1.Resize(WEATHER_ITEM_LABEL_WIDTH, WEATHER_ITEM_LABEL_HEIGHT); + sLabel_1.SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_ITEM_FONT_SIZE); + sLabel_1.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + sLabel_1.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + sLabel_1.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_1.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + + sIcon.SetPosition(WEATHER_ICON_X, WEATHER_ICON_Y); + sIcon.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + sLabel_2.SetPosition(WEATHER_LABEL2_X, 0); + sLabel_2.Resize(WEATHER_ITEM_LABEL_WIDTH, WEATHER_ITEM_LABEL_HEIGHT); + sLabel_2.SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_ITEM_FONT_SIZE); + sLabel_2.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + sLabel_2.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel_2.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel_2.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + chartLine.SetPosition(WEATHER_CHARTLINE_X, WEATHER_CHARTLINE_Y, WEATHER_CHARTLINE_WIDTH, WEATHER_CHARTLINE_HEIGHT); + chartLine.SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); +} + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherMainPage.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherMainPage.cpp new file mode 100644 index 000000000..e1d963039 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherMainPage.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherMainPage + * Create: 2025-03-23 + */ + +#include +#include "weather/WeatherMainPage.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "weather/WeatherPresenter.h" +#include "weather/WeatherModel.h" +#include "ui_resource_weather.h" +#include "common/image_cache_manager.h" +#include "wearable_log.h" +#include +#include + +static constexpr int16_t WEATHER_LABEL_SIZE_WIDTH_ONE = 250; +static constexpr int16_t WEATHER_LABEL_SIZE_HEIGHT_ONE = 60; +static constexpr int16_t WEATHER_LABEL_SIZE_WIDTH_FOUR = 210; +static constexpr int16_t WEATHER_LABEL_SIZE_HEIGHT_FOUR = 40; +static constexpr int16_t WEATHER_LABEL_SIZE_WIDTH_FIVE = 223; +static constexpr int16_t WEATHER_LABEL_SIZE_HEIGHT_FIVE = 46; +static constexpr int16_t WEATHER_LABEL_SIZE_WIDTH_SIX = 149; +static constexpr int16_t WEATHER_LABEL_SIZE_HEIGHT_SIX = 20; +static constexpr int16_t WEATHER_LABEL_FRONT_ONE = 40; +static constexpr int16_t WEATHER_LABEL_FRONT_TWO = 24; +static constexpr int16_t WEATHER_LABEL_FRONT_THREE = 36; +static constexpr int16_t WEATHER_LABEL_FRONT_FOUR = 120; +static constexpr int16_t WEATHER_LABEL_FRONT = 22; +static constexpr int16_t WEATHER_AROUND_X = 74; +static constexpr int16_t WEATHER_AROUND_Y = 323; +static constexpr int16_t WEATHER_AROUND_WIDTH = 198; +static constexpr int16_t WEATHER_AROUND_HEIGHT = 40; +static constexpr int16_t WEATHER_CODE_POSITION_X = 267; +static constexpr int16_t WEATHER_CODE_POSITION_Y = 268; +static constexpr int16_t WEATHER_CODE_POSITION_WIDTH = 72; +static constexpr int16_t WEATHER_CODE_POSITION_HEIGHT = 46; +static constexpr int16_t WEATHER_TEMP_POSITION_X = 210; +static constexpr int16_t WEATHER_TEMP_POSITION_Y = 130; +static constexpr int16_t WEATHER_TEMP_WIDTH = 190; +static constexpr int16_t WEATHER_TEMP_HEIGHT = 120; +static constexpr int16_t WEATHER_IMAGE_WIDTH = 78; +static constexpr int16_t WEATHER_IMAGE_HEIGHT = 115; +static constexpr int16_t WEATHER_IMAGEAIR_X = 78; +static constexpr int16_t WEATHER_IMAGEAIR_Y = 327; +static constexpr int16_t WEATHER_IMAGEAIR_DATA = 40; +static constexpr int16_t WEATHER_IMAGEHUMIDITY_X = 336; +static constexpr int16_t WEATHER_IMAGEHUMIDITY_Y = 327; +static constexpr int16_t WEATHER_LABLEAIR_DATA = 79; +static constexpr int16_t WEATHER_LABLEAIR_HEIGHT = 30; +static constexpr int16_t WEATHER_IMAGEHUMIDITY_DATA = 120; +static constexpr int16_t WEATHER_IMG_X = 71; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_X = 199; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_Y = 429; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_WIDTH = 56; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_HEIGHT = 10; +static constexpr int16_t WEATHER_LABELTITLE_POSITION_X = 63; +static constexpr int16_t WEATHER_LABELTITLE_POSITION_Y = 100; +static constexpr int16_t WEATHER_LABELTITLE_WIDTH = 400; +static constexpr int16_t WEATHER_ADDRESS_X = 143; +static constexpr int16_t WEATHER_ADDRESS_Y = 49; + +const char *weatherNames[] = {"晴", "多云", "阴", "阵雨", "雷阵雨", "雷阵雨伴有冰雹", "雨夹雪", + "小雨", "中雨", "大雨", "暴雨", "大暴雨", "特大暴雨", "阵雪", + "小雪", "中雪", "大雪", "暴雪", "雾", "冻雨", "沙尘暴", + "小到中雨", "中到大雨", "大到暴雨", "小到中雪", "中到大雪", "大到暴雪", "浮尘", + "扬沙", "强沙尘暴", "霾", "无天气数据"}; + +namespace OHOS { +REGIST_SLICE_PAGE(VIEW_WEATHER, WEATHER_PAGES::WEATHER_MAIN_PAGE, WeatherMainPage, true); + +WeatherMainPage::WeatherMainPage() +{ + weatherModel = &WeatherModel::GetInstance(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherMainPage::WeatherMainPage"); +} + +WeatherMainPage::~WeatherMainPage() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherMainPage::~WeatherMainPage"); + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (weatherImg != nullptr) { + delete weatherImg; + weatherImg = nullptr; + } + + if (mainImg != nullptr) { + delete mainImg; + mainImg = nullptr; + } + + if (aroundImg != nullptr) { + delete aroundImg; + aroundImg = nullptr; + } + + if (ImageAir != nullptr) { + delete ImageAir; + ImageAir = nullptr; + } + + if (ImageHumidity != nullptr) { + delete ImageHumidity; + ImageHumidity = nullptr; + } + + if (ImagePageKey != nullptr) { + delete ImagePageKey; + ImagePageKey = nullptr; + } + ImageCacheManager::GetInstance().UnloadAllInMultiRes(WEATHER_IMAGE); +} + +void WeatherMainPage::OnStart(void *data) +{ + group = new UIViewGroup(); + if (group == nullptr) { + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::InitPageFirst successful"); + group->SetPosition(0, 0); + group->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + group->SetOnDragListener(this); + group->SetViewId("weather"); + group->SetDraggable(true); + group->SetTouchable(true); + flag = weatherModel->InitWeatherItem(); + cur = weatherModel->GetCurWeather(); + mainImg = new UIImageView(); + if (mainImg == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::mainImg new image fail"); + return; + } + mainImg->SetPosition(0, 0); + mainImg->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + group->Add(mainImg); + InitWeatherImage(); + InitImage(); + InitLabel(); + if (!flag) { + labelTitle = new UILabel(); + if (labelTitle == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::labelTitle new label fail"); + return; + } + labelTitle->SetText("天气未更新,请连接手机更新数据"); + labelTitle->SetPosition(WEATHER_LABELTITLE_POSITION_X, WEATHER_LABELTITLE_POSITION_Y, WEATHER_LABELTITLE_WIDTH, + WEATHER_LABEL_SIZE_HEIGHT_ONE); + labelTitle->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT); + group->Add(labelTitle); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::InitWeatherItem fail"); + } + AddViewToPageContainer(group); +} + +void WeatherMainPage::InitImage() +{ + aroundImg = new UIImageView(); + if (aroundImg == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::aroundImage new image fail"); + return; + } + aroundImg->SetPosition(WEATHER_AROUND_X, WEATHER_AROUND_Y); + if (weatherModel->GetDayStatus()) { + LOADIMG::LoadImageViewImg(mainImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER64); + LOADIMG::LoadImageViewImg(aroundImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER75); + } else { + LOADIMG::LoadImageViewImg(mainImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER65); + LOADIMG::LoadImageViewImg(aroundImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER76); + } + ImageAir = new UIImageView(); + if (ImageAir == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::ImageAir new image fail"); + return; + } + ImageAir->SetPosition(WEATHER_IMAGEAIR_X, WEATHER_IMAGEAIR_Y); + ImageAir->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + LOADIMG::LoadImageViewImg(ImageAir, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER69); + ImageHumidity = new UIImageView(); + if (ImageHumidity == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::ImageHumidity new image fail"); + return; + } + ImageHumidity->SetPosition(WEATHER_IMAGEHUMIDITY_X, WEATHER_IMAGEHUMIDITY_Y); + ImageHumidity->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + LOADIMG::LoadImageViewImg(ImageHumidity, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER70); + ImagePageKey = new UIImageView(); + if (ImagePageKey == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::ImagePageKey new image fail"); + return; + } + ImagePageKey->SetPosition(WEATHER_IMAGEPAGEKEY_X, WEATHER_IMAGEPAGEKEY_Y); + ImagePageKey->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + LOADIMG::LoadImageViewImg(ImagePageKey, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER66); + group->Add(aroundImg); + group->Add(ImageAir); + group->Add(ImageHumidity); + group->Add(ImagePageKey); +} + +void WeatherMainPage::InitWeatherImage() +{ + addressImg = new UIImageView(); + if (addressImg == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::img new image fail"); + return; + } + addressImg->SetPosition(WEATHER_ADDRESS_X, WEATHER_ADDRESS_Y); + addressImg->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + curWeather_code = std::atoi(cur.weather_code); + LOADIMG::LoadImageViewImg(addressImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER77); + + weatherImg = new UIImageView(); + if (weatherImg == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::img new image fail"); + return; + } + weatherImg->SetPosition(WEATHER_IMG_X, WEATHER_TEMP_POSITION_Y); + weatherImg->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + curWeather_code = std::atoi(cur.weather_code); + LOADIMG::LoadImageViewImg(weatherImg, WEATHER_IMAGE, bigWeatherImage[curWeather_code]); + group->Add(addressImg); + group->Add(weatherImg); +} + + +void WeatherMainPage::InitLabel() +{ + int posX[LABEL_COUNT] = {140, 113, 120, 222, 100, 210}; + int posY[LABEL_COUNT] = {34, 274, 332, 332, 376, 130}; + for (int i = 0; i < LABEL_COUNT; i++) { + title[i] = new UILabel(); + if (title[i] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::InitPageFirst new label:%d fail", i); + return; + } + if (i == SET_ZERO) { + title[i]->SetText(cur.address); + title[i]->SetPosition(posX[i], posY[i], WEATHER_LABEL_SIZE_WIDTH_ONE, WEATHER_LABEL_SIZE_HEIGHT_ONE); + title[i]->SetAlign(TEXT_ALIGNMENT_LEFT); + title[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT_ONE); + } else if (i == SET_ONE) { + std::ostringstream oss; + oss << cur.max_degree << "° / " << cur.min_degree << "° " << weatherNames[curWeather_code]; + std::string weatherTemp = oss.str(); + title[i]->SetText(weatherTemp.c_str()); + title[i]->SetPosition(posX[i], posY[i], WEATHER_LABEL_SIZE_WIDTH_FIVE, WEATHER_LABEL_SIZE_HEIGHT_FIVE); + title[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT_THREE); + } else if (i == SET_TWO) { + std::ostringstream oss; + oss << "空气 -"; + std::string weatherHumidity = oss.str(); + title[i]->SetText(weatherHumidity.c_str()); + title[i]->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title[i]->SetPosition(posX[i], posY[i], WEATHER_LABLEAIR_DATA, WEATHER_LABLEAIR_HEIGHT); + title[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT_TWO); + } else if (i == SET_THREE) { + std::ostringstream oss; + oss << "湿度" << cur.humidity <<"%"; + std::string weatherHumidity = oss.str(); + title[i]->SetText(weatherHumidity.c_str()); + title[i]->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title[i]->SetPosition(posX[i], posY[i], WEATHER_IMAGEHUMIDITY_DATA, WEATHER_LABLEAIR_HEIGHT); + title[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT_TWO); + } else if (i == SET_FOUR) { + std::ostringstream oss; + std::string updateTime = FormatTime(flag, cur.updateTime); + oss << "上次更新时间 " << updateTime; + updateTime = oss.str(); + title[i]->SetText(updateTime.c_str()); + title[i]->SetPosition(posX[i], posY[i], WEATHER_LABEL_SIZE_WIDTH_ONE, WEATHER_LABEL_SIZE_HEIGHT_FOUR); + title[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT_TWO); + } else if (i == SET_FIVE) { + std::ostringstream oss; + oss << cur.degree << "°"; + std::string weatherTemp = oss.str(); + title[i]->SetText(weatherTemp.c_str()); + title[i]->SetPosition(posX[i], posY[i], WEATHER_TEMP_WIDTH, WEATHER_TEMP_HEIGHT); + title[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABEL_FRONT_FOUR); + } + title[i]->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(title[i]); + } +} + +std::string WeatherMainPage::FormatTime(bool falg, const std::string &inputStr) +{ + if (!flag) { + return "--"; + } + tm inputTm = {}; + std::istringstream iss(inputStr); + iss >> std::get_time(&inputTm, "%Y%m%d%H%M"); + time_t inputTime = mktime(&inputTm); + time_t now = time(nullptr); + tm *nowTm = localtime(&now); + if (inputTm.tm_year == nowTm->tm_year && inputTm.tm_mon == nowTm->tm_mon && inputTm.tm_mday == nowTm->tm_mday) { + char buffer[6]; + strftime(buffer, sizeof(buffer), "%H:%M", &inputTm); + return std::string(buffer); + } else { + char buffer[6]; + strftime(buffer, sizeof(buffer), "%m/%d", &inputTm); + return std::string(buffer); + } +} + +bool WeatherMainPage::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPresenter::OnDrag ChangeSlice(VIEW_APPLIST)"); + } else if (event.GetDragDirection() == DragEvent::DIRECTION_RIGHT_TO_LEFT) { + NativeAbility::GetInstance().SwitchPageInSlice(WEATHER_PAGES::WEATHER_SECOND_PAGE, nullptr, + TransitionType::TRANSITION_INVALID, true); + } + return false; +} + +bool WeatherMainPage::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + return true; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherModel.cpp new file mode 100644 index 000000000..6b77b9572 --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherModel.cpp @@ -0,0 +1,411 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherModel + * Create: 2025-03-23 + */ + +#include "weather/WeatherModel.h" +#include "weather/WeatherPresenter.h" +#include "wearable_log.h" +#include "ui_resource_weather.h" +#ifdef BUILD_IN_LINUX +#include "localtime.h" +#endif + +namespace OHOS { + +WeatherModel::WeatherModel() {} + +WeatherModel::~WeatherModel() {} + +WeatherModel &WeatherModel::GetInstance() +{ + static WeatherModel instance; + return instance; +} + +uint8_t WeatherModel::GetWeatherListNum() +{ + return usedLen; +} + +WeatherItem *WeatherModel::GetWeatherlistItems() +{ + if (weather[0].label_1 == nullptr) { + ImageInfo *imgSrc = + ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_WEATHER47, WEATHER_IMAGE); + weather[SET_ZERO] = {"今天", imgSrc, "16°/26°", true}; + weather[SET_ONE] = {"明天", imgSrc, "18°/28°", false}; + weather[SET_TWO] = {"后天", imgSrc, "17°/27°", false}; + weather[SET_THREE] = {"周四", imgSrc, "15°/24°", false}; + weather[SET_FOUR] = {"周五", imgSrc, "14°/22°", false}; + weather[SET_FIVE] = {"周六", imgSrc, "16°/25°", false}; + weather[SET_SIX] = {"周日", imgSrc, "19°/29°", false}; + usedLen = SET_SEVEN; + } + return weather; +} + +CurWeather WeatherModel::GetCurWeather() +{ + if (curWeather.min_degree == nullptr) { + curWeather.min_degree = "10"; + curWeather.max_degree = "25"; + curWeather.address = "北京市"; + curWeather.weather_code = "02"; + curWeather.degree = "18"; + curWeather.updateTime = "2023-11-15 14:30:00 20"; + curWeather.humidity = "90"; + curWeather.sunSet = "17:30"; + curWeather.sunRise = "06:45"; + } + return curWeather; +} + +std::vector WeatherModel::GetHourWeather() +{ + if (houWeather.size() < WEATHER_COUNT) { + HourWeather weatherData[] = { + {"00:00", "18", "04"}, {"01:00", "17", "06"}, {"02:00", "17", "06"}, {"03:00", "16", "06"}, + {"04:00", "16", "07"}, {"05:00", "15", "07"}, {"06:00", "16", "08"}, {"07:00", "17", "08"}, + {"08:00", "18", "04"}, {"09:00", "20", "04"}, {"10:00", "22", "04"}, {"11:00", "24", "04"}, + {"12:00", "25", "04"}, {"13:00", "26", "04"}, {"14:00", "26", "04"}, {"15:00", "25", "06"}, + {"16:00", "24", "06"}, {"17:00", "23", "06"}, {"18:00", "22", "06"}, {"19:00", "21", "07"}, + {"20:00", "20", "07"}, {"21:00", "19", "10"}, {"22:00", "18", "10"}, {"23:00", "18", "10"}}; + for (const auto &item : weatherData) { + houWeather.push_back(item); + } + } + return houWeather; +} + +bool WeatherModel::InitWeatherItem() +{ + std::ifstream file("/user/app/user/ace/data/com.vendor.Weather/weather.json"); + if (!file.is_open()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "no file"); + return false; + } + std::stringstream buffer; + buffer << file.rdbuf(); + std::string content = buffer.str(); + int intsize = sizeof(content); + cJSON *root = nullptr; + // 解析JSON字符串 + if (intsize != 0) { + root = cJSON_Parse(content.c_str()); + } + if (root == NULL) { + // 如果解析失败,输出错误信息 + const char *error_ptr; + return false; + } + // 访问JSON数据 + bool updateMsg = InitVecObserve(root); + if (updateMsg) { + InitVecForecast(root); + InitVecRise(root); + InitVecWeek(root); + InitVecAddress(root); + InitFirstPageData(); + InitSecondPageData(); + InitThirdPageData(); + } else { + cJSON_Delete(root); + return false; + } + cJSON_Delete(root); + return true; +} + +void WeatherModel::InitFirstPageData() +{ + curWeather = {0}; + static std::string sunset; + static std::string sunrise; + if (map_observe.find("min_degree") != map_observe.end()) { + curWeather.min_degree = map_observe["min_degree"].c_str(); + } + if (map_observe.find("max_degree") != map_observe.end()) { + curWeather.max_degree = map_observe["max_degree"].c_str(); + } + if (map_observe.find("degree") != map_observe.end()) { + curWeather.degree = map_observe["degree"].c_str(); + } + if (map_observe.find("weather_code") != map_observe.end()) { + curWeather.weather_code = map_observe["weather_code"].c_str(); + } + if (map_observe.find("update_time") != map_observe.end()) { + curWeather.updateTime = map_observe["update_time"].c_str(); + } + if (map_observe.find("humidity") != map_observe.end()) { + curWeather.humidity = map_observe["humidity"].c_str(); + } + if (map_address.find("city") != map_address.end()) { + curWeather.address = map_address["city"].c_str(); + } + if (map_address.find("address") != map_address.end()) { + curWeather.address = map_address["address"].c_str(); + } +} + +void WeatherModel::InitSecondPageData() +{ + houWeather.clear(); + static std::string dayTime[WEATHER_COUNT]; + static std::string dayTemp[WEATHER_COUNT]; + static std::string dayWeather[WEATHER_COUNT]; + + for (const auto &item : vec_forecast_1h) { + const std::string name = std::get<0>(item); + const std::string category = std::get<1>(item); + const int id = std::get(item); + HourWeather sample = {nullptr}; + if (name == "update_time") { + dayTime[id] = category; + } else if (name == "degree") { + dayTemp[id] = category; + } else if (name == "weather_code") { + dayWeather[id] = category; + } + } + for (int i = 0; i < WEATHER_COUNT; i++) { + HourWeather sample = {nullptr}; + sample.hour = dayTime[i].c_str(); + sample.degree = dayTemp[i].c_str(); + sample.weather = dayWeather[i].c_str(); + houWeather.push_back(sample); + } +} + +void WeatherModel::InitThirdPageData() +{ + static std::string strTmp[SET_EIGHT]; + static std::string minTemp[SET_EIGHT]; + static std::string maxTemp[SET_EIGHT]; + static std::string currentWeek[SET_EIGHT]; + static int weatherValue[SET_EIGHT]; + for (const auto &item : vec_forecast_24h) { + const std::string name = std::get<0>(item); + const std::string category = std::get<1>(item); + const int id = std::get(item); + if (name == "current_week") { + if (id == SET_ZERO) { + currentWeek[id] = "今天"; + } else if (id == SET_ONE) { + currentWeek[id] = "明天"; + } else if (id == SET_TWO) { + currentWeek[id] = "后天"; + } else { + currentWeek[id] = category; + } + } else if (name == "min_degree") { + minTemp[id] = category; + } else if (name == "max_degree") { + maxTemp[id] = category; + } else if (name == "day_weather_code") { + weatherValue[id] = std::atoi(category.c_str()); + } + } + for (int i = 0; i < SET_SEVEN; i++) { + strTmp[i] = maxTemp[i] + "°/" + minTemp[i] + "°"; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherModel::InitWeatherItem:%s", strTmp[i].c_str()); + } + // 只显示七天的天气 + for (int i = 0; i < SET_SEVEN; i++) { + int weatherIndex = weatherValue[i]; + ImageInfo *imgSrc = + ImageCacheManager::GetInstance().LoadOneInMultiRes(smallWeatherImage[weatherIndex], WEATHER_IMAGE); + weather[i] = {currentWeek[i].c_str(), imgSrc, strTmp[i].c_str(), true}; + } + usedLen = SET_SEVEN; +} + +bool WeatherModel::InitVecForecast(cJSON *root) +{ + vec_forecast_1h.clear(); + // 获取 forecast_1h 对象 + cJSON *forecast_1h = cJSON_GetObjectItemCaseSensitive(root, "forecast_1h"); + if (!cJSON_IsObject(forecast_1h)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error forecast_1h:"); + cJSON_Delete(root); + return false; + } + for (int i = 0; i < WEATHER_COUNT; i++) { + cJSON *forecast_1h_num = cJSON_GetObjectItemCaseSensitive(forecast_1h, std::to_string(i).c_str()); + if (!cJSON_IsObject(forecast_1h_num)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error forecast_1h_num:%d", i); + continue; // 跳过当前循环,继续处理下一个 + } + std::string str = cJSON_GetObjectItemCaseSensitive(forecast_1h_num, "update_time")->valuestring; + std::string hour = str.substr(SET_TWELVE, SET_TWO); + // 确保字符串长度至少为12 + if (str.length() >= WEATHER_HOUR) { + // 提取小时部分 + hour = str.substr(SET_EIGHT, SET_TWO) + ":00"; + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error forecast_1h:"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error forecast_1h hour size error"); + hour = "00:00"; + } + vec_forecast_1h.push_back(std::make_tuple("update_time", hour, i)); + vec_forecast_1h.push_back( + std::make_tuple("degree", cJSON_GetObjectItemCaseSensitive(forecast_1h_num, "degree")->valuestring, i)); + vec_forecast_1h.push_back(std::make_tuple( + "weather_code", cJSON_GetObjectItemCaseSensitive(forecast_1h_num, "weather_code")->valuestring, i)); + } + return true; +} + +bool WeatherModel::InitVecObserve(cJSON *root) +{ + map_observe.clear(); + // 获取 observe 对象 + cJSON *observe = cJSON_GetObjectItemCaseSensitive(root, "observe"); + if (!cJSON_IsObject(observe)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error observe:"); + cJSON_Delete(root); + return false; + } + map_observe.insert(std::make_pair("weather", cJSON_GetObjectItemCaseSensitive(observe, "weather")->valuestring)); + map_observe.insert(std::make_pair("degree", cJSON_GetObjectItemCaseSensitive(observe, "degree")->valuestring)); + map_observe.insert(std::make_pair("humidity", cJSON_GetObjectItemCaseSensitive(observe, "humidity")->valuestring)); + map_observe.insert( + std::make_pair("min_degree", cJSON_GetObjectItemCaseSensitive(observe, "min_degree")->valuestring)); + map_observe.insert( + std::make_pair("max_degree", cJSON_GetObjectItemCaseSensitive(observe, "max_degree")->valuestring)); + map_observe.insert( + std::make_pair("update_time", cJSON_GetObjectItemCaseSensitive(observe, "update_time")->valuestring)); + map_observe.insert( + std::make_pair("weather_code", cJSON_GetObjectItemCaseSensitive(observe, "weather_code")->valuestring)); + return true; +} + +bool WeatherModel::InitVecRise(cJSON *root) +{ + // 获取 rise 对象 + vec_rise.clear(); + cJSON *rise = cJSON_GetObjectItemCaseSensitive(root, "rise"); + if (!cJSON_IsObject(rise)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error rise:"); + cJSON_Delete(root); + return false; + } + for (int i = 0; i < SET_FOURTEEN; i++) { + cJSON *rise_num = cJSON_GetObjectItemCaseSensitive(rise, std::to_string(i).c_str()); + if (!cJSON_IsObject(rise_num)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error rise:%d", i); + continue; // 跳过当前循环,继续处理下一个 + } + std::string sunSet = cJSON_GetObjectItemCaseSensitive(rise_num, "sunset")->valuestring; + std::string sunRise = cJSON_GetObjectItemCaseSensitive(rise_num, "sunrise")->valuestring; + SetDayStatus(sunRise, sunSet); + } + return true; +} + +bool WeatherModel::InitVecWeek(cJSON *root) +{ + vec_forecast_24h.clear(); + cJSON *forecast_24h = cJSON_GetObjectItemCaseSensitive(root, "forecast_24h"); + if (!cJSON_IsObject(forecast_24h)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error forecast_24h:"); + cJSON_Delete(root); + return false; + } + for (int i = 0; i < SET_TEN; i++) { + cJSON *forecast_24h_num = cJSON_GetObjectItemCaseSensitive(forecast_24h, std::to_string(i).c_str()); + if (!cJSON_IsObject(forecast_24h_num)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error forecast_24h_num:%d", i); + continue; + } + std::istringstream iss(cJSON_GetObjectItemCaseSensitive(forecast_24h_num, "time")->valuestring); + char dash1; + char dash2; + int year = 0; + int month = 0; + int day = 0; + const int start_year = START_YEAR; + if ((iss >> year >> dash1 >> month >> dash2 >> day) && (dash1 == '-') && (dash2 == '-')) { + std::tm timeinfo = {}; + timeinfo.tm_year = year - start_year; + timeinfo.tm_mon = month - 1; + timeinfo.tm_mday = day; + timeinfo.tm_hour = 0; + timeinfo.tm_min = 0; + timeinfo.tm_sec = 0; + timeinfo.tm_isdst = -1; + std::time_t timestamp = mktime(&timeinfo); + if (timestamp == -1) { + return false; + } + std::tm localTimeInfo; +#ifdef _WIN32 + if (localtime_s(&localTimeInfo, ×tamp) != 0) { +#else + if (localtime_r(×tamp, &localTimeInfo) == nullptr) { +#endif + return false; + } + const char *current_weeks[] = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; + vec_forecast_24h.push_back(std::make_tuple("current_week", current_weeks[localTimeInfo.tm_wday], i)); + vec_forecast_24h.push_back(std::make_tuple( + "min_degree", cJSON_GetObjectItemCaseSensitive(forecast_24h_num, "min_degree")->valuestring, i)); + vec_forecast_24h.push_back(std::make_tuple( + "max_degree", cJSON_GetObjectItemCaseSensitive(forecast_24h_num, "max_degree")->valuestring, i)); + vec_forecast_24h.push_back(std::make_tuple( + "day_weather_code", cJSON_GetObjectItemCaseSensitive(forecast_24h_num, "day_weather_code")->valuestring, + i)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "day_weather_code:%s ", + cJSON_GetObjectItemCaseSensitive(forecast_24h_num, "day_weather_code")->valuestring); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error Date"); + } + } + return true; +} + +bool WeatherModel::InitVecAddress(cJSON *root) +{ + map_address.clear(); + cJSON *address = cJSON_GetObjectItemCaseSensitive(root, "address"); + if (!cJSON_IsObject(address)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Error address:"); + cJSON_Delete(root); + return false; + } + map_address.insert(std::make_pair("province", cJSON_GetObjectItemCaseSensitive(address, "province")->valuestring)); + map_address.insert(std::make_pair("city", cJSON_GetObjectItemCaseSensitive(address, "city")->valuestring)); + map_address.insert(std::make_pair("county", cJSON_GetObjectItemCaseSensitive(address, "county")->valuestring)); + return true; +} + +void WeatherModel::SetDayStatus(const std::string &timeRise, const std::string &timeSet) +{ +#ifdef _WIN32 + struct timeval tv; + gettimeofday(&tv, NULL); +#else + struct timeval64 tv; + gettimeofday64(&tv, NULL); +#endif + uint64_t second = tv.tv_sec; + uint64_t minute = second / MIN_TO_HOUR; + uint64_t hour = minute / MIN_TO_HOUR; + uint8_t realHour = static_cast(hour % HOURLY_SYSTEM); + uint8_t realMinute = static_cast(minute % MIN_TO_HOUR); + int currentTime = realHour * MIN_TO_HOUR + realMinute; + int hours = (timeRise[SET_ZERO] - '0') * SET_TEN + (timeRise[SET_ONE] - '0'); + int minutes = (timeRise[SET_THREE] - '0') * SET_TEN + (timeRise[SET_FOUR] - '0'); + int rise = hours * MIN_TO_HOUR + minutes; + hours = (timeSet[SET_ZERO] - '0') * SET_TEN + (timeSet[SET_ONE] - '0'); + minutes = (timeSet[SET_THREE] - '0') * SET_TEN + (timeSet[SET_FOUR] - '0'); + int set = hours * MIN_TO_HOUR + minutes; + isDay = (currentTime >= rise && currentTime < set) ? true : false; +} + +bool WeatherModel::GetDayStatus() +{ + return isDay; +} +} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageSecond.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageSecond.cpp new file mode 100644 index 000000000..f9e9e768f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageSecond.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherPageSecond + * Create: 2025-03-15 + */ + +#include "weather/WeatherPageSecond.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "weather/WeatherPresenter.h" +#include "weather/WeatherView.h" +#include "weather/WeatherModel.h" +#include "ui_resource_weather.h" +#include "common/image_cache_manager.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr uint16_t WEATHER_TITLE_WIDTH = 51; +static constexpr uint16_t WEATHER_TITLE_HEIGHT = 26; +static constexpr uint16_t WEATHER_TOPLABEL_X = 156; +static constexpr uint16_t WEATHER_TOPLABEL_Y = 22; +static constexpr uint16_t WEATHER_TOPLABEL_WIDTH = 150; +static constexpr uint16_t WEATHER_TOPLABEL_HEIGHT = 60; +static constexpr uint16_t WEATHER_TOPLABEL_FRONT = 26; +static constexpr uint16_t WEATHER_LABELTIME_FRONT = 20; +static constexpr uint16_t WEATHER_LABELTIME_FRONT_TWO = 24; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_X = 199; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_Y = 429; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_WIDTH = 56; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_HEIGHT = 10; +static constexpr uint16_t ANIMATOR_TIME = 50; + +REGIST_SLICE_PAGE(VIEW_WEATHER, WEATHER_PAGES::WEATHER_SECOND_PAGE, WeatherPageSecond, false); + +WeatherPageSecond::WeatherPageSecond() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageSecond::WeatherPageSecond"); + weatherModel = &WeatherModel::GetInstance(); +} + +WeatherPageSecond::~WeatherPageSecond() +{ + if (weatherSwipeGroup != nullptr) { + weatherSwipeGroup->RemoveAll(); + delete weatherSwipeGroup; + weatherSwipeGroup = nullptr; + } + + for (int i = 0; i < SET_THREE; ++i) { + if (swipeGroup[i] != nullptr) { + swipeGroup[i]->RemoveAll(); + delete swipeGroup[i]; + swipeGroup[i] = nullptr; + } + } + + for (int i = 0; i < SET_EIGHT; ++i) { + if (imgBack[i] != nullptr) { + delete imgBack[i]; + imgBack[i] = nullptr; + } + } + + for (int i = 0; i < SET_EIGHT; ++i) { + if (labelTime[i] != nullptr) { + delete labelTime[i]; + labelTime[i] = nullptr; + } + } + + for (int i = 0; i < SET_EIGHT; ++i) { + if (labelTemp[i] != nullptr) { + delete labelTemp[i]; + labelTemp[i] = nullptr; + } + } + + for (int i = 0; i < SET_EIGHT; ++i) { + if (imgWeather[i] != nullptr) { + delete imgWeather[i]; + imgWeather[i] = nullptr; + } + } + if (mainImg != nullptr) { + delete mainImg; + mainImg = nullptr; + } + if (ImagePageKey != nullptr) { + delete ImagePageKey; + ImagePageKey = nullptr; + } + ImageCacheManager::GetInstance().UnloadAllInMultiRes(WEATHER_IMAGE); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageSecond::~WeatherPageSecond"); +} + +void WeatherPageSecond::OnStart(void *data) +{ + weatherSwipeGroup = new UISwipeView(UISwipeView::VERTICAL); + if (weatherSwipeGroup == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "weatherSwipeGroup new fail"); + return; + } + weatherSwipeGroup->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + weatherSwipeGroup->SetViewId("weatherSwipeGroup"); + weatherSwipeGroup->SetOnDragListener(this); + weatherSwipeGroup->SetOnSwipeListener(this); + weatherSwipeGroup->SetDraggable(true); + weatherSwipeGroup->SetTouchable(true); + weatherSwipeGroup->SetAnimatorTime(ANIMATOR_TIME); + for (int i = 0; i < SET_THREE; i++) { + swipeGroup[i] = new UIViewGroup(); + if (swipeGroup[i] == nullptr) { + return; + } + WeatherInit(swipeGroup[i]); + weatherSwipeGroup->Add(swipeGroup[i]); + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::InitPageFirst successful"); + AddViewToPageContainer(weatherSwipeGroup); +} + +void WeatherPageSecond::WeatherInit(UIViewGroup *group) +{ + group->SetPosition(0, 0); + group->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); + group->SetOnDragListener(this); + group->SetViewId("weather"); + group->SetDraggable(true); + group->SetTouchable(true); + mainImg = new UIImageView(); + mainImg->SetPosition(0, 0); + mainImg->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + ImageInfo *imgSrc = + ImageCacheManager::GetInstance().LoadOneInMultiRes(IMAGE_CONVERTER_TOOL_WEATHER65, WEATHER_IMAGE); + if (imgSrc == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherMainPage::LoadOneInMultiRes fail"); + } + if (weatherModel->GetDayStatus()) { + LOADIMG::LoadImageViewImg(mainImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER64); + } else { + LOADIMG::LoadImageViewImg(mainImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER65); + } + group->Add(mainImg); + houWeather = weatherModel->GetHourWeather(); + ImagePageKey = new UIImageView(); + if (ImagePageKey == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::ImagePageKey new image fail"); + return; + } + ImagePageKey->SetPosition(WEATHER_IMAGEPAGEKEY_X, WEATHER_IMAGEPAGEKEY_Y, WEATHER_IMAGEPAGEKEY_WIDTH, + WEATHER_IMAGEPAGEKEY_HEIGHT); + ImagePageKey->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + LOADIMG::LoadImageViewImg(ImagePageKey, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER67); + group->Add(ImagePageKey); + int count = index * SET_EIGHT; + index++; + InitImage(group, count); + InitLabel(group, count); + return; +} + +void WeatherPageSecond::InitImage(UIViewGroup *group, int count) +{ + int weatherPosX[SET_EIGHT] = {67, 161, 257, 351, 67, 161, 257, 351}; + int weatherPosY[SET_EIGHT] = {125, 125, 125, 125, 289, 289, 289, 289}; + int backPosX[SET_EIGHT] = {47, 141, 235, 329, 47, 141, 235, 329}; + int backPosY[SET_EIGHT] = {71, 71, 71, 71, 235, 235, 235, 235}; + for (int i = 0; i < SET_EIGHT; i++) { + imgBack[i] = new UIImageView(); + if (imgBack[i] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageSecond::InitPageSecond new UIImageView fail"); + return; + } + imgBack[i]->SetPosition(backPosX[i], backPosY[i]); + if (weatherModel->GetDayStatus()) { + LOADIMG::LoadImageViewImg(imgBack[i], WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER73); + } else { + LOADIMG::LoadImageViewImg(imgBack[i], WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER74); + } + + imgWeather[i] = new UIImageView(); + if (imgWeather[i] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageSecond::InitPageSecond new labelTime fail"); + return; + } + imgWeather[i]->SetPosition(weatherPosX[i], weatherPosY[i]); + int curWeather_code = std::atoi(houWeather[count + i].weather); + LOADIMG::LoadImageViewImg(imgWeather[i], WEATHER_IMAGE, smallWeatherImage[curWeather_code]); + group->Add(imgBack[i]); + group->Add(imgWeather[i]); + } +} + +void WeatherPageSecond::InitLabel(UIViewGroup *group, int count) +{ + int timePosX[SET_EIGHT] = {67, 161, 255, 349, 67, 161, 255, 349}; + int timePosY[SET_EIGHT] = {91, 91, 91, 91, 255, 255, 255, 255}; + int tempPosX[SET_EIGHT] = {75, 169, 263, 356, 75, 169, 263, 356}; + int tempPosY[SET_EIGHT] = {175, 175, 175, 175, 339, 339, 339, 339}; + UILabel *topLabel = new UILabel(); + if (topLabel == nullptr) { + return; + } + topLabel->SetText("24小时预报"); + topLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_TOPLABEL_FRONT); + topLabel->SetPosition(WEATHER_TOPLABEL_X, WEATHER_TOPLABEL_Y, WEATHER_TOPLABEL_WIDTH, WEATHER_TOPLABEL_HEIGHT); + group->Add(topLabel); + for (int i = 0; i < SET_EIGHT; i++) { + labelTemp[i] = new UILabel(); + if (labelTemp[i] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageSecond::InitPageSecond new labelTemp fail"); + return; + } + std::ostringstream oss; + oss << houWeather[count + i].degree << "°"; + std::string temp = oss.str(); + labelTemp[i]->SetText(temp.c_str()); + labelTemp[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABELTIME_FRONT_TWO); + labelTemp[i]->SetPosition(tempPosX[i], tempPosY[i], WEATHER_TITLE_WIDTH, WEATHER_TITLE_HEIGHT); + + labelTime[i] = new UILabel(); + if (labelTime[i] == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageSecond::InitPageSecond new labelTime fail"); + return; + } + std::string strHour = houWeather[count + i].hour; + labelTime[i]->SetText(strHour.c_str()); + labelTime[i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_LABELTIME_FRONT); + labelTime[i]->SetPosition(timePosX[i], timePosY[i], WEATHER_TITLE_WIDTH, WEATHER_TITLE_HEIGHT); + group->Add(labelTemp[i]); + group->Add(labelTime[i]); + } +} + +bool WeatherPageSecond::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchPageInSlice(WEATHER_PAGES::WEATHER_MAIN_PAGE, nullptr, + TransitionType::TRANSITION_INVALID, true); + } else if (event.GetDragDirection() == DragEvent::DIRECTION_RIGHT_TO_LEFT) { + NativeAbility::GetInstance().SwitchPageInSlice(WEATHER_PAGES::WEATHER_THIRD_PAGE, nullptr, + TransitionType::TRANSITION_INVALID, true); + } + return false; +} + +void WeatherPageSecond::OnSwipe(UISwipeView &view) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TempPresenter::OnSwipe "); + UNUSED(view); + return; +} + +bool WeatherPageSecond::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + return true; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageThird.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageThird.cpp new file mode 100644 index 000000000..d6ca8fbaf --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPageThird.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherPageThird + * Create: 2025-03-23 + */ + +#include "weather/WeatherPageThird.h" +#include "components/ui_list_nested.h" +#include "components/ui_scroll_view_nested.h" +#include "NativeAbility.h" +#include "SlicePageFactory.h" +#include "weather/WeatherPresenter.h" +#include "weather/WeatherView.h" +#include "weather/WeatherModel.h" +#include "ui_resource_weather.h" +#include "common/image_cache_manager.h" +#include "wearable_log.h" + +namespace OHOS { +static constexpr uint8_t WEATHER_ITEM_FONT_SIZE = 25; +static constexpr int16_t WEATHER_RESIZE_SIZE_WIDTH = 200; +static constexpr int16_t WEATHER_RESIZE_SIZE_HEIGHT = 50; +static constexpr int16_t WEATHER_TITLE_POSITION_X = 130; +static constexpr int16_t WEATHER_LIST_POSITION_X = 32; +static constexpr int16_t WEATHER_LIST_POSITION_Y = 70; +static constexpr int16_t WEATHER_LIST_WIDTH = 390; +static constexpr int16_t WEATHER_LIST_HEIGHT = 318; +static constexpr int16_t WEATHER_LIST_SELECT_POSITION = 80; +static constexpr int16_t LIST_POS = 20; +static constexpr int16_t WEATHER_LABEL_FRONT_ONE = 20; +static constexpr int16_t WEATHER_LABEL_FRONT = 40; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_X = 199; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_Y = 429; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_WIDTH = 56; +static constexpr int16_t WEATHER_IMAGEPAGEKEY_HEIGHT = 10; + +REGIST_SLICE_PAGE(VIEW_WEATHER, WEATHER_PAGES::WEATHER_THIRD_PAGE, WeatherPageThird, false); + +WeatherPageThird::WeatherPageThird() +{ + weatherModel = &WeatherModel::GetInstance(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageThird::WeatherPageThird"); +} + +WeatherPageThird::~WeatherPageThird() +{ + if (group != nullptr) { + group->RemoveAll(); + delete group; + group = nullptr; + } + + if (contentList != nullptr) { + delete contentList; + contentList = nullptr; + } + + if (title != nullptr) { + delete title; + title = nullptr; + } + + if (listAdapter != nullptr) { + delete listAdapter; + listAdapter = nullptr; + } + + if (mainImg != nullptr) { + delete mainImg; + mainImg = nullptr; + } + + if (ImagePageKey != nullptr) { + delete ImagePageKey; + ImagePageKey = nullptr; + } + ImageCacheManager::GetInstance().UnloadAllInMultiRes(WEATHER_IMAGE); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageThird::~WeatherPageThird"); +} + +void WeatherPageThird::OnStart(void *data) +{ + group = new UIViewGroup(); + if (group == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::group is nullptr"); + return; + } + group->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + group->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + group->SetOnDragListener(this); + + title = new UILabel(); + if (title == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::title is nullptr"); + return; + } + title->SetPosition(WEATHER_TITLE_POSITION_X, WEATHER_LABEL_FRONT_ONE); + title->SetText("7日天气预报"); + title->Resize(WEATHER_RESIZE_SIZE_WIDTH, WEATHER_RESIZE_SIZE_HEIGHT); + title->SetFont(DEFAULT_VECTOR_FONT_FILENAME, WEATHER_ITEM_FONT_SIZE); + title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + title->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + title->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + title->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + + mainImg = new UIImageView(); + mainImg->SetPosition(0, 0); + mainImg->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + if (weatherModel->GetDayStatus()) { + LOADIMG::LoadImageViewImg(mainImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER64); + } else { + LOADIMG::LoadImageViewImg(mainImg, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER65); + } + InitScrollView(); + InitScrollData(); + AddViewToPageContainer(group); +} + +void WeatherPageThird::InitScrollView() +{ + contentList = new UIList(); + if (contentList == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::contentList is nullptr"); + return; + } + + contentList->SetPosition(WEATHER_LIST_POSITION_X, WEATHER_LIST_POSITION_Y); + contentList->Resize(WEATHER_LIST_WIDTH, WEATHER_LIST_HEIGHT); + contentList->SetSelectPosition(WEATHER_LIST_SELECT_POSITION); + contentList->SetDraggable(true); + contentList->SetThrowDrag(true); + contentList->EnableAutoAlign(true); + contentList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + contentList->SetElastic(true); + ImagePageKey = new UIImageView(); + if (ImagePageKey == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherPageFirst::ImagePageKey new image fail"); + return; + } + ImagePageKey->SetPosition(WEATHER_IMAGEPAGEKEY_X, WEATHER_IMAGEPAGEKEY_Y, WEATHER_IMAGEPAGEKEY_WIDTH, + WEATHER_IMAGEPAGEKEY_HEIGHT); + ImagePageKey->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + LOADIMG::LoadImageViewImg(ImagePageKey, WEATHER_IMAGE, IMAGE_CONVERTER_TOOL_WEATHER68); + group->Add(mainImg); + group->Add(title); + group->Add(contentList); + group->Add(ImagePageKey); +} + +bool WeatherPageThird::InitScrollData() +{ + const WeatherItem *itemInfo = weatherModel->GetWeatherlistItems(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::InitWeatherItem %s", itemInfo); + RefreshWeathersList(itemInfo, weatherModel->GetWeatherListNum()); + return true; +} + +void WeatherPageThird::RefreshWeathersList(const WeatherItem *item, uint8_t count) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::listAdapter"); + listAdapter = new WeatherAdapter(); + if (listAdapter == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::OnStart::listAdapter is nullptr"); + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::RefreshWeathersList"); + if (item == nullptr) { + return; + } else { + for (int i = 0; i < count; i++) { + listAdapter->AddListItem(item[i]); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::RefreshWeathersList %d", i); + } + } + if (contentList == nullptr) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WeatherView::contentList fail"); + return; + } + contentList->ScrollTo(0); + contentList->SetAdapter(listAdapter); +} + +bool WeatherPageThird::OnDrag(UIView &view, const DragEvent &event) +{ + UNUSED(view); + if ((event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > X_DRAG_OFFSET) && + (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) { + NativeAbility::GetInstance().SwitchPageInSlice(WEATHER_PAGES::WEATHER_SECOND_PAGE, nullptr, + TransitionType::TRANSITION_INVALID, true); + } + return false; +} + +void WeatherPageThird::OnSwipe(UISwipeView &view) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TempPresenter::OnSwipe "); + UNUSED(view); + return; +} + +bool WeatherPageThird::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + return true; +} +} \ No newline at end of file diff --git a/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPresenter.cpp b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPresenter.cpp new file mode 100644 index 000000000..c9438428f --- /dev/null +++ b/code/sdk/application/wearable/nativeapp/nativeui/weather/src/WeatherPresenter.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: WeatherPresenter + * Create: 2025-03-23 + */ + +#include "weather/WeatherView.h" +#include "weather/WeatherModel.h" +#include "weather/WeatherPresenter.h" +#include "uiservice/ui_service.h" +#include "NativeRegisterManager.h" +#include "wearable_log.h" + +namespace OHOS { + REGIST_MENU(VIEW_WEATHER, WeatherView, WeatherPresenter, WEATHER_MAIN_ICON, WEATHER_MAIN_ICON, "天气"); +} diff --git a/code/sdk/application/wearable/ohos_deps/CMakeLists.txt b/code/sdk/application/wearable/ohos_deps/CMakeLists.txt index 09de4d2b6..3f7de56c1 100644 --- a/code/sdk/application/wearable/ohos_deps/CMakeLists.txt +++ b/code/sdk/application/wearable/ohos_deps/CMakeLists.txt @@ -5,11 +5,13 @@ set(PUBLIC_HEADER ) set(PRIVATE_HEADER + ${ROOT_DIR}/application/wearable/service/device_msg ) set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/phony_timer.c ${CMAKE_CURRENT_SOURCE_DIR}/ohos_timer.c + ${CMAKE_CURRENT_SOURCE_DIR}/wearable_onlinelog.c ) set(COMPONENT_PUBLIC_CCFLAGS diff --git a/code/sdk/application/wearable/ohos_deps/wearable_log.h b/code/sdk/application/wearable/ohos_deps/wearable_log.h index d641846ad..9e67cac16 100644 --- a/code/sdk/application/wearable/ohos_deps/wearable_log.h +++ b/code/sdk/application/wearable/ohos_deps/wearable_log.h @@ -7,11 +7,6 @@ #ifndef WEARABLE_LOG_H #define WEARABLE_LOG_H -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif -#endif #if !defined(SW_UART_DEBUG) && !defined(SW_RTT_DEBUG) #include "soc_diag_util.h" @@ -20,6 +15,13 @@ extern "C" { #else #include "debug_print.h" #endif +#include "wearable_onlinelog.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /** * @brief Enumerates logging module types. @@ -44,11 +46,13 @@ typedef enum { WEARABLE_LOG_MODULE_SMART_VOICE, /* UI SERVICE */ WEARABLE_LOG_MODULE_UI_SERVICE, + /* msg_center */ + WEARABLE_LOG_MODULE_MSG_CENTER, WEARABLE_LOG_MODULE_MAX } WearableLogModuleType; -#if !defined(SW_UART_DEBUG) && !defined(SW_RTT_DEBUG) +#if !defined(SW_UART_DEBUG) && !defined(SW_RTT_DEBUG) && !defined(CONFIG_ONLINE_LOG) #define WEARABLE_LOGE(mod, fmt, arg...) uapi_diag_error_log(0, fmt, ##arg) #define WEARABLE_LOGW(mod, fmt, arg...) uapi_diag_warning_log(0, fmt, ##arg) #define WEARABLE_LOGI(mod, fmt, arg...) uapi_diag_info_log(0, fmt, ##arg) @@ -57,6 +61,15 @@ typedef enum { #else #define WEARABLE_LOGD(mod, fmt, arg...) #endif +#elif (CONFIG_ONLINE_LOG == 1) && !defined(_WIN32) +#define WEARABLE_LOGE(mod, fmt, arg...) ONLINE_PRINT(ONLINE_ERROR, fmt "\n", ##arg) +#define WEARABLE_LOGW(mod, fmt, arg...) ONLINE_PRINT(ONLINE_WARN, fmt "\n", ##arg) +#define WEARABLE_LOGI(mod, fmt, arg...) ONLINE_PRINT(ONLINE_INFO, fmt "\n", ##arg) +#ifdef WEARABLE_LOG_DEBUG +#define WEARABLE_LOGD(mod, fmt, arg...) ONLINE_PRINT(ONLINE_INFO, fmt "\n", ##arg) +#else +#define WEARABLE_LOGD(mod, fmt, arg...) +#endif #else #define WEARABLE_LOGE(mod, fmt, arg...) PRINT("[WEARABLE E/] " fmt "\n", ##arg) #define WEARABLE_LOGW(mod, fmt, arg...) PRINT("[WEARABLE W/] " fmt "\n", ##arg) @@ -68,36 +81,36 @@ typedef enum { #endif #endif -#define CHECK_NULL_AND_RETURN(pointer, mod, fmt) \ - do { \ - if ((pointer) == nullptr) { \ - WEARABLE_LOGE((mod), (fmt)); \ - return; \ - } \ +#define CHECK_NULL_AND_RETURN(pointer, mod, fmt) \ + do { \ + if ((pointer) == nullptr) { \ + WEARABLE_LOGE((mod), (fmt)); \ + return; \ + } \ } while (0) -#define CHECK_NULL_AND_RETURN_NULL(pointer, mod, fmt) \ - do { \ - if ((pointer) == nullptr) { \ - WEARABLE_LOGE((mod), (fmt)); \ - return nullptr; \ - } \ +#define CHECK_NULL_AND_RETURN_NULL(pointer, mod, fmt) \ + do { \ + if ((pointer) == nullptr) { \ + WEARABLE_LOGE((mod), (fmt)); \ + return nullptr; \ + } \ } while (0) #define CHECK_NULL_AND_RETURN_CODE(pointer, mod, fmt, code) \ - do { \ - if ((pointer) == nullptr) { \ - WEARABLE_LOGE((mod), (fmt)); \ + do { \ + if ((pointer) == nullptr) { \ + WEARABLE_LOGE((mod), (fmt)); \ return (code); \ - } \ + } \ } while (0) -#define DELETE_IF_NOT_NULL(pointer) \ - do { \ - if ((pointer) != nullptr) { \ - delete (pointer); \ - (pointer) = nullptr; \ - } \ +#define DELETE_IF_NOT_NULL(pointer) \ + do { \ + if ((pointer) != nullptr) { \ + delete (pointer); \ + (pointer) = nullptr; \ + } \ } while (0) #ifdef __cplusplus diff --git a/code/sdk/application/wearable/ohos_deps/wearable_onlinelog.c b/code/sdk/application/wearable/ohos_deps/wearable_onlinelog.c new file mode 100644 index 000000000..8cb72c40e --- /dev/null +++ b/code/sdk/application/wearable/ohos_deps/wearable_onlinelog.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. + * Description: wearable_onlinelog src fie. + * Author: CompanyName + * Create: + */ +#include "wearable_log.h" +#include "securec.h" +#include "diag_ind_src.h" +#include "diag_service.h" +#include "diag_common.h" +#include "msg_center_protocol.h" +#include "msg_center_device.h" +#if defined(SW_UART_DEBUG) +#include "uart.h" +#endif + +#if (CONFIG_ONLINE_LOG == 1) && !defined(_WIN32) +#define TL_BYTE1 1 +#define TL_BYTE2 2 +#define SHIFT_8_BIT 8 + +#define SET_UART_CHANNEL_CMD 1 +#define SET_BR_CHANNEL_CMD 2 +#define SET_BLE_CHANNEL_CMD 3 + +static uint8_t g_log_diag_channel = DIAG_FRAME_FID_PC; + +// 在线日志级别对应的字符串 +static const char *gLevelStrings[] = {"[WEARABLE D/] ", "[WEARABLE I/] ", "[WEARABLE W/] ", "[WEARABLE E/] "}; +// 在线日志过滤器; +static uint8_t gOnlineLevelFilter = 0xf; + +errcode_t uapi_diag_service_send_log(uint8_t channel, uint8_t type, uint8_t *payload, uint32_t pay_len); + +static uint8_t calculate_tl_byte(uint32_t payloadLen) +{ + uint8_t tl_byte = 0; + if (payloadLen <= 0x7f) { + tl_byte = 0; + } else if (payloadLen > 0xff) { + tl_byte = TL_BYTE2; + } else { + tl_byte = TL_BYTE1; + } + return tl_byte; +} + +void set_online_log_level(uint8_t filter) +{ + gOnlineLevelFilter = filter; +} + +static void send_uart_str(const char *s, uint32_t str_len) +{ +#if defined(SW_UART_DEBUG) + if (hal_uart_get_funcs(SW_DEBUG_UART_BUS) == NULL) { + return; + } + uapi_uart_write(SW_DEBUG_UART_BUS, (const void *)s, str_len, 0); +#endif +} + +void change_log_diag_channel(uint8_t channel) +{ + if (channel == SET_UART_CHANNEL_CMD) { + g_log_diag_channel = DIAG_FRAME_FID_PC; + } else if (channel == SET_BR_CHANNEL_CMD) { + g_log_diag_channel = DIAG_FRAME_FID_PHONE; + } else if (channel == SET_BLE_CHANNEL_CMD) { + g_log_diag_channel = DIAG_FRAME_FID_BT; + } else { + g_log_diag_channel = DIAG_FRAME_FID_PC; + } +} + +uint8_t get_log_diag_channel() +{ + return g_log_diag_channel; +} + +void online_print_str(uint16_t level, const char *str, ...) +{ + static uint8_t buffer[1024]; + uint8_t filter = (1 << level) & gOnlineLevelFilter; + if (!filter) { + return; + } + int offset = sprintf_s((char *)buffer, sizeof(buffer), "%s", gLevelStrings[level]); + if (offset < 0 || (size_t)offset >= sizeof(buffer)) { + return; + } + va_list args; + va_start(args, str); + offset += vsprintf_s((char *)(buffer + offset), sizeof(buffer) - offset, str, args); + if (offset < 0 || (size_t)offset >= sizeof(buffer)) { + va_end(args); + return; + } + va_end(args); + uint8_t channel = get_log_diag_channel(); + if (channel == DIAG_FRAME_FID_PC) { + send_uart_str((const char *)buffer, offset); + } else { + uapi_diag_service_send_log(channel, MSGCENTER_TYPE_ID_ONLINELOG_REPORT, buffer, offset); + } +} + +errcode_t uapi_diag_service_send_log(uint8_t channel, uint8_t type, uint8_t *payload, uint32_t pay_len) +{ + uint8_t size; + diag_ser_data_t *diag_data; + diag_ser_frame_t *frame; + uint32_t result = ERRCODE_FAIL; + // 计算tl的长度及填充tl数据; + uint8_t tl_byte = calculate_tl_byte(pay_len); + uint32_t tl_len = sizeof(msg_center_pkt_tlv_t) + tl_byte; + uint8_t tl_data[4]; + msg_center_pkt_tlv_t *tl = (msg_center_pkt_tlv_t *)tl_data; + tl->type = 0x80 | type; + if (tl_byte == TL_BYTE1) { + tl->len = tl_byte; + tl->data[0] = (uint8_t)pay_len; + } else if (tl_byte == TL_BYTE2) { + tl->len = tl_byte; + tl->data[0] = (uint16_t)pay_len & 0xff; + tl->data[1] = (uint16_t)pay_len >> SHIFT_8_BIT; + } else { + tl->len = 0x80 | (uint8_t)pay_len; + } + + size = sizeof(diag_ser_data_t) + sizeof(diag_ser_frame_t) + pay_len + tl_len; + diag_data = (diag_ser_data_t *)malloc(size); + if (diag_data == NULL) { + return ERRCODE_FAIL; + } + + diag_data->header.ser_id = DIAG_SER_MSG_CENTER; + diag_data->header.cmd_id = MSGCENTER_CMD_DEVICE; + diag_data->header.ack_en = false; + diag_data->header.src = DIAG_FRAME_FID_MCU; + diag_data->header.dst = channel; + diag_data->header.crc_en = 1; + diag_data->header.length = size - sizeof(diag_ser_data_t); // size = modeleId + cmdId + tlv + + frame = (diag_ser_frame_t *)&(diag_data->payload); + frame->module_id = DIAG_SER_MSG_CENTER; + frame->cmd_id = MSGCENTER_CMD_DEVICE; + (void)memcpy_s(&(frame->tlv), tl_len, tl, tl_len); + (void)memcpy_s(&(frame->tlv[tl_len]), pay_len, payload, pay_len); + result = uapi_diag_service_send_data(diag_data); + free(diag_data); + return result; +} +#endif diff --git a/code/sdk/application/wearable/ohos_deps/wearable_onlinelog.h b/code/sdk/application/wearable/ohos_deps/wearable_onlinelog.h new file mode 100644 index 000000000..9ed85ed06 --- /dev/null +++ b/code/sdk/application/wearable/ohos_deps/wearable_onlinelog.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved. + * Description: Wearable onlinelog header file. + * Author: + * Create: + */ + +#ifndef WEARABLE_ONLINELOG_H +#define WEARABLE_ONLINELOG_H + +#include "stdint.h" +#include "errcode.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* 特性: 在线日志 */ +#ifndef CONFIG_ONLINE_LOG +#define CONFIG_ONLINE_LOG 1 +#endif + +enum OnLineLogLevel { + ONLINE_DEBUG = 0, + ONLINE_INFO, + ONLINE_WARN, + ONLINE_ERROR +}; + +void online_print_str(uint16_t level, const char *str, ...); +void change_log_diag_channel(uint8_t channel); +uint8_t get_log_diag_channel(void); +void set_online_log_level(uint8_t filter); +errcode_t uapi_diag_service_send_log(uint8_t channel, uint8_t type, uint8_t *payload, uint32_t pay_len); + +#ifndef ONLINE_PRINT +#define ONLINE_PRINT(level, fmt, arg...) online_print_str(level, fmt, ##arg) +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // WEARABLE_ONLINELOG_H \ No newline at end of file diff --git a/code/sdk/application/wearable/ohos_startup/CMakeLists.txt b/code/sdk/application/wearable/ohos_startup/CMakeLists.txt index 41c20067a..e68cca93f 100644 --- a/code/sdk/application/wearable/ohos_startup/CMakeLists.txt +++ b/code/sdk/application/wearable/ohos_startup/CMakeLists.txt @@ -14,6 +14,7 @@ set(PUBLIC_HEADER set(PRIVATE_HEADER ${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.6.0/ + ${ROOT_DIR}/application/wearable/service/device_msg/ ) set(PRIVATE_DEFINES diff --git a/code/sdk/application/wearable/ohos_startup/ohosfwk_startup.c b/code/sdk/application/wearable/ohos_startup/ohosfwk_startup.c index 6b2fb6821..d1f181e8d 100644 --- a/code/sdk/application/wearable/ohos_startup/ohosfwk_startup.c +++ b/code/sdk/application/wearable/ohos_startup/ohosfwk_startup.c @@ -97,6 +97,10 @@ boot_animation_init_deinit(); if (upg_check_upgrade_need_upgrade()) return ; #endif OHOS_SystemInit(); + +#ifdef PUBLISH_TEST_DATA + PublishTestData(); +#endif #ifdef SUPPORT_POWER_MANAGER const power_display_svr_api_t *display_api = power_display_svr_get_api(); diff --git a/code/sdk/application/wearable/service/CMakeLists.txt b/code/sdk/application/wearable/service/CMakeLists.txt index 7b1691bee..1137e9b93 100644 --- a/code/sdk/application/wearable/service/CMakeLists.txt +++ b/code/sdk/application/wearable/service/CMakeLists.txt @@ -8,6 +8,8 @@ add_subdirectory_if_exist(xiaodu_navi) add_subdirectory_if_exist(xiaodu_voice) add_subdirectory_if_exist(xiaodu_navi_vector) add_subdirectory_if_exist(hc_demo_msg) +add_subdirectory_if_exist(device_msg) +add_subdirectory_if_exist(remote_msg) add_subdirectory_if_exist(auto_ota_msg) add_subdirectory_if_exist(alipay_msg) add_subdirectory_if_exist(app_store) diff --git a/code/sdk/application/wearable/service/app_store/CMakeLists.txt b/code/sdk/application/wearable/service/app_store/CMakeLists.txt index e679c5341..5cfeb9a55 100644 --- a/code/sdk/application/wearable/service/app_store/CMakeLists.txt +++ b/code/sdk/application/wearable/service/app_store/CMakeLists.txt @@ -8,7 +8,6 @@ set(PRIVATE_HEADER ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/uiservice/include ) set(SOURCES diff --git a/code/sdk/application/wearable/service/app_store/app_store.cpp b/code/sdk/application/wearable/service/app_store/app_store.cpp index 8c6efbeb1..f7cc6c66d 100644 --- a/code/sdk/application/wearable/service/app_store/app_store.cpp +++ b/code/sdk/application/wearable/service/app_store/app_store.cpp @@ -8,7 +8,7 @@ #include "bundle_install_msg.h" #include "bundlems_slite_client.h" #include "appexecfwk_errors.h" -#include "ui_service.h" +#include "uiservice/ui_service.h" void AppStoreReplyAck(uint8_t cmd_id, uint8_t type, uint32_t ack) { @@ -112,7 +112,13 @@ errcode_t AppStoreGetPkgList(uint8_t cmd_id, uint8_t type, void *usr_data, uint1 for (int32_t i = 0; i < count; i++) { (void)strncpy_s((char*)unitInfo[i].pkgName, PKG_NAME_MAX_LENGTH, bundleInfos[i].bundleName, strlen(bundleInfos[i].bundleName)); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppStoreGetPkgList pkgName[%d] = %s", i, unitInfo[i].pkgName); + (void)strncpy_s((char*)unitInfo[i].versionName, VERSION_NAME_MAX_LENGTH, + bundleInfos[i].versionName, strlen(bundleInfos[i].versionName)); + (void)strncpy_s((char*)unitInfo[i].labelName, LABEL_NAME_MAX_LENGTH, + bundleInfos[i].label, strlen(bundleInfos[i].label)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppStoreGetPkgList pkgName[%d] = %s, versionName[%d] = %s,\ + labeName[%d] = %s", i, unitInfo[i].pkgName, i, unitInfo[i].versionName, i, + unitInfo[i].labelName); unitInfo[i].versionCode = bundleInfos[i].versionCode; } ret = msg_center_send_data(MSGCENTER_CMD_APP_STORE, type, infoList, len); @@ -127,3 +133,40 @@ errcode_t AppStoreGetPkgList(uint8_t cmd_id, uint8_t type, void *usr_data, uint1 } return ret; } + +errcode_t AppStoreGetBundleInfo(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + BundleInfo bundleInfo; + int32_t ret = ERRCODE_FAIL; + + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + char *bundleName = (char *)malloc(payload_len + 1); + (void)memcpy_s(bundleName, payload_len, tlv_payload, payload_len); + bundleName[payload_len] = '\0'; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bundleName = %s", bundleName); + + uint8_t bundleRet = OHOS::BundleMsClient::GetInstance().GetBundleInfo(bundleName, 0, &bundleInfo); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "get bundleInfo, ret = %d", bundleRet); + + int32_t len = sizeof(PkgUnitInfo); + PkgUnitInfo *info = (PkgUnitInfo *)malloc(len); + if (info != nullptr) { + memset_s(info, len, 0, len); + (void)strncpy_s((char*)info->pkgName, PKG_NAME_MAX_LENGTH, bundleInfo.bundleName, + strlen(bundleInfo.bundleName)); + (void)strncpy_s((char*)info->versionName, VERSION_NAME_MAX_LENGTH, bundleInfo.versionName, + strlen(bundleInfo.versionName)); + (void)strncpy_s((char*)info->labelName, LABEL_NAME_MAX_LENGTH, bundleInfo.label, strlen(bundleInfo.label)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppStoreGetBundleInfo pkgName = %s, versionName = %s, labeName = %s", + info->pkgName, info->versionName, info->labelName); + info->versionCode = bundleInfo.versionCode; + ret = msg_center_send_data(cmd_id, type, info, len); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "AppStoreGetBundleInfo send data ret = 0x%x", ret); + free(info); + free(bundleName); + } + + return ret; +} \ No newline at end of file diff --git a/code/sdk/application/wearable/service/app_store/app_store.h b/code/sdk/application/wearable/service/app_store/app_store.h index 7bbc93b96..375740141 100644 --- a/code/sdk/application/wearable/service/app_store/app_store.h +++ b/code/sdk/application/wearable/service/app_store/app_store.h @@ -18,6 +18,8 @@ extern "C" { #endif #define PKG_NAME_MAX_LENGTH 128 +#define VERSION_NAME_MAX_LENGTH 128 +#define LABEL_NAME_MAX_LENGTH 256 #define FS_DIR_APP_STORE "/user/app_store/" typedef enum { @@ -29,6 +31,7 @@ typedef enum { APP_STORE_OPERATION = 0x01, APP_STORE_NOTIFY_PROGRESS = 0x02, APP_STORE_GET_PKG_LIST = 0x03, + APP_STORE_GET_BUNDLEINFO = 0x04, } AppStoreType; typedef enum { @@ -60,10 +63,13 @@ typedef struct { typedef struct { uint8_t pkgName[PKG_NAME_MAX_LENGTH]; int32_t versionCode; + uint8_t versionName[VERSION_NAME_MAX_LENGTH]; + uint8_t labelName[LABEL_NAME_MAX_LENGTH]; } PkgUnitInfo; errcode_t AppStorePkgOperation(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); errcode_t AppStoreGetPkgList(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t AppStoreGetBundleInfo(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); #ifdef __cplusplus #if __cplusplus diff --git a/code/sdk/application/wearable/service/app_store/app_store_msg.cpp b/code/sdk/application/wearable/service/app_store/app_store_msg.cpp index f34d838d8..d2f1f1a08 100644 --- a/code/sdk/application/wearable/service/app_store/app_store_msg.cpp +++ b/code/sdk/application/wearable/service/app_store/app_store_msg.cpp @@ -10,6 +10,7 @@ extern "C" { static const msg_center_cmd_map_t g_appStoreTbl[] = { { MSGCENTER_CMD_APP_STORE, APP_STORE_OPERATION, AppStorePkgOperation }, { MSGCENTER_CMD_APP_STORE, APP_STORE_GET_PKG_LIST, AppStoreGetPkgList }, + { MSGCENTER_CMD_APP_STORE, APP_STORE_GET_BUNDLEINFO, AppStoreGetBundleInfo }, }; errcode_t AppStoreTypeDispatch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) diff --git a/code/sdk/application/wearable/service/broadcast/include/broadcast_feature.h b/code/sdk/application/wearable/service/broadcast/include/broadcast_feature.h index 54854380c..8359e67ba 100644 --- a/code/sdk/application/wearable/service/broadcast/include/broadcast_feature.h +++ b/code/sdk/application/wearable/service/broadcast/include/broadcast_feature.h @@ -43,7 +43,9 @@ typedef enum { TOPIC_EVENT_HFP_FINISHED, TOPIC_EVENT_HFP_PHONE_TO_WATCH, TOPIC_EVENT_HFP_WATCH_TO_PHONE, - + TOPIC_EVENT_BLOODOXYGEN_UPDATA, + TOPIC_EVENT_SPORT_DISTANCE, + TOPIC_EVENT_LOCATION, TOPIC_END_NUM = 20000, } TopicNum; diff --git a/code/sdk/application/wearable/service/broadcast/src/broadcast_implement.c b/code/sdk/application/wearable/service/broadcast/src/broadcast_implement.c index 2560ff487..5fe38efd7 100644 --- a/code/sdk/application/wearable/service/broadcast/src/broadcast_implement.c +++ b/code/sdk/application/wearable/service/broadcast/src/broadcast_implement.c @@ -32,6 +32,9 @@ static const TopicToCore topicToCoreArray[] = { {TOPIC_EVENT_HFP_FINISHED, A_CORE_MASK, 1}, {TOPIC_EVENT_HFP_PHONE_TO_WATCH, A_CORE_MASK, 1}, {TOPIC_EVENT_HFP_WATCH_TO_PHONE, A_CORE_MASK, 1}, + {TOPIC_EVENT_BLOODOXYGEN_UPDATA, A_CORE_MASK, 1}, + {TOPIC_EVENT_SPORT_DISTANCE, A_CORE_MASK, 1}, + {TOPIC_EVENT_LOCATION, A_CORE_MASK, 1}, }; /* 所有的topic,其对应的位图 */ diff --git a/code/sdk/application/wearable/service/device_msg/CMakeLists.txt b/code/sdk/application/wearable/service/device_msg/CMakeLists.txt new file mode 100644 index 000000000..9ea557d33 --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/CMakeLists.txt @@ -0,0 +1,51 @@ +set(COMPONENT_NAME "device_msg") + +set(PUBLIC_HEADER +) + +set(PRIVATE_HEADER + ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits + ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits + ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include + ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits + ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits + ${ROOT_DIR}/middleware/services/media/foundation/audiomanager/interfaces/kits/audiomanager + ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks + ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits + ${ROOT_DIR}/middleware/chips/brandy/nv/include + ${ROOT_DIR}/middleware/chips/brandy/nv/nv_config + ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include + ${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include + ${ROOT_DIR}/middleware/utils/dfx/diag/ +) + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/device_msg.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/device_proxy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/msg_center_device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/device_location.cpp +) + +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -std=c++11 + -Wno-missing-field-initializers +) + +set(WHOLE_LINK + true +) + +set(PUBLIC_DEFINES +) + +set(PRIVATE_DEFINES + APP_PLATFORM_WATCHGT + CONFIG_ACELITE_ENABLE +) + +build_component() + + diff --git a/code/sdk/application/wearable/service/device_msg/device_location.cpp b/code/sdk/application/wearable/service/device_msg/device_location.cpp new file mode 100644 index 000000000..d24a14f75 --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/device_location.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +#include "device_location.h" +#include "wearable_log.h" +#include "locator.h" + +using namespace OHOS::Location; + +LocationInfo_t g_locationInfo = {0}; + +class GnssStatusCallback : public IGnssStatusCallback { +public: + GnssStatusCallback() {} + ~GnssStatusCallback() {} + + void OnStatusChange(const std::shared_ptr &statusInfo) override + { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnStatusChange, num:%d\n", statusInfo->GetSatellitesNumber()); + for (int32_t satIdx = 0; satIdx < statusInfo->GetSatellitesNumber(); satIdx++) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "sat index:%d svid:%d ele:%.3f az:%.3f cnr:%.3f \n", satIdx, + statusInfo->GetSatelliteIds()[satIdx], statusInfo->GetAltitudes()[satIdx], + statusInfo->GetAzimuths()[satIdx], statusInfo->GetCarrierToNoiseDensitys()[satIdx]); + } + } + +private: +}; + +class NmeaMessageCallback : public INmeaMessageCallback { +public: + NmeaMessageCallback() {} + ~NmeaMessageCallback() {} + + void OnMessageChange(int64_t timestamp, const std::string msg) override + { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnMessageChange timestamp :%lld msg:%s\n", timestamp, msg.c_str()); + } + +private: +}; + +class LocatorCallback : public ILocatorCallback { +public: + LocatorCallback() {} + + ~LocatorCallback() {} + + void OnLocationReport(const std::shared_ptr &location) override + { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnLocationReport Lat:%.3f Long:%.3f Alt:%.3f Speed:%.3f dir:%.3f\n", + location->GetLatitude(), location->GetLongitude(), location->GetAltitude(), location->GetSpeed(), + location->GetDirection()); + } + + void OnErrorReport(const int errorCode) override + { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "error code:%d\n", errorCode); + } + + void OnLocatingStatusChange(const int status) override + { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnLocatingStatusChange status:%d\n", status); + } + +private: +}; + +typedef struct { + Locator *locator; + bool isStarted; + LocatorCallback locatorCallback; + GnssStatusCallback gnssStatusCallback; + NmeaMessageCallback nmeaMessageCallback; +} LocationSampleContext; + +static LocationSampleContext g_locationContext = { + .locator = nullptr, + .isStarted = false, +}; + +int32_t deviceLocationStartLocating() +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "LocationStartLocating\n"); + if (g_locationContext.locator == nullptr) { + g_locationContext.locator = &Locator::GetInstance(); + } + if (g_locationContext.locator == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator is nullptr\n"); + return ERRCODE_FAILURE; + } + + bool isEnabled = false; + LocationErrCode errCode = g_locationContext.locator->IsLocationEnabled(isEnabled); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator IsLocationEnabled failed:%d\n", errCode); + return errCode; + } + + if (!isEnabled) { + errCode = g_locationContext.locator->EnableAbility(true); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator EnableAbility failed:%d\n", errCode); + return errCode; + } + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "RegisterGnssStatusCallback\n"); + errCode = g_locationContext.locator->RegisterGnssStatusCallback(&g_locationContext.gnssStatusCallback); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator RegisterGnssStatusCallback failed:%d\n", errCode); + return errCode; + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "RegisterNmeaMessageCallback\n"); + errCode = g_locationContext.locator->RegisterNmeaMessageCallback(&g_locationContext.nmeaMessageCallback); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator RegisterNmeaMessageCallback failed:%d\n", errCode); + return errCode; + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "StartLocating\n"); + RequestConfig requestConfig; + requestConfig.SetPriority(PRIORITY_ACCURACY); + errCode = g_locationContext.locator->StartLocating(&requestConfig, &g_locationContext.locatorCallback); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator StartLocating failed:%d\n", errCode); + return errCode; + } + g_locationContext.isStarted = true; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "StartLocating end\n"); + return ERRCODE_SUCCESS; +} + +int32_t deviceLocationStopLocating() +{ + if (!g_locationContext.isStarted) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator is not started\n"); + return ERRCODE_FAILURE; + } + LocationErrCode errCode = + g_locationContext.locator->UnregisterNmeaMessageCallback(&g_locationContext.nmeaMessageCallback); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator UnregisterNmeaMessageCallback failed:%d\n", errCode); + return errCode; + } + errCode = g_locationContext.locator->UnregisterGnssStatusCallback(&g_locationContext.gnssStatusCallback); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator RegisterGnssStatusCallback failed:%d\n", errCode); + return errCode; + } + errCode = g_locationContext.locator->StopLocating(&g_locationContext.locatorCallback); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator StopLocating failed:%d\n", errCode); + return errCode; + } + g_locationContext.isStarted = false; + + bool isEnabled = false; + errCode = g_locationContext.locator->IsLocationEnabled(isEnabled); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator IsLocationEnabled failed:%d\n", errCode); + return errCode; + } + if (!isEnabled) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator Is not Enabled\n"); + return ERRCODE_FAILURE; + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "EnableAbility false\n"); + errCode = g_locationContext.locator->EnableAbility(false); + if (errCode != ERRCODE_SUCCESS) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "locator EnableAbility failed:%d\n", errCode); + return errCode; + } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Disable end\n"); + return ERRCODE_SUCCESS; +} \ No newline at end of file diff --git a/code/sdk/application/wearable/service/device_msg/device_location.h b/code/sdk/application/wearable/service/device_msg/device_location.h new file mode 100644 index 000000000..3305d698c --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/device_location.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ +#ifndef DEVICE_LOCATION_H +#define DEVICE_LOCATION_H +#include + +typedef struct LocationInfo { + int32_t latitude_; + int32_t longitude_; + uint16_t altitude_; + uint16_t accuracy_; + uint16_t speed_; + uint16_t direction_; + int64_t timeStamp_; +} LocationInfo_t; + +int32_t deviceLocationStartLocating(); +int32_t deviceLocationStopLocating(); +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/service/device_msg/device_msg.cpp b/code/sdk/application/wearable/service/device_msg/device_msg.cpp new file mode 100644 index 000000000..3f54b45ab --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/device_msg.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#include "msg_center_protocol.h" +#include "msg_center_cmd.h" +#include "ohos_init.h" +#include "msg_center_device.h" +#ifdef PUBLISH_TEST_DATA +#include +#include +#include "graphic_timer.h" +#include "broadcast_feature.h" +#include "ohos_timer.h" +#include "heartrate/HeartModel.h" +#include "device_location.h" +#endif +namespace OHOS { + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef PUBLISH_TEST_DATA +#define BLOODOXYGEN_LOWER 90 +#define BLOODOXYGEN_RANGE 10 +#define STEP_RANGE 5 +#define DISTANCE_RANGE 10 +#define HEARTRATE_LOWER 60 +#define HEARTRATE_RANGE 60 +static uint8_t g_rotation_publish = 0; +static GraphicTimer *g_publishTestDataHandle = nullptr; +enum publishDataType { + PUBLISH_SETP = 0, + PUBLISH_DISTANCE, + PUBLISH_HEARTRATE, + PUBLISH_BLOODOXYGEN, + PUBLISH_TYPE_MAX +}; + +static void PublishTopicTestDataEvent(uint16_t topic, const void *data, size_t len) +{ + int32_t ret; + uint16_t size = len; + BroadcastApi *broadcastApi = nullptr; + IUnknown *api = nullptr; + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PublishTopicTestDataEvent topic=%u!!", topic); + + void *publishData = malloc(size); + if (publishData == nullptr) { + return; + } + ret = memcpy_s(publishData, size, data, size); + if (ret != EOK) { + free(publishData); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PublishTopicTestDataEvent memcpy_s fail! ret = %d", ret); + return; + } + + Request request = { + .msgId = topic, + .len = size, + .msgValue = 0, + .data = publishData, + }; + + /* public request */ + api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME); + if (api == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetFeatureApi failed"); + free(publishData); + return; + } + ret = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi); + if (ret != 0 || broadcastApi == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "QueryInterface failed"); + free(publishData); + return; + } + broadcastApi->PublishTopic((IUnknown *)broadcastApi, &request); + broadcastApi->Release((IUnknown *)broadcastApi); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PublishTopicTestDataEvent end!!"); + + return; +} + +static void PublishTestDataCallback(void *) +{ + switch (g_rotation_publish++ % PUBLISH_TYPE_MAX) { + case PUBLISH_BLOODOXYGEN: { + uint8_t blood_oxygen = BLOODOXYGEN_LOWER + rand() % BLOODOXYGEN_RANGE; + PublishTopicTestDataEvent(TOPIC_EVENT_BLOODOXYGEN_UPDATA, &blood_oxygen, sizeof(uint8_t)); + break; + } + case PUBLISH_SETP: { + uint32_t step = rand() % STEP_RANGE; + PublishTopicTestDataEvent(TOPIC_EVENT_STEPDATA_UPDATE, &step, sizeof(uint32_t)); + break; + } + case PUBLISH_HEARTRATE: { + HeartDatas heart_data = {0}; + heart_data.perSec = HEARTRATE_LOWER + rand() % HEARTRATE_RANGE; + PublishTopicTestDataEvent(TOPIC_EVENT_HEARTRATE_UPDATA, &heart_data, sizeof(HeartDatas)); + break; + } + case PUBLISH_DISTANCE: { + uint32_t distance = rand() % DISTANCE_RANGE; + PublishTopicTestDataEvent(TOPIC_EVENT_SPORT_DISTANCE, &distance, sizeof(uint32_t)); + break; + } + default: + break; + } +} + +void PublishTestData() +{ + uint32 tick = GetOSTick(5000); // 5秒发布一次测试数据 + if (g_publishTestDataHandle == nullptr) { + g_publishTestDataHandle = new GraphicTimer(tick, PublishTestDataCallback, nullptr, true); + } + if (g_publishTestDataHandle == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PublishTestData new GraphicTimer failed!!"); + return; + } + bool retTimer = g_publishTestDataHandle->Start(); + if (!retTimer) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PublishTestData Start failed!!"); + if (g_publishTestDataHandle != nullptr) { + delete g_publishTestDataHandle; + g_publishTestDataHandle = nullptr; + } + return; + } +} +#endif +static const msg_center_cmd_map_t g_msg_center_device_tbl[] = { + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_GET_BATTERY_LEVEL, msg_center_get_battery_level}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_GET_STORAGE_INFO, msg_center_get_storage_info}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_GET_PRODUCT_INFO, msg_center_get_product_info}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_GET_LANGUAGE_ID, msg_center_get_language_id}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_GET_VOLUME_INFO, msg_center_get_volume_info}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SET_LANGUAGE_ID, msg_center_set_language_id}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SET_VOLUME_INFO, msg_center_set_volume_info}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_DEVICE_HEARTRATE, msg_center_device_heartrate}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_DEVICE_STEPDATA, msg_center_device_stepdata}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_DEVICE_BLOODOXYGEN, msg_center_device_bloodoxygen}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_OFFLINE_LOG_SWITCH, msg_center_offline_log_switch}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_LOCATION_GET_INFO, msg_center_location_get_info}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_LOCATION_START, msg_center_location_start}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_LOCATION_STOP, msg_center_location_stop}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SPORT_ACTION, msg_center_sport_action}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SPORT_GET_DATA, msg_center_sport_get_data}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SPORT_REPORT_DATA, msg_center_sport_report_data}, +#if (CONFIG_ONLINE_LOG == 1) + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SET_ONLINELOG_CHANNEL, msg_center_set_online_log_channel}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_SET_ONLINELOG_LEVEL, msg_center_set_online_log_level}, +#endif + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_OTA_INIT, msg_center_ota_init}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_OTA_UPDATE, msg_center_ota_update}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_OFF_FIND_PHONE, msg_center_device_findphone}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_CAMERA_WATCH_EXIT, msg_center_camera_exit}, + {MSGCENTER_CMD_DEVICE, MSGCENTER_TYPE_ID_CAMERA_CONNECT_PHONE_SUCCESS, msg_center_camera_online}, +}; + +errcode_t msg_center_device_type_dispatch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tbl_size = sizeof(g_msg_center_device_tbl) / sizeof(g_msg_center_device_tbl[0]); + uint8_t i; + for (i = 0; i < tbl_size; i++) { + msg_center_cmd_map_t *item = (msg_center_cmd_map_t *)&g_msg_center_device_tbl[i]; + if ((item->type == type) && (item->handler != NULL)) { + item->handler(cmd_id, type, usr_data, usr_len); + return ERRCODE_SUCC; + } + } + return ERRCODE_NOT_SUPPORT; +} + +void device_init(void) +{ + msg_center_register_cmd(MSGCENTER_CMD_DEVICE, msg_center_device_type_dispatch); +} + +APP_FEATURE_INIT_PRI(device_init, LAYER_INIT_LEVEL_4); +#ifdef __cplusplus +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/service/device_msg/device_proxy.cpp b/code/sdk/application/wearable/service/device_msg/device_proxy.cpp new file mode 100644 index 000000000..336cfd7ed --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/device_proxy.cpp @@ -0,0 +1,476 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#include +#include "device_proxy.h" +#include "wearable_log.h" +#include "common_def.h" +#include "cpp/audio_manager.h" +#include "uiservice/ui_service.h" +#include "ui_resource_string.h" +#include +#include +#include "key_id.h" +#include "common.h" +#include "nv.h" +#include "upg.h" +#include "upg_porting.h" + +namespace OHOS { +static constexpr const char *MOUNT_POINT[] = {"/system", "/user", "/update", "/music"}; +static constexpr const uint16_t language_protocol[] = {(uint8_t)(0x0u << 8) | LANGUAGE_ID_ZH, + (uint8_t)(0x1u << 8) | LANGUAGE_ID_ZH, + (uint8_t)(0x2u << 8) | LANGUAGE_ID_EN}; +static constexpr const uint8_t language_mask_bits = 8; +static constexpr const uint16_t language_key_mask = 0xFF00; +static constexpr const uint16_t language_val_mask = 0x00FF; + +static constexpr const uint8_t percentage_scale = 100; // 百分比换算基数 +static constexpr const uint8_t percentage_max = 100; +static constexpr const uint8_t percentage_min = 0; + +static constexpr const uint32_t adc_reference_ratio_numerator = 450U; // 18 * 1000 +static constexpr const uint32_t adc_reference_ratio_denominator = 1024U / 2U; // 40960 / (1000/18)/2U +static constexpr const uint32_t millivolt_per_volt = 1000U; + +static constexpr const uint32_t def_samples_to_keep = 10; +static constexpr const uint32_t def_samples_to_discard = 5; +static constexpr const uint32_t def_adc_max_range_mv = 380; +static constexpr const uint32_t def_adc_min_range_mv = 0; + +template +T clamp(const T &value, const T &min_val, const T &max_val) +{ + return (value < min_val) ? (min_val) : (value > max_val ? max_val : value); +} + +void device_proxy::get_storage_info(storage_info &info) +{ + memset_s(&info, sizeof(storage_info), 0, sizeof(storage_info)); + for (size_t i = 0; i < sizeof(MOUNT_POINT) / sizeof(MOUNT_POINT[0]); i++) { + struct statfs tmpStat = {0}; + if (statfs(MOUNT_POINT[i], &tmpStat) != 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "无法获取%s的挂载点信息,%s", MOUNT_POINT[i], strerror(errno)); + continue; + } + + uint32_t total = static_cast(tmpStat.f_blocks * tmpStat.f_bsize); + uint32_t used = static_cast((tmpStat.f_blocks - tmpStat.f_bfree) * tmpStat.f_bsize); + uint32_t free = static_cast(tmpStat.f_bfree * tmpStat.f_bsize); + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "挂载点%s信息, 总:%d(byte), 用:%d(byte), 剩:%d(byte)", + MOUNT_POINT[i], total, used, free); + info.total_size += total; + info.used_size += used; + info.free_size += free; + } +} +void device_proxy::get_language_id(uint8_t &id) +{ + sys_language_id_t lang_id = {0}; + uint16_t nvsize = 0; + + errcode_t ret = uapi_nv_read(NV_ID_SYS_LANGUAGE_ID, sizeof(sys_language_id_t), &nvsize, (uint8_t *)&lang_id); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "nv get language id error, ret=%u", ret); + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "language nvsize=%u id = %u", nvsize, lang_id.language_id); + + for (auto key : language_protocol) { + if (lang_id.language_id == (uint8_t)(key & language_val_mask)) { + id = (uint8_t)((key & language_key_mask) >> language_mask_bits); + return; + } + } + id = LANGUAGE_ID_ZH; +} +void device_proxy::set_language_id(uint8_t id) +{ + sys_language_id_t lang_id = {.language_id = LANGUAGE_ID_ZH}; + + for (auto key : language_protocol) { + if (id == (uint8_t)((key & language_key_mask) >> language_mask_bits)) { + lang_id.language_id = (uint8_t)(key & 0xFF); + } + } + + errcode_t ret = uapi_nv_write(NV_ID_SYS_LANGUAGE_ID, (uint8_t *)&lang_id, sizeof(sys_language_id_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "nv set language id error, ret=%u", ret); + return; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "set language id = %u", lang_id.language_id); + // 发送更新消息到uiservice + SendMsgToUIService(UI_UPDATE_LANGUAGE, 0, nullptr, 0); +} +void device_proxy::get_product_info(std::string &info_string) +{ + sys_product_info_t info = {0}; + uint16_t nvsize = 0; + info_string.clear(); + + errcode_t ret = uapi_nv_read(NV_ID_SYS_PRODUCT_INFO, sizeof(sys_product_info_t), &nvsize, (uint8_t *)&info); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "nv get product info error, ret=%u", ret); + return; + } + + if (nvsize < sizeof(sys_product_info_t) || info.size == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "invalid product info size: nvsize=%u, info.size=%u", nvsize, info.size); + return; + } + + info_string.assign((const char *)info.name, info.size); + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "product info: nvsize=%u, strlen=%zu, data=%.*s", nvsize, info_string.size(), + static_cast(info_string.size()), info_string.c_str()); +} +void device_proxy::get_volume_info(uint8_t vol_type, std::vector &vol_info) +{ + std::vector audio_types; + + if (vol_type == vol_type_all_idx || vol_type > vol_type_max_idx) { + for (uint8_t i = 0; i < vol_type_max_idx; i++) { + uint8_t max_perc = 0; + trans_type_to_audio_stream_type(i, audio_types); + for (auto types : audio_types) { // 每个类型也由多个音频类型组成, 取声音最大的 + int32_t vol = Audio::AudioManager::GetInstance().GetVolume(types); + int32_t max_vol = Audio::AudioManager::GetInstance().GetMaxVolume(types); + int32_t min_vol = Audio::AudioManager::GetInstance().GetMinVolume(types); + uint8_t perc = calc_vol_percentage(min_vol, max_vol, vol); + max_perc = max_perc > perc ? max_perc : perc; + } + volume_info info; + info.type = i; + info.perc = max_perc; + + vol_info.push_back(info); + } + } else { + uint8_t max_perc = 0; + trans_type_to_audio_stream_type(vol_type, audio_types); + for (auto types : audio_types) { // 每个类型也由多个音频类型组成, 取声音最大的 + int32_t vol = Audio::AudioManager::GetInstance().GetVolume(types); + int32_t max_vol = Audio::AudioManager::GetInstance().GetMaxVolume(types); + int32_t min_vol = Audio::AudioManager::GetInstance().GetMinVolume(types); + uint8_t perc = calc_vol_percentage(min_vol, max_vol, vol); + max_perc = max_perc > perc ? max_perc : perc; + } + volume_info info; + info.type = vol_type; + info.perc = max_perc; + + vol_info.push_back(info); + } +} +void device_proxy::set_volume_info(volume_info &vol_info) +{ + std::vector audio_types; + trans_type_to_audio_stream_type(vol_info.type, audio_types); + for (auto types : audio_types) { + int32_t max_vol = Audio::AudioManager::GetInstance().GetMaxVolume(types); + int32_t min_vol = Audio::AudioManager::GetInstance().GetMinVolume(types); + + int32_t vol = calc_vol_volume(min_vol, max_vol, vol_info.perc); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetVolume %08X, %d", types, vol); + Audio::AudioManager::GetInstance().SetVolume(types, vol); + } +} +OTA_ERR device_proxy::ota_init(ota_info &info) +{ + // 检查OTA的当前状态 + upg_status status = uapi_upg_get_status(); + if (status == UPG_STATUS_UPDATING) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTAInit:The update module is being upgraded."); + return OTA_ERR::OTA_ERR_STATUS_UPDATING; + } + // 清理并检查升级区空间大小 + delete_file_with_cleanup(upg_get_pkg_file_dir(), upg_get_pkg_file_path()); + uint32_t total_size = uapi_upg_get_storage_size(); + if (total_size == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTAInit:OTA check storage size error, total_size is 0"); + return OTA_ERR::OTA_ERR_INVAILD_STORAGE; + } + if (info.package_size >= total_size) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTAInit:check size error, total size:%u, need size:%u", total_size, + info.package_size); + return OTA_ERR::OTA_ERR_INSUFFICIENT_STORAGE_SPACE; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OTAInit:check succ"); + return OTA_ERR::OTA_SUCC; +} +OTA_ERR device_proxy::ota_update(ota_info &info) +{ + uint32_t total_size = 0; + do { + FILE *fp = fopen(upg_get_pkg_file_path(), "rb"); + if (fp == nullptr) { + break; + } + fseek(fp, 0L, SEEK_END); + total_size = ftell(fp); + fclose(fp); + } while (false); + if (total_size == 0) { + return OTA_ERR::OTA_ERR_INVAILD_STORAGE; + } + if (total_size != info.package_size) { + return OTA_ERR::OTA_ERR_PACKAGE_SIZE_ERROR; + } + return OTA_ERR::OTA_SUCC; +} + +void device_proxy::call_ui_ota_update() +{ + // 发送升级请求到uiservice + SendMsgToUIService(UI_OTA_UPDATE, 0, nullptr, 0); +} + +int device_proxy::delete_file_with_cleanup(const char *ppath, const char *path) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "path:%s, ppath:%s", path, ppath); + // 1. 删除文件 + if (unlink(path) == -1) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "unlink failed:%d", errno); + return 1; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "unlink succ"); + // 2. 打开父目录文件描述符 + int dir_fd = open(ppath, O_RDONLY); + if (dir_fd == -1) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "open parent dir failed:%d", errno); + return 1; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "open parent dir succ"); + // 3. 同步父目录元数据到磁盘 + if (fsync(dir_fd) == -1) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "fsync dir failed:%d", errno); + close(dir_fd); + return 1; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "fsync dir succ"); + close(dir_fd); + return 0; +} + +uint8_t device_proxy::calc_vol_percentage(int32_t min, int32_t max, int32_t curr) +{ + if (min >= max) { + return 0; + } + const int32_t clamped_curr = clamp(curr, min, max); + const int64_t range = static_cast(max) - min; + + const int64_t scaled_value = (static_cast(clamped_curr - min) * percentage_scale); + return static_cast(scaled_value / range); +} +int32_t device_proxy::calc_vol_volume(int32_t min, int32_t max, uint8_t percentage) +{ + if (min >= max) { + return min; + } + uint8_t clamped_percentage = clamp(percentage, percentage_min, percentage_max); + + double range = static_cast(max - min); + double percentage_ratio = static_cast(clamped_percentage) / 100.0; + int32_t curr = static_cast(min + range * percentage_ratio); + + return static_cast(clamp(curr, min, max)); +} +void device_proxy::trans_type_to_audio_stream_type(uint8_t type, std::vector &audio_types) +{ + audio_types.clear(); + switch (type) { + case vol_type_alarm: + audio_types.push_back(AUDIO_STREAM_ALARM); // 通用报警音 + audio_types.push_back(AUDIO_STREAM_ALARM_SYSTEM); // 设备报警 + audio_types.push_back(AUDIO_STREAM_ALARM_CLOCK); // 闹钟报警 + break; + case vol_type_ring: + audio_types.push_back(AUDIO_STREAM_RING); // 来电铃声 + break; + case vol_type_call: + audio_types.push_back(AUDIO_STREAM_VOICE_CALL); // 普通语音通话 + audio_types.push_back(AUDIO_STREAM_VOICE_CALL_VOIP); // 网络语音通话(如微信通话) + audio_types.push_back(AUDIO_STREAM_VOICE_CALL_BT_SCO); // 蓝牙语音通话 + audio_types.push_back(AUDIO_STREAM_VOICE_CALL_VOLTE); // 4G VOLTE 高清语音通话 + break; + case vol_type_assistant: + audio_types.push_back(AUDIO_STREAM_VOICE_ASSISTANT); // 语音助手(如 Siri、Google Assistant) + audio_types.push_back(AUDIO_STREAM_TTS); // 语音合成(如文本转语音) + break; + case vol_type_notification: + audio_types.push_back(AUDIO_STREAM_NOTIFICATION); // 通用提示音 + audio_types.push_back(AUDIO_STREAM_NOTIFICATION_SYSTEM); // 设备提示音(如蓝牙连接/断开、低电量提示) + audio_types.push_back(AUDIO_STREAM_NOTIFICATION_PROMPT); // 运动健康提示音(如运动完成提醒) + break; + case vol_type_music: + audio_types.push_back(AUDIO_STREAM_MUSIC); // 本地音乐播放。 + audio_types.push_back(AUDIO_STREAM_A2DP_MUSIC); // 蓝牙传输的媒体音(如从手机传输到蓝牙耳机的音乐)。 + break; + case vol_type_video: + audio_types.push_back(AUDIO_STREAM_FITNESS_VIDEO); // 健身视频的指导音频。 + break; + } +} + +uint8_t battery_power::get_battery_percentage() +{ + battery_power *inst = get_instance(); + if (inst == nullptr) { + return 0; + } + uint32_t voltage = 0; + // 从adc获取电压值 + if (inst->adc_context_startup()) { + voltage = inst->calc_voltage(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "calc_voltage:%u", voltage); + } + inst->adc_context_shutdown(); + // 根据电压值计算电量百分比 + return inst->calc_percentage(voltage); +} + +battery_power *battery_power::get_instance() +{ + static battery_power *instance = nullptr; + if (instance == nullptr) { + battery_power *temp = new battery_power(); + if (!temp->adc_context_init()) { + delete temp; + return nullptr; + } + instance = temp; + } + return instance; +} + +battery_power::battery_power() +{ + // 数据由海思提供 + channel = ADC_CHANNEL_3; + analog_pin = S_AGPIO_L27; + mode = PIN_MODE_0; + samples_to_keep = def_samples_to_keep; + samples_to_discard = def_samples_to_discard; + // 由测试检测而来, 测试中得到的数据应该是0.3744V(没有标注单位,猜测得到,未必准确) + // 因为要算百分比, 换算成毫伏更容易计算 + adc_max_range_mv = def_adc_max_range_mv; + adc_min_range_mv = def_adc_min_range_mv; +} + +battery_power::~battery_power() +{ + adc_context_shutdown(); +} + +bool battery_power::adc_context_init() +{ + // 初始化pin模块 + uapi_pin_init(); + // 初始化高精度计数器 + errcode_t err = uapi_tcxo_init(); + if (err != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_tcxo_init error %u", err); + return false; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_tcxo_init succ"); + // 设置pin脚模式 + err = uapi_pin_set_mode(analog_pin, mode); + if (err != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_pin_set_mode error %u", err); + return false; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_pin_set_mode succ"); + return true; +} + +bool battery_power::adc_context_startup() +{ + errcode_t err = uapi_adc_init(ADC_CLOCK_500KHZ); // 初始化adc + if (err != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_init error %u", err); + return false; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_init succ"); + uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_power_en true"); + err = uapi_adc_open_channel(channel); + if (err != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_open_channel error %u", err); + return false; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_open_channel succ"); + return true; +} +void battery_power::adc_context_shutdown() +{ + errcode_t err = uapi_adc_close_channel(channel); + if (err != ERRCODE_SUCC) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_close_channel error %u", err); + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_close_channel succ"); + uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, false); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_power_en false"); + uapi_adc_deinit(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uapi_adc_deinit"); +} + +uint8_t battery_power::calc_percentage(uint32_t voltage) +{ + if (voltage >= adc_max_range_mv) { + return percentage_max; + } + if (voltage <= adc_min_range_mv) { + return percentage_min; + } + + uint32_t voltage_range = adc_max_range_mv - adc_min_range_mv; + uint32_t rounding_term = voltage_range / 2; + uint32_t voltage_offset = voltage - adc_min_range_mv; + return static_cast((voltage_offset * percentage_scale + rounding_term) / voltage_range); +} + +uint32_t battery_power::calc_voltage() +{ + // 丢弃初始帧数据 + for (uint32_t i = 0; i < samples_to_discard; i++) { + uapi_adc_manual_sample(ADC_CHANNEL_NONE); + uapi_tcxo_delay_ms((uint64_t)3); // 延迟3ms + } + + uint32_t stick = 0; + uint32_t stick_count = 0; + // 采集样本数 + for (uint32_t i = 0; i < samples_to_keep; i++) { + uint32_t irq_sts = osal_irq_lock(); + uint32_t sample_result = + (uint32_t)uapi_adc_manual_sample(ADC_CHANNEL_NONE); // 每次读取CHANNEL_NONE? testsuit中是这样写的 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sample result = %u", sample_result); + if (sample_result != 0) { + stick += sample_result; + stick_count++; + } + osal_irq_restore(irq_sts); + } + + if (stick_count == 0) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "error, no result"); + return 0; + } + + uint32_t voltage = adc_trans_sytick_to_voltages(stick / stick_count); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "adc trans voltages:%u", voltage); + return voltage; +} + +uint32_t battery_power::adc_trans_sytick_to_voltages(uint32_t sytick) +{ + // 整数运算公式:(sytick * numerator + denominator/2) / denominator + return (sytick * adc_reference_ratio_numerator + adc_reference_ratio_denominator) / adc_reference_ratio_denominator; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/service/device_msg/device_proxy.h b/code/sdk/application/wearable/service/device_msg/device_proxy.h new file mode 100644 index 000000000..7cedf8061 --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/device_proxy.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#ifndef WATCH_SETTING_PROXY_H +#define WATCH_SETTING_PROXY_H + +#include +#include +#include "msg_center_protocol.h" +#include "cpp/audio_manager.h" +#include "adc.h" +#include "tcxo.h" +#include "pinctrl.h" +#include "hal_adc.h" + +namespace OHOS { + +typedef struct storage_info { + uint32_t total_size; // 总大小 + uint32_t used_size; // 已使用 + uint32_t free_size; // 未使用 +} storage_info_t; + +typedef struct volume_info { + uint8_t type; // 类型 + uint8_t perc; // 百分比 +} volume_info_t; + +typedef struct ota_info { + uint32_t package_size; +} ota_info_t; + +enum class OTA_ERR : uint32_t { + OTA_SUCC = 0x00000000u, //"成功" + OTA_ERR_INVALID_PARAM = 0x00000001u, //"参数错误" + OTA_ERR_INITIALIZE_ERR = 0x00000002u, //"OTA初始化错误" + OTA_ERR_STATUS_UPDATING = 0x00000003u, //"OTA正在升级中" + OTA_ERR_INVAILD_STORAGE = 0x00000004u, //"获取升级区信息错误" + OTA_ERR_INSUFFICIENT_STORAGE_SPACE = 0x00000005u, //"升级区没有足够的空间" + OTA_ERR_PACKAGE_SIZE_ERROR = 0x00000006u, //"升级包大小不匹配" +}; + +static constexpr const uint8_t vol_type_all_idx = 0; +static constexpr const uint8_t vol_type_max_idx = 7; +static constexpr const uint8_t vol_type_alarm = 1; // 报警类 +static constexpr const uint8_t vol_type_ring = 2; // 来电铃声 +static constexpr const uint8_t vol_type_call = 3; // 语音通话 +static constexpr const uint8_t vol_type_assistant = 4; // 语音助手 +static constexpr const uint8_t vol_type_notification = 5; // 通用提示音 +static constexpr const uint8_t vol_type_music = 6; // 音乐 +static constexpr const uint8_t vol_type_video = 7; // 视频 + + +class device_proxy { +public: + static void get_storage_info(storage_info &info); + static void get_language_id(uint8_t &lang_id); + static void set_language_id(uint8_t lang_id); + static void get_product_info(std::string &info_string); + static void get_volume_info(uint8_t vol_type, std::vector &vol_info); + static void set_volume_info(volume_info &vol_info); + static OTA_ERR ota_init(ota_info &info); + static OTA_ERR ota_update(ota_info &info); + static void call_ui_ota_update(); +public: + static uint32_t calc_stat_size(uint64_t size); + static uint8_t calc_vol_percentage(int32_t min, int32_t max, int32_t curr); + static int32_t calc_vol_volume(int32_t min, int32_t max, uint8_t percentage); + static void trans_type_to_audio_stream_type(uint8_t type, std::vector &audio_types); + static int delete_file_with_cleanup(const char *ppath, const char *path); +}; + +class battery_power { +public: + static uint8_t get_battery_percentage(); + +protected: + static battery_power *get_instance(); + +private: + battery_power(); + ~battery_power(); + bool adc_context_init(); + bool adc_context_startup(); + void adc_context_shutdown(); + uint8_t calc_percentage(uint32_t voltage); + uint32_t calc_voltage(); + uint32_t adc_trans_sytick_to_voltages(uint32_t sytick); + +private: + adc_channel_t channel; // ADC信道 + pin_t analog_pin; // ADC输入引脚 + pin_mode_t mode; // ADC管脚工作模式 + uint32_t samples_to_keep; // 总采样次数 + uint32_t samples_to_discard; // 丢弃的初始样本数 + uint32_t adc_max_range_mv; // ADC原始值上限(单位:毫伏) + uint32_t adc_min_range_mv; // ADC原始值下限(单位:毫伏) +}; + +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/service/device_msg/msg_center_device.cpp b/code/sdk/application/wearable/service/device_msg/msg_center_device.cpp new file mode 100644 index 000000000..56f89c1a8 --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/msg_center_device.cpp @@ -0,0 +1,520 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#include "msg_center_protocol.h" +#include "msg_center_device.h" +#include "device_proxy.h" +#include "wearable_log.h" +#include "device_location.h" +#include "AppViewIDs.h" +#include "NativeAbility.h" +#include "sports/SportsModel.h" +#include "findphone/FindPhoneMainPage.h" +#include "camera/CameraMainPage.h" + +#ifdef __cplusplus +extern "C" { +#endif +#include "diag_msg.h" +#include "diag_ind_src.h" + +uint8_t g_bloodoxygen = 0; +uint16_t g_heartrate = 0; +uint32_t g_stepdata = 0; +uint32_t g_distance = 0; +extern LocationInfo_t g_locationInfo; +// 获取电量 +errcode_t msg_center_get_battery_level(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get_battery_level"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + + uint8_t battery_level = OHOS::battery_power::get_battery_percentage(); + + errcode_t ret = msg_center_send_data(cmd_id, type, &battery_level, sizeof(battery_level)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send get_battery_level_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// 获取存储空间 +errcode_t msg_center_get_storage_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get_storage_info"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + uint8_t battery_level = 0; + + OHOS::storage_info info; + OHOS::device_proxy::get_storage_info(info); + + errcode_t ret = msg_center_send_data(cmd_id, type, &info, sizeof(OHOS::storage_info)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send get_storage_info_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// 获取手表类型 +errcode_t msg_center_get_product_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get_product_info"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + uint8_t battery_level = 0; + + std::string product_info; + OHOS::device_proxy::get_product_info(product_info); + + errcode_t ret = msg_center_send_data(cmd_id, type, (void *)product_info.c_str(), product_info.length()); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send get_product_info_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// 获取语言 +errcode_t msg_center_get_language_id(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get_language_id"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + uint8_t battery_level = 0; + + uint8_t language_id = 0; + OHOS::device_proxy::get_language_id(language_id); + + errcode_t ret = msg_center_send_data(cmd_id, type, &language_id, sizeof(uint8_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send get_language_id_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// 获取音量 +errcode_t msg_center_get_volume_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get_volume_info"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + + uint8_t vol_type = 0; + if (v_len == sizeof(uint8_t)) { + vol_type = *(uint8_t *)v_data; + } + + std::vector vol_info; + OHOS::device_proxy::get_volume_info(vol_type, vol_info); + + errcode_t ret = msg_center_send_data(cmd_id, type, &vol_info[0], vol_info.size() * sizeof(OHOS::volume_info)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send get_volume_info_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// 设置语言 +errcode_t msg_center_set_language_id(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "set_language_id"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + + uint8_t language_id = 0; + if (v_len != sizeof(uint8_t)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "v_len check error, v_len=%u, need=%u", v_len, sizeof(uint8_t)); + return ERRCODE_FAIL; + } + + language_id = *(uint8_t *)v_data; + OHOS::device_proxy::set_language_id(language_id); + + errcode_t ret = msg_center_send_data(cmd_id, type, &language_id, sizeof(uint8_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send set_language_id_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// 设置音量 +errcode_t msg_center_set_volume_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "set_volume_info"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + + OHOS::volume_info info; + if (v_len != sizeof(OHOS::volume_info)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "v_len check error, v_len=%u, need=%u", v_len, sizeof(uint8_t)); + return ERRCODE_FAIL; + } + + memcpy_s(&info, sizeof(OHOS::volume_info), v_data, v_len); + OHOS::device_proxy::set_volume_info(info); + + errcode_t ret = msg_center_send_data(cmd_id, type, &info, sizeof(OHOS::volume_info)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send set_volume_info_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// ota初始化 +errcode_t msg_center_ota_init(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ota_init"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + + OHOS::ota_info info; + if (v_len != sizeof(OHOS::ota_info)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "v_len check error, v_len=%u, need=%u", v_len, sizeof(uint8_t)); + return ERRCODE_FAIL; + } + + memcpy_s(&info, sizeof(OHOS::ota_info), v_data, v_len); + OHOS::OTA_ERR err = OHOS::device_proxy::ota_init(info); + + errcode_t ret = msg_center_send_data(cmd_id, type, &err, sizeof(OHOS::OTA_ERR)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send set_volume_info_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +// ota检测和本地升级 +errcode_t msg_center_ota_update(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ota_update"); + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + void *v_data = msg_center_get_tlv_payload(usr_data); + uint8_t v_len = usr_len - tl_len; + + OHOS::ota_info info; + if (v_len != sizeof(OHOS::ota_info)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "v_len check error, v_len=%u, need=%u", v_len, sizeof(uint8_t)); + return ERRCODE_FAIL; + } + + memcpy_s(&info, sizeof(OHOS::ota_info), v_data, v_len); + OHOS::OTA_ERR err = OHOS::device_proxy::ota_update(info); + + errcode_t ret = msg_center_send_data(cmd_id, type, &err, sizeof(OHOS::OTA_ERR)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send set_volume_info_ack fail, ret = %d", ret); + return ERRCODE_FAIL; + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send ret = %d", ret); + OHOS::device_proxy::call_ui_ota_update(); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "send ui over"); + return ERRCODE_SUCC; +} + +errcode_t msg_center_device_heartrate(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + + ret = msg_center_send_data(cmd_id, type, &g_heartrate, sizeof(g_heartrate)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_device_heartrate:%d\r\n", g_heartrate); + /* notify UI or call UI load */ + + return ERRCODE_SUCC; +} + +errcode_t msg_center_device_stepdata(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + + ret = msg_center_send_data(cmd_id, type, &g_stepdata, sizeof(g_stepdata)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_device_stepdata:%d\r\n", g_stepdata); + /* notify UI or call UI load */ + + return ERRCODE_SUCC; +} + +errcode_t msg_center_device_bloodoxygen(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + + ret = msg_center_send_data(cmd_id, type, &g_bloodoxygen, sizeof(g_bloodoxygen)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_device_bloodoxygen:%d\r\n", g_bloodoxygen); + /* notify UI or call UI load */ + + return ERRCODE_SUCC; +} + +/* LOCATION */ +errcode_t msg_center_location_get_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + + ret = msg_center_send_data(cmd_id, type, &g_locationInfo, sizeof(g_locationInfo)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_get_info latitude_:%d,longitude_:%d\n", + g_locationInfo.latitude_, g_locationInfo.longitude_); + /* notify UI or call UI load */ + + return ERRCODE_SUCC; +} + +errcode_t msg_center_location_start(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + uint8_t ack = 1; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_start finish\r\n"); + ret = deviceLocationStartLocating(); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_start fail\r\n"); + ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_start send msg fail\r\n"); + return ERRCODE_FAIL; + } + } else { + ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_start send msg fail\r\n"); + return ERRCODE_FAIL; + } + } + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_start finish\r\n"); + /* notify UI or call UI load */ + + return ERRCODE_SUCC; +} + +errcode_t msg_center_location_stop(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + uint8_t ack = 1; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_stop\r\n"); + ret = deviceLocationStopLocating(); + ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_stop fail\r\n"); + ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_stop send msg fail\r\n"); + return ERRCODE_FAIL; + } + } else { + ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_stop send msg fail\r\n"); + return ERRCODE_FAIL; + } + } + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_location_stop\r\n"); + /* notify UI or call UI load */ + + return ERRCODE_SUCC; +} + +/* SPORT */ +errcode_t msg_center_sport_action(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + uint8_t ack = 1; + sport_action_t action = (sport_action_t)*tlv_payload; + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_sport_action : %d\r\n", action); + + switch (action) { + case SPORT_ACTION_START: + OHOS::NativeAbility::GetInstance().ChangeSlice(VIEW_SPORTS); + OHOS::SportsModel::GetInstance()->ResetSportsData(); + if (!OHOS::SportsModel::GetInstance()->StartSportsTimer()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_sport_start StartSportsTimer failed\r\n"); + ret = ERRCODE_FAIL; + } + break; + case SPORT_ACTION_PAUSE: + OHOS::SportsModel::GetInstance()->StopSportsTimer(false); + break; + case SPORT_ACTION_RESUME: + if (!OHOS::SportsModel::GetInstance()->StartSportsTimer()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_sport_resume StartSportsTimer failed\r\n"); + ret = ERRCODE_FAIL; + } + break; + case SPORT_ACTION_STOP: + OHOS::SportsModel::GetInstance()->StopSportsTimer(false); + OHOS::NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN_SAMPLE); + break; + default: + ret = ERRCODE_FAIL; + break; + } + + ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_sport_resume send data failed\r\n"); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + +errcode_t msg_center_sport_get_data(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_sport_get_data\r\n"); + OHOS::sport_data_t *sportData = OHOS::SportsModel::GetInstance()->GetSportsData(); + ret = msg_center_send_data(cmd_id, type, sportData, sizeof(OHOS::sport_data_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_sport_get_data end data failed\r\n"); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + +errcode_t msg_center_sport_report_data(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + return ERRCODE_SUCC; +} + +errcode_t msg_center_camera_exit(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "recv exit camera from phone"); + OHOS::NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST); + return ERRCODE_SUCC; +} + +errcode_t msg_center_camera_online(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "recv connect success from phone"); + if (OHOS::CameraMainPage::GetInstance() != nullptr) { + OHOS::CameraMainPage::GetInstance()->Refresh_page(); + return ERRCODE_SUCC; + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "CameraMainPage not exist\r\n"); + return ERRCODE_FAIL; + } +} + +errcode_t msg_center_offline_log_switch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + uint8_t data = *tlv_payload; + errcode_t ret = ERRCODE_SUCC; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_offline_log_switch, data = %d\r\n", data); + if (data) { + uapi_zdiag_set_offline_log_enable(true); /*open offline log*/ + } else { + uapi_zdiag_set_offline_log_enable(false); /*close offline log*/ + } + ret = msg_center_send_data(cmd_id, type, &data, sizeof(data)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + +#if (CONFIG_ONLINE_LOG == 1) +errcode_t msg_center_set_online_log_channel(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + uint8_t data = *tlv_payload; + errcode_t ret = ERRCODE_SUCC; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_set_online_log_channel, data = %d\r\n", data); + change_log_diag_channel(data); + ret = msg_center_send_data(cmd_id, type, &data, sizeof(data)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + +errcode_t msg_center_set_online_log_level(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + uint8_t data = *tlv_payload; + errcode_t ret = ERRCODE_SUCC; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_set_online_log_level, data = %d\r\n", data); + set_online_log_level(data); + ret = msg_center_send_data(cmd_id, type, &data, sizeof(data)); + if (ret != ERRCODE_SUCC) { + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +#endif + +errcode_t msg_center_device_findphone(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + bool ret = true; + if ( OHOS::FindPhoneMainPage::GetInstance() != nullptr) { + ret = OHOS::FindPhoneMainPage::GetInstance()->StopFindPhone(); + } else { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "FindphonePage not exist\r\n"); + } + if (!ret) { + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/service/device_msg/msg_center_device.h b/code/sdk/application/wearable/service/device_msg/msg_center_device.h new file mode 100644 index 000000000..02f3c2583 --- /dev/null +++ b/code/sdk/application/wearable/service/device_msg/msg_center_device.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + * Description: Breath Ease + * Author: wangle + * Create: 2025-4-23 + */ +#ifndef MSG_CENTER_DEVICE_H +#define MSG_CENTER_DEVICE_H + +#include "msg_center_protocol.h" +#include "wearable_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum sport_action { + SPORT_ACTION_START = 1, + SPORT_ACTION_PAUSE = 2, + SPORT_ACTION_RESUME = 3, + SPORT_ACTION_STOP = 4, +} sport_action_t; + +typedef enum msg_center_device_type_id { + MSGCENTER_TYPE_ID_GET_BATTERY_LEVEL = 0x1, + MSGCENTER_TYPE_ID_GET_STORAGE_INFO = 0x2, + MSGCENTER_TYPE_ID_GET_PRODUCT_INFO = 0x3, + MSGCENTER_TYPE_ID_GET_LANGUAGE_ID = 0x4, + MSGCENTER_TYPE_ID_GET_VOLUME_INFO = 0x5, + MSGCENTER_TYPE_ID_SET_LANGUAGE_ID = 0x6, + MSGCENTER_TYPE_ID_SET_VOLUME_INFO = 0x7, + MSGCENTER_TYPE_ID_DEVICE_HEARTRATE = 0x8, + MSGCENTER_TYPE_ID_DEVICE_STEPDATA = 0x9, + MSGCENTER_TYPE_ID_DEVICE_BLOODOXYGEN = 0xa, + MSGCENTER_TYPE_ID_OFFLINE_LOG_SWITCH = 0xb, + MSGCENTER_TYPE_ID_LOCATION_GET_INFO = 0x20, + MSGCENTER_TYPE_ID_LOCATION_START = 0x21, + MSGCENTER_TYPE_ID_LOCATION_STOP = 0x22, + MSGCENTER_TYPE_ID_LOCATION_REPORT = 0x23, + MSGCENTER_TYPE_ID_SPORT_ACTION = 0x27, + MSGCENTER_TYPE_ID_SPORT_GET_DATA = 0x28, + MSGCENTER_TYPE_ID_SPORT_REPORT_DATA = 0x29, + MSGCENTER_TYPE_ID_SET_ONLINELOG_CHANNEL = 0x30, + MSGCENTER_TYPE_ID_SET_ONLINELOG_LEVEL = 0x31, + MSGCENTER_TYPE_ID_ONLINELOG_REPORT = 0x33, + MSGCENTER_TYPE_ID_OTA_INIT = 0x34, + MSGCENTER_TYPE_ID_OTA_UPDATE = 0x35, + MSGCENTER_TYPE_ID_ON_FIND_PHONE = 0x36, + MSGCENTER_TYPE_ID_OFF_FIND_PHONE = 0x37, + MSGCENTER_TYPE_ID_SLEEP_DATA = 0x38, + MSGCENTER_TYPE_ID_ON_CAMERA = 0x39, + MSGCENTER_TYPE_ID_CAMERA_WATCH_EXIT = 0x40, + MSGCENTER_TYPE_ID_CAMERA_PHONE_EXIT = 0x41, + MSGCENTER_TYPE_ID_CAMERA_CONNECT_PHONE = 0x42, + MSGCENTER_TYPE_ID_CAMERA_CONNECT_PHONE_SUCCESS = 0x43, +} msg_center_device_type_id_t; + +// 获取电量 +errcode_t msg_center_get_battery_level(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// 获取存储空间 +errcode_t msg_center_get_storage_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// 获取手表类型 +errcode_t msg_center_get_product_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// 获取语言 +errcode_t msg_center_get_language_id(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// 获取音量 +errcode_t msg_center_get_volume_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// 设置语言 +errcode_t msg_center_set_language_id(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// 设置音量 +errcode_t msg_center_set_volume_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// ota初始化 +errcode_t msg_center_ota_init(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +// ota检测和本地升级 +errcode_t msg_center_ota_update(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +errcode_t msg_center_device_heartrate(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_device_stepdata(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_device_bloodoxygen(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +/* LOCATION */ +errcode_t msg_center_location_get_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_location_start(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_location_stop(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +/* SPORT */ +errcode_t msg_center_sport_action(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_sport_get_data(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_sport_report_data(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +/* 离线日志开关 */ +errcode_t msg_center_offline_log_switch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +/* 查找手机 */ +errcode_t msg_center_device_findphone(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +/* CAMERA */ +errcode_t msg_center_camera_exit(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +errcode_t msg_center_camera_online(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +#if (CONFIG_ONLINE_LOG == 1) +/* 在线日志通道 */ +errcode_t msg_center_set_online_log_channel(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +/* 在线日志级数 */ +errcode_t msg_center_set_online_log_level(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); +#endif + +#ifdef PUBLISH_TEST_DATA +void PublishTestData(); +#endif +#ifdef __cplusplus +} +#endif +#endif /* MSG_CENTER_DEVICE_H */ diff --git a/code/sdk/application/wearable/service/dial_market/CMakeLists.txt b/code/sdk/application/wearable/service/dial_market/CMakeLists.txt index 058f8dc76..8c61862ab 100644 --- a/code/sdk/application/wearable/service/dial_market/CMakeLists.txt +++ b/code/sdk/application/wearable/service/dial_market/CMakeLists.txt @@ -11,7 +11,6 @@ set(PRIVATE_HEADER ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils ${ROOT_DIR}/open_source/openharmony/base/startup/syspara_lite/include ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/format/interfaces/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/main/include/dial ) set(SOURCES diff --git a/code/sdk/application/wearable/service/dial_market/dial_market.cpp b/code/sdk/application/wearable/service/dial_market/dial_market.cpp new file mode 100644 index 000000000..5d6de8491 --- /dev/null +++ b/code/sdk/application/wearable/service/dial_market/dial_market.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. + * Description: ota upgrade handle. + * This file should be changed only infrequently and with great care. + */ +#include +#include "securec.h" +#include "msg_center.h" +#include "msg_center_protocol.h" +#include "msg_center_cmd.h" +#include "wearable_log.h" +#include "common_def.h" +#include "dial_market.h" +#include "parameter.h" +#include "main/dial/WatchInterface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +errcode_t msg_center_dial_market_get_sys_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + watch_sys_info sys; + bool op_ret = false; + + /* 组装信息 */ + strcpy_s(sys.chip_platform, MAX_CHIP_PLAT_LEN, "hisi"); + strcpy_s(sys.chip_model, MAX_CHIP_MODEL_LEN, "3321"); + char *os_version = GetOsName(); + if (os_version == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "os_version is NULL\r\n"); + return ERRCODE_FAIL; + } + strcpy_s(sys.os_version, MAX_OS_LEN, os_version); // "OpenHarmony-5.0.1.115" + + char *api_level = GetSdkApiLevel(); + if (api_level == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "api_level is NULL\r\n"); + free(os_version); + return ERRCODE_FAIL; + } + strcpy_s(sys.api_level, MAX_API_LEVEL_LEN, api_level); // "13" + + op_ret = GetWatchSystemInfo(&sys); + if (op_ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "GetWatchSystemInfo fail\r\n"); + free(os_version); + free(api_level); + return ERRCODE_FAIL; + } + + ret = msg_center_send_data(cmd_id, type, &sys, sizeof(watch_sys_info)); + if (ret != ERRCODE_SUCC) { + free(os_version); + free(api_level); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + + free(os_version); + free(api_level); + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_get_dev_cap(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + watch_dev_cap_info cap; + bool op_ret = false; + + op_ret = GetWatchCapability(&cap); + if (op_ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "GetWatchCapability fail\r\n"); + return ERRCODE_FAIL; + } + + ret = msg_center_send_data(cmd_id, type, &cap, sizeof(watch_dev_cap_info)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_get_one_watch_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + uint32_t uuid = *(uint32_t *)tlv_payload; + bool op_ret = false; + watch_dial_info info; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "uuid = %d\r\n", uuid); + op_ret = GetWatchFaceInfo(uuid, &info); + if (op_ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "GetWatchFaceInfo fail\r\n"); + (void)memset_s(&info, sizeof(watch_dial_info), 0, sizeof(watch_dial_info)); + info.uuid = uuid; + (void)msg_center_send_data(cmd_id, type, &info, sizeof(watch_dial_info)); + return ERRCODE_FAIL; + } + + ret = msg_center_send_data(cmd_id, type, &info, sizeof(watch_dial_info)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_install_watch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + uint32_t uuid = 0; + bool op_ret = false; + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + + char *path = (char *)malloc(payload_len + 1); + if (path == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "malloc failed.\r\n"); + return ERRCODE_FAIL; + } + + (void)memcpy_s(path, payload_len, tlv_payload, payload_len); + path[payload_len] = '\0'; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "path = %s\r\n", path); + + op_ret = GetUuidByPath(path, &uuid); + if (op_ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "install fail.\r\n"); + free(path); + return ERRCODE_FAIL; + } + + ret = msg_center_send_data(cmd_id, type, &uuid, sizeof(uint32_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + free(path); + return ERRCODE_FAIL; + } + + free(path); + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_uninstall_watch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + bool op_ret = false; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + uint32_t uuid = *(uint32_t *)tlv_payload; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "uuid = %d\r\n", uuid); + op_ret = UninstallWatch(uuid); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "uninstall ret : %d\r\n", op_ret); + + ret = msg_center_send_data(cmd_id, type, &op_ret, sizeof(uint8_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_set_watch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + bool op_ret = false; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + uint32_t uuid = *(uint32_t *)tlv_payload; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "uuid = %d\r\n", uuid); + op_ret = SetCurrentWatchFace(uuid); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "set_current_watch_face ret : %d\r\n", op_ret); + + ret = msg_center_send_data(cmd_id, type, &op_ret, sizeof(uint8_t)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_get_all_watch_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + watch_dial_info *info = nullptr; + uint8_t watch_num = 0; + bool op_ret = false; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "get_all_watch_info\r\n"); + op_ret = GetAllWatchFaceInfo(&info, &watch_num); + if (op_ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "GetAllWatchFaceInfo fail\r\n"); + watch_num = 0; + (void)msg_center_send_data(cmd_id, type, info, sizeof(watch_dial_info) * watch_num); + return ERRCODE_FAIL; + } + + ret = msg_center_send_data(cmd_id, type, info, sizeof(watch_dial_info) * watch_num); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + free(info); + return ERRCODE_FAIL; + } + + free(info); + return ERRCODE_SUCC; +} + +errcode_t msg_center_dial_market_get_cur_watch_info(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + errcode_t ret = ERRCODE_SUCC; + bool op_ret = false; + watch_dial_info info; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "get_cur_watch_info\r\n"); + op_ret = GetCurrentWatchFaceInfo(&info); + if (op_ret == false) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "GetCurrentWatchFaceInfo fail\r\n"); + (void)memset_s(&info, sizeof(watch_dial_info), 0, sizeof(watch_dial_info)); + info.uuid = 0xFFFFFFFF; // 异常时用全F的uuid表示 + (void)msg_center_send_data(cmd_id, type, &info, sizeof(watch_dial_info)); + return ERRCODE_FAIL; + } + + ret = msg_center_send_data(cmd_id, type, &info, sizeof(watch_dial_info)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send data fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + + return ERRCODE_SUCC; +} +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/service/dial_market/dial_market_msg.cpp b/code/sdk/application/wearable/service/dial_market/dial_market_msg.cpp new file mode 100644 index 000000000..b30812e0b --- /dev/null +++ b/code/sdk/application/wearable/service/dial_market/dial_market_msg.cpp @@ -0,0 +1,47 @@ + +#include "msg_center_protocol.h" +#include "msg_center_cmd.h" +#include "ohos_init.h" +#include "dial_market.h" + +namespace OHOS { + +#ifdef __cplusplus +extern "C" { +#endif + +static const msg_center_cmd_map_t g_msg_center_dial_market_tbl[] = { + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_GET_SYS_INFO, msg_center_dial_market_get_sys_info}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_GET_DEV_CAP, msg_center_dial_market_get_dev_cap}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_GET_ONE_WATCH_INFO, msg_center_dial_market_get_one_watch_info}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_INSTALL_WATCH, msg_center_dial_market_install_watch}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_UNINSTALL_WATCH, msg_center_dial_market_uninstall_watch}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_SET_WATCH, msg_center_dial_market_set_watch}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_GET_ALL_WATCH_INFO, msg_center_dial_market_get_all_watch_info}, + { MSGCENTER_CMD_DIAL_MARKET, MSGCENTER_TYPE_ID_DM_GET_CUR_WATCH_INFO, msg_center_dial_market_get_cur_watch_info}, +}; + +errcode_t msg_center_dial_market_dispatch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tbl_size = sizeof(g_msg_center_dial_market_tbl) / sizeof(g_msg_center_dial_market_tbl[0]); + uint8_t i; + for (i = 0; i < tbl_size; i++) { + msg_center_cmd_map_t *item = (msg_center_cmd_map_t *)&g_msg_center_dial_market_tbl[i]; + if ((item->type == type) && (item->handler != NULL)) { + item->handler(cmd_id, type, usr_data, usr_len); + return ERRCODE_SUCC; + } + } + return ERRCODE_NOT_SUPPORT; +} + +void dial_market_init(void) +{ + msg_center_register_cmd(MSGCENTER_CMD_DIAL_MARKET, msg_center_dial_market_dispatch); +} + +APP_FEATURE_INIT_PRI(dial_market_init, LAYER_INIT_LEVEL_4); +#ifdef __cplusplus +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/service/msg_center/CMakeLists.txt b/code/sdk/application/wearable/service/msg_center/CMakeLists.txt index a1ac91cb3..a26eab496 100644 --- a/code/sdk/application/wearable/service/msg_center/CMakeLists.txt +++ b/code/sdk/application/wearable/service/msg_center/CMakeLists.txt @@ -18,9 +18,13 @@ set(PRIVATE_HEADER ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components_ext ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include ${ROOT_DIR}/application/wearable/service/xiaodu_voice + ${ROOT_DIR}/application/wearable/service/watch_setting_msg/include ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs ${ROOT_DIR}/application/wearable/service/msg_center/src/notify/ketinput/include + ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include + ${ROOT_DIR}/application/wearable/nativeabilityfwk/include + ${ROOT_DIR}/open_source/openharmony/foundation/multimedia/player/interfaces/kits ) set(SOURCES @@ -88,15 +92,6 @@ set(PUBLIC_HEADER ) set(PRIVATE_HEADER - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/alarmclockmanage/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/alarmclocktimerconfig/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/alarm/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/callerlog/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/phoneservice/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/main/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/player/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/bluetooth/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/key/include ${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativelauncher/include ${CMAKE_CURRENT_SOURCE_DIR}/../../ohos_deps ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include @@ -120,20 +115,13 @@ set(PRIVATE_HEADER ${ROOT_DIR}/include/middleware/services/bts/common ${ROOT_DIR}/application/auto_ota ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector + ${ROOT_DIR}/open_source/openharmony/third_party/cJSON + ${ROOT_DIR}/application/wearable/service/device_msg ${ROOT_DIR}/application/wearable/service/msg_center/src/notify/ketinput/include ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include ${ROOT_DIR}/application/wearable/nativeabilityfwk/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/alarm/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/key/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/alarmclockmanage/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/alarmclocktimerconfig/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/main/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/callerlog/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/phoneservice/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/makephone/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/player/include - ${ROOT_DIR}/application/wearable/nativeapp/nativeui/applist/include ${ROOT_DIR}/open_source/openharmony/foundation/multimedia/player/interfaces/kits + ) if("JS_ENABLE" IN_LIST DEFINES) @@ -144,18 +132,18 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/makephone_notification.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/common/msg_center_common.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/common/msg_center_utils.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/common/msg_center_self_cmd.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/ketinput/src/NotifyOnKeyListener.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/pairing_notification.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/phone_msg_notification.cpp ) else() set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/msg_center_customer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/msg_center_cmd.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/msg_center_self_cmd.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/alarm_notification.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/makephone_notification.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/ketinput/src/NotifyOnKeyListener.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/pairing_notification.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/notify/phone_msg_notification.cpp ) endif() diff --git a/code/sdk/application/wearable/service/msg_center/brandy-auto-ota-cli/libmsg_center.a b/code/sdk/application/wearable/service/msg_center/brandy-auto-ota-cli/libmsg_center.a index 6a29e7c9809b732e3e6ee487b20698936ebb5de9..c6b588af40311fc7db1cf3e70d2f76cdbdef0c06 100644 GIT binary patch delta 36704 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

{2`&JfKlLkeEfIdJA8Z!_^UpC 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 delta 38088 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 gFxUe6n%bC-S_K(639>_x+x)R6zAM}qTd;kCd delta 38088 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 diff --git a/code/sdk/application/wearable/service/msg_center/brandy-native-js/libmsg_center.a b/code/sdk/application/wearable/service/msg_center/brandy-native-js/libmsg_center.a index c3aaaca9686556b7bc05c051081c4d2e52d0ffb3..b1e105a9cc75ad88d729fd204dc0ae272780a222 100644 GIT binary patch delta 36704 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 gFxUe6n%bC-S_K(639>_x+x)R6zAIs+?EC2ui delta 38088 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 diff --git a/code/sdk/application/wearable/service/msg_center/brandy-xts/libmsg_center.a b/code/sdk/application/wearable/service/msg_center/brandy-xts/libmsg_center.a index 426bb7c4307c469bb6ea6f40b719636e23ecb051..7f842a9c972b66c06ec3fe9343c9f081e8d1006c 100644 GIT binary patch delta 36698 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 j;eiSb#xrAPJkJ6h$q^ zDs?0|HA#}8kyJ<}Nsgm(q?#lol{%eLsebooul1SP^E7?G*Z+V0uIsnhd)@c_S#Nvo z^|IgAGkbrFId^aEmHwEHo$}kY&+X9RfsA&ctwMD9f4GJIUuKTHL+;V<+$qHWwpFAF z!P~ddLj2#^LjSiC`a?Q$@k#N&Z=wGo(2JXe{NJ`Cr-h{L#M=L_+ZD5JD7t=n*&)Z* zw3cmazUY+;rXcPMIwatJcl_mR$GKPEkT6L`8{~>li(`I7|JzSy9|G|M*8d zYpPZAHKQ7Q!L;PzdO{`8}vhYq-ZF5NFjy-_g9y<3^aHIsHL@B3ClipTg$c$4?$^f)wNI& zQRJ(aT6UGw)Q>Hj^jrkVxM=Y%Y!5OO(c%N}?v*@7d;(5+8y6$afDczATQ!kc>b6$1 z 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 diff --git a/code/sdk/application/wearable/service/msg_center/include/msg_center_protocol.h b/code/sdk/application/wearable/service/msg_center/include/msg_center_protocol.h index 02cf29c8f..ed6ece04c 100644 --- a/code/sdk/application/wearable/service/msg_center/include/msg_center_protocol.h +++ b/code/sdk/application/wearable/service/msg_center/include/msg_center_protocol.h @@ -62,6 +62,8 @@ typedef enum msg_center_cmd_id { MSGCENTER_CMD_WATCH_CONNECT = 0x8, MSGCENTER_CMD_APP_STORE = 0x9, MSGCENTER_CMD_DIAL_MARKET = 0xa, + MSGCENTER_CMD_PHONE_MSG = 0xb, // 增加消息通知; + MSGCENTER_CMD_DEVICE = 0xc, MSGCENTER_CMD_MAX } msg_center_cmd_id_t; diff --git a/code/sdk/application/wearable/service/msg_center/include/notify/notification_manager.h b/code/sdk/application/wearable/service/msg_center/include/notify/notification_manager.h index 532f1c11d..345828de1 100644 --- a/code/sdk/application/wearable/service/msg_center/include/notify/notification_manager.h +++ b/code/sdk/application/wearable/service/msg_center/include/notify/notification_manager.h @@ -24,6 +24,7 @@ #include "components/ui_view_group.h" #include "alarm_notification.h" #include "makephone_notification.h" +#include "phone_msg_notification.h" constexpr uint16_t HALF_SCREEN = 2; constexpr int16_t NOTIFY_PRIORITY_DEFAULT = 4; diff --git a/code/sdk/application/wearable/service/msg_center/include/notify/phone_msg_notification.h b/code/sdk/application/wearable/service/msg_center/include/notify/phone_msg_notification.h new file mode 100644 index 000000000..735c01edf --- /dev/null +++ b/code/sdk/application/wearable/service/msg_center/include/notify/phone_msg_notification.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: phone message notification + * Author: + * Create: 2025-04-25 + */ + +#ifndef PHONE_MSG_NOTIFICATION_H +#define PHONE_MSG_NOTIFICATION_H + +#include "components/ui_view_group.h" +#include "components/ui_view_group.h" +#include "components/ui_label.h" +#include "components/ui_label_button_ext.h" +#include "graphic_timer.h" +#include + +struct PhoneMsg { + std::string appName; + std::string msgTitle; + std::string msgContent; +}; + +namespace OHOS { +class PhoneMsgView { +public: + static UIViewGroup *CreatePhoneMsgView(); + static void FreePhoneMsgView(void); + static void UpDatePhoneMsg(std::string appName, std::string titile, std::string content); + static void StartPhoneMsgTimer(int32_t interval); + static void DisablePhoneMsgTimer(); + static const uint32_t notifyTime = 5000; + +private: + static UIViewGroup *phoneMsgView_; + static UILabel *appNameLabel_; + static UILabel *titleLabel_; + static UILabel *contentLabel_; + static GraphicTimer *phoneMsgNotifyStop_; + static PhoneMsg phoneMsg_; + static UILabelButtonExt *cancelButton_; +}; + +class PhoneMsgViewEventListener : public OHOS::UIView::OnClickListener, + public OHOS::UIView::OnLongPressListener, + public OHOS::UIView::OnTouchListener, + public OHOS::UIView::OnDragListener { +public: + PhoneMsgViewEventListener(); + virtual ~PhoneMsgViewEventListener(); + static PhoneMsgViewEventListener *GetInstance(void); + bool OnDrag(UIView& view, const DragEvent& event) override; + bool OnDragEnd(OHOS::UIView& view, const OHOS::DragEvent& event) override; + bool OnClick(OHOS::UIView& view, const OHOS::ClickEvent& event) override; + bool OnPress(OHOS::UIView& view, const OHOS::PressEvent& event) override + { + return true; + } + bool OnLongPress(OHOS::UIView& view, const OHOS::LongPressEvent& event) override + { + return true; + } + bool OnRelease(OHOS::UIView& view, const OHOS::ReleaseEvent& event) override + { + return true; + } + + bool OnDragStart(OHOS::UIView& view, const OHOS::DragEvent& event) override + { + return true; + } +}; +}; // namespace OHOS + +#endif /* PHONE_MSG_NOTIFICATION_H */ diff --git a/code/sdk/application/wearable/service/msg_center/src/common/msg_center_self_cmd.cpp b/code/sdk/application/wearable/service/msg_center/src/common/msg_center_self_cmd.cpp new file mode 100644 index 000000000..ee822bec1 --- /dev/null +++ b/code/sdk/application/wearable/service/msg_center/src/common/msg_center_self_cmd.cpp @@ -0,0 +1,43 @@ +#include "msg_center_protocol.h" +#include "msg_center_cmd.h" +#include "ohos_init.h" +#include "msg_center_common.h" +namespace OHOS { + +#ifdef __cplusplus +extern "C" { +#endif + +static const msg_center_cmd_map_t g_msg_center_self_cmd_tbl[] = { +#ifdef JS_ENABLE + { MSGCENTER_CMD_PING, MSGCENTER_TYPE_ID_PING_REC, msg_center_ping_rec}, + { MSGCENTER_CMD_PING, MSGCENTER_TYPE_ID_PING_RSP, NULL}, +#endif +}; + +errcode_t msg_center_self_cmd_type(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tbl_size = sizeof(g_msg_center_self_cmd_tbl) / sizeof(g_msg_center_self_cmd_tbl[0]); + uint8_t i; + for (i = 0; i < tbl_size; i++) { + msg_center_cmd_map_t *item = (msg_center_cmd_map_t *)&g_msg_center_self_cmd_tbl[i]; + if ((item->type == type) && (item->handler != NULL)) { + item->handler(cmd_id, type, usr_data, usr_len); + return ERRCODE_SUCC; + } + } + return ERRCODE_NOT_SUPPORT; +} + +void xiaodu_self_cmd_init(void) +{ + msg_center_register_cmd(MSGCENTER_CMD_PING, msg_center_self_cmd_type); +} + +#ifdef JS_ENABLE +APP_FEATURE_INIT_PRI(xiaodu_self_cmd_init, LAYER_INIT_LEVEL_4); +#endif +#ifdef __cplusplus +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp b/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp index 04e3aa018..557dec374 100644 --- a/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp +++ b/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp @@ -14,9 +14,9 @@ #include "wearable_log.h" #include "service_id_define.h" #include "broadcast_service.h" -#include "AlarmClockModel.h" -#include "AlarmPopUpPresenter.h" -#include "CallerLogModel.h" +#include "alarm/AlarmClockModel.h" +#include "alarm/AlarmPopUpPresenter.h" +#include "callerlog/CallerLogModel.h" #include "notification_manager.h" #include "NativeAbility.h" #include "abilityms_slite_client.h" @@ -29,32 +29,42 @@ #include "baidumap.h" #include "common_def.h" #include "keyinput.h" -#include "KeyInputListener.h" -#include "VolumeSettingView.h" -#include "VolumeSettingPresenter.h" -#include "VolumeSettingView.h" +#include "key/KeyInputListener.h" +#include "main/VolumeSettingView.h" +#include "main/VolumeSettingPresenter.h" +#include "main/VolumeSettingView.h" +#include "cJSON.h" +#include "heartrate/HeartModel.h" +#include "device_location.h" namespace OHOS { #ifdef __cplusplus extern "C" { #endif +extern uint8_t g_bloodoxygen; +extern uint16_t g_heartrate; +extern uint32_t g_stepdata; +extern uint32_t g_distance; +extern LocationInfo_t g_locationInfo; + /* 订阅事件设定优先级 */ const PriorityMapper PRI_MAPPER[] = { {TOPIC_EVENT_ALARM_RING, PRIORITY_TWO}, {TOPIC_EVENT_NEXTDAY_UPDATE, PRIORITY_TWO}, - {TOPIC_EVENT_BLE_TRANSMIT,PRIORITY_ONE}, {TOPIC_EVENT_HFP_INCOMMING, PRIORITY_ONE}, {TOPIC_EVENT_HFP_FINISHED, PRIORITY_ONE}, {TOPIC_EVENT_HFP_PHONE_ACTIVE, PRIORITY_ONE}, {TOPIC_EVENT_HFP_WATCH_ACTIVE, PRIORITY_ONE}, {TOPIC_EVENT_HFP_WATCH_TO_PHONE, PRIORITY_ONE}, {TOPIC_EVENT_HFP_PHONE_TO_WATCH, PRIORITY_ONE}, - {TOPIC_EVENT_DEVICE_BIND, PRIORITY_ONE}, - // {TOPIC_EVENT_DEVICE_UNBIND, PRIORITY_TWO}, - // {TOPIC_EVENT_DEVICE_UNBINDING_REQUEST, PRIORITY_TWO}, - - }; + {TOPIC_DEMO_ALL_MSG, PRIORITY_TWO}, + {TOPIC_EVENT_STEPDATA_UPDATE, PRIORITY_TWO}, + {TOPIC_EVENT_HEARTRATE_UPDATA, PRIORITY_TWO}, + {TOPIC_EVENT_BLOODOXYGEN_UPDATA, PRIORITY_TWO}, + {TOPIC_EVENT_SPORT_DISTANCE, PRIORITY_TWO}, + {TOPIC_EVENT_LOCATION, PRIORITY_TWO}, +}; bool g_pressFlag = false; bool g_longPressFlag = false; @@ -86,7 +96,11 @@ void MsgCenterSubscribe() MsgCenterSubscribeTopic(TOPIC_EVENT_HFP_FINISHED); MsgCenterSubscribeTopic(TOPIC_EVENT_HFP_PHONE_TO_WATCH); MsgCenterSubscribeTopic(TOPIC_EVENT_HFP_WATCH_TO_PHONE); - MsgCenterSubscribeTopic(TOPIC_EVENT_DEVICE_BIND); + MsgCenterSubscribeTopic(TOPIC_EVENT_STEPDATA_UPDATE); + MsgCenterSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA); + MsgCenterSubscribeTopic(TOPIC_EVENT_BLOODOXYGEN_UPDATA); + MsgCenterSubscribeTopic(TOPIC_EVENT_SPORT_DISTANCE); + MsgCenterSubscribeTopic(TOPIC_EVENT_LOCATION); } static OHOS::UIViewGroup* ShowAlarmNotify(void) @@ -109,28 +123,12 @@ static OHOS::UIViewGroup* ShowMultiPhoneCallNotify(void) return OHOS::CreateMultiplePhoneView(); } - -/*显示绑定通知*/ -static OHOS::UIViewGroup* showDeviceBindingNotify(void) +static OHOS::UIViewGroup* ShowMsgNotify(void) { - return OHOS::CreateDeviceBindingView(); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ShowMsgNotify"); + return OHOS::PhoneMsgView::CreatePhoneMsgView(); } -/*显示解绑通知*/ -static OHOS::UIViewGroup* showDeviceUnBindingNotify(void) -{ - return OHOS::CreateDeviceUnBindingView(); -} - -/*显示解除绑定请求(与新设备连接)通知*/ -static OHOS::UIViewGroup* showDeviceUnbindingRequestNotify(void) -{ - return OHOS::CreateDeviceUnbindingRequestGroupView(); -} -static OHOS::UIViewGroup* showtransmitNotify(void) -{ - return OHOS::transmittingShow(); -} void MsgCenterNotifyAlarmProc(const Topic topic, Request* req) { unused(req); @@ -206,115 +204,84 @@ void MsgCenterNotifyHfpWatchProc(const Topic topic, Request* req) } } -void MsgCenterNotifyDeviceBindProc(const Topic topic, Request* req) +void MsgCenterNotifyMsgWatchProc(const Topic topic, Request* req) { - //unused(req); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MsgCenterNotifyBindProc Bind!"); - const power_display_svr_api_t *display_api = power_display_svr_get_api(); - if (display_api->get_screen_state() != SCREEN_ON) - { - display_api->turn_on_screen(); + std::string msgContent((char *)(req->data), req->len); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MsgCenterNotifyMsgWatchProc msgContent %s\r\n", msgContent.c_str()); + cJSON *msgJson = cJSON_Parse(msgContent.c_str()); + if (msgJson == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "phone msg_result cJSON_Parse, fail = %p\r\n", msgJson); } - uint8_t* data=(uint8_t*)req->data; - uint8_t len_name = req->len; - char devname[len_name]; - if(data!=NULL && req->len>=2) - { - switch(data[0]) - { - case DEVICEBIND: - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_ONE); - len_name = req->len-2; - memset(devname,0,len_name); - if(len_name > 0) - { - memcpy(devname,(char *)req->data+2,len_name); - PairingViewEventListener::GetInstance().SetDeviceName(devname); - }else{ - PairingViewEventListener::GetInstance().SetDeviceName(NULL); - } - NotificationManager::GetInstance()->ShowNotify(showDeviceBindingNotify, (uint16_t)topic, true); - break; - case DEVICEUNBIND: - - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_ONE); - len_name = req->len-2; - memset(devname,0,len_name); - if(len_name > 0) - { - memcpy(devname,(char *)req->data+2,len_name); - // printf("devname:%s\r\n",devname); - PairingViewEventListener::GetInstance().SetDeviceName(devname); - }else{ - PairingViewEventListener::GetInstance().SetDeviceName(NULL); - } - NotificationManager::GetInstance()->ShowNotify(showDeviceUnBindingNotify, (uint16_t)topic, true); - break; - case DeviceUnBindingRequest: - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_TWO); - NotificationManager::GetInstance()->ShowNotify(showDeviceUnbindingRequestNotify, (uint16_t)topic, true); - break; - case SHUTDOWN: - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " SHUTDOWN"); - set_lowpower_falg(3); - if (NotificationManager::GetInstance()->HasNotifyShowing()) - NotificationManager::GetInstance()->StopNotify(); - - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_TWO); - - NotificationManager::GetInstance()->ShowNotify(showlowpowerNotify, (uint16_t)topic, true); - //low_power_play(true); - break; - case REBOOT: - set_lowpower_falg(4); - if (NotificationManager::GetInstance()->HasNotifyShowing()) - NotificationManager::GetInstance()->StopNotify(); - - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_TWO); - NotificationManager::GetInstance()->ShowNotify(showlowpowerNotify, (uint16_t)topic, true); - //low_power_play(false); - break; - - default: - break; - } - + cJSON *appNameJson = cJSON_GetObjectItem(msgJson, "appName"); + cJSON *packageNameJson = cJSON_GetObjectItem(msgJson, "packageName"); + cJSON *titleJson = cJSON_GetObjectItem(msgJson, "title"); + cJSON *contentJson = cJSON_GetObjectItem(msgJson, "content"); + char *appName = appNameJson->valuestring; + char *packageName = packageNameJson->valuestring; + char *title = titleJson->valuestring; + char *content = contentJson->valuestring; + if (msgJson) { + cJSON_Delete(msgJson); + } + PhoneMsgView::UpDatePhoneMsg(appName, title, content); + if (CheckPriority(topic)) { + NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_TWO); + NotificationManager::GetInstance()->ShowNotify(ShowMsgNotify, static_cast(topic), true); } - } -void MsgCenterNotifybleTransmit(const Topic topic, Request* req) + +void MsgCenterNotifyHeartRateProc(const Topic topic, Request* req) { unused(topic); - uint8_t* data=(uint8_t*)req->data; - - - if(data[0]==TRANS_FREE) - { - if(transmittingISShow()) - NotificationManager::GetInstance()->StopNotify(); + if(req && req->data){ + HeartDatas* heart_data = (HeartDatas*)req->data; + g_heartrate = heart_data->perSec; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MsgCenterNotifyHeartRateProc per heartrate: %d\n", g_heartrate); } - else if (data[0]==IS_NEED_CAT1_OTA) - { - - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_ONE); +} - NotificationManager::GetInstance()->ShowNotify(showCat1UpdataNotify, (uint16_t)topic, true); +void MsgCenterNotifyStepDataProc(const Topic topic, Request* req) +{ + unused(topic); + uint32_t step = 0; + if(req && req->data){ + step = *(uint32_t*)req->data; + g_stepdata += step; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MsgCenterNotifyStepDataProc step:%d, totalStep:%d\n", step, g_stepdata); } - else if (data[0]==FILE_IS_DONE) - { - set_transmittingShow_falg(data[0]); +} + +void MsgCenterNotifyBloodOxygenProc(const Topic topic, Request* req) +{ + unused(topic); + if(req && req->data){ + g_bloodoxygen = *(uint8_t*)req->data; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MsgCenterNotifyBloodOxygenProc bloodoxygen:%d\n", g_bloodoxygen); } - else - { - set_transmittingShow_falg(data[0]); - - NotificationManager::GetInstance()->SetNotifyPriority(PRIORITY_ONE); +} - NotificationManager::GetInstance()->ShowNotify(showtransmitNotify, (uint16_t)topic, true); +void MsgCenterNotifyDistanceProc(const Topic topic, Request* req) +{ + unused(topic); + uint32_t distance = 0; + if(req && req->data){ + distance = *(uint32_t*)req->data; + g_distance += distance; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MsgCenterNotifyDistanceProc distance:%d\n", g_distance); } - // unused(req); +} +void MsgCenterNotifyLocationProc(const Topic topic, Request* req) +{ + unused(topic); + if(req && req->data){ + LocationInfo_t* location = (LocationInfo_t*)req->data; + g_locationInfo.latitude_ = location->latitude_; + g_locationInfo.longitude_ = location->longitude_; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "latitude_:%d,longitude_:%d\n", g_locationInfo.latitude_, g_locationInfo.longitude_); + } } + /* 订阅事件通知逻辑可定制 */ static MsgCenterNotifyTable g_msgCenterNotifyTable[] = { {TOPIC_EVENT_ALARM_RING, MsgCenterNotifyAlarmProc}, @@ -325,13 +292,13 @@ static MsgCenterNotifyTable g_msgCenterNotifyTable[] = { {TOPIC_EVENT_HFP_WATCH_TO_PHONE, MsgCenterNotifyHfpPhoneProc}, {TOPIC_EVENT_HFP_WATCH_ACTIVE, MsgCenterNotifyHfpWatchProc}, {TOPIC_EVENT_HFP_PHONE_TO_WATCH, MsgCenterNotifyHfpWatchProc}, -{TOPIC_EVENT_BLE_TRANSMIT, MsgCenterNotifybleTransmit}, - - {TOPIC_EVENT_DEVICE_BIND, MsgCenterNotifyDeviceBindProc}, - // {TOPIC_EVENT_DEVICE_UNBIND, MsgCenterNotifyDeviceUnBindProc}, - // {TOPIC_EVENT_DEVICE_UNBINDING_REQUEST, MsgCenterNotifyDeviceUnBindingRequestProc}, - - }; + {TOPIC_DEMO_ALL_MSG, MsgCenterNotifyMsgWatchProc}, + {TOPIC_EVENT_HEARTRATE_UPDATA, MsgCenterNotifyHeartRateProc}, + {TOPIC_EVENT_STEPDATA_UPDATE, MsgCenterNotifyStepDataProc}, + {TOPIC_EVENT_BLOODOXYGEN_UPDATA, MsgCenterNotifyBloodOxygenProc}, + {TOPIC_EVENT_SPORT_DISTANCE, MsgCenterNotifyDistanceProc}, + {TOPIC_EVENT_LOCATION, MsgCenterNotifyLocationProc}, +}; static MsgCenterNotifyTable *MsgCenterGetNotifyTblCb(uint8_t idx) { @@ -506,12 +473,12 @@ void StopJsApp(char *bundleName) { ElementName* topAbility = OHOS::AbilityMsClient::GetInstance().GetTopAbility(); if (topAbility == nullptr) { - WEARABLE_LOGE(HILOG_MODULE_AAFWK, "topAbility is null"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "topAbility is null"); return; } if (strcmp(topAbility->bundleName, bundleName) != 0) { - WEARABLE_LOGE(HILOG_MODULE_AAFWK, "%s is not top active", bundleName); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "%s is not top active", bundleName); FreeElement(topAbility); return; } diff --git a/code/sdk/application/wearable/service/msg_center/src/notify/alarm_notification.cpp b/code/sdk/application/wearable/service/msg_center/src/notify/alarm_notification.cpp index dc289cf8e..9b98affc0 100644 --- a/code/sdk/application/wearable/service/msg_center/src/notify/alarm_notification.cpp +++ b/code/sdk/application/wearable/service/msg_center/src/notify/alarm_notification.cpp @@ -8,7 +8,7 @@ #include "notification_manager.h" #include "wearable_log.h" #include "UiConfig.h" -#include "AlarmPopUpPresenter.h" +#include "alarm/AlarmPopUpPresenter.h" #include "components/ui_image_view.h" #include "components/ui_label.h" @@ -84,6 +84,7 @@ void NoOperateCallback(void* data) { (void)data; NotificationManager::GetInstance()->StopNotify(); + AlarmPopUpPresenter::GetInstance()->DelayAlarmRing(); } void StartAlarmTimer(AlarmTimerType type, int32_t interval) diff --git a/code/sdk/application/wearable/service/msg_center/src/notify/ketinput/src/NotifyOnKeyListener.cpp b/code/sdk/application/wearable/service/msg_center/src/notify/ketinput/src/NotifyOnKeyListener.cpp index bfcc29b0b..cfff9a774 100644 --- a/code/sdk/application/wearable/service/msg_center/src/notify/ketinput/src/NotifyOnKeyListener.cpp +++ b/code/sdk/application/wearable/service/msg_center/src/notify/ketinput/src/NotifyOnKeyListener.cpp @@ -9,18 +9,18 @@ #include "common/key_code.h" #include "AppViewIDs.h" #include "View.h" -#include "KeyInputListener.h" -#include "VolumeSettingView.h" -#include "VolumeSettingPresenter.h" -#include "VolumeSettingView.h" +#include "key/KeyInputListener.h" +#include "main/VolumeSettingView.h" +#include "main/VolumeSettingPresenter.h" +#include "main/VolumeSettingView.h" #include "wearable_log.h" #include "UiConfig.h" #include "dock/input_device.h" #include "notification_manager.h" -#include "AlarmPopUpPresenter.h" -#include "CallerLogModel.h" -#include "MainCallingPresenter.h" -#include "ApplistModel.h" +#include "alarm/AlarmPopUpPresenter.h" +#include "callerlog/CallerLogModel.h" +#include "makephone/MainCallingPresenter.h" +#include "applist/ApplistModel.h" namespace OHOS { static bool IsNotifyCallStatus() { diff --git a/code/sdk/application/wearable/service/msg_center/src/notify/makephone_notification.cpp b/code/sdk/application/wearable/service/msg_center/src/notify/makephone_notification.cpp index 29c369a94..c0929b0df 100644 --- a/code/sdk/application/wearable/service/msg_center/src/notify/makephone_notification.cpp +++ b/code/sdk/application/wearable/service/msg_center/src/notify/makephone_notification.cpp @@ -7,15 +7,15 @@ #include "notification_manager.h" #include "wearable_log.h" -#include "CallerLogModel.h" -#include "PhoneService.h" +#include "callerlog/CallerLogModel.h" +#include "phoneservice/PhoneService.h" #include "cmsis_os.h" #include "UiConfig.h" #include "components/ui_image_view.h" #include "components/ui_label.h" #include "common/image_cache_manager.h" -#include "VolumeSettingView.h" -#include "VolumeSettingPresenter.h" +#include "main/VolumeSettingView.h" +#include "main/VolumeSettingPresenter.h" #include "ui_resource_image.h" namespace OHOS { diff --git a/code/sdk/application/wearable/service/msg_center/src/notify/phone_msg_notification.cpp b/code/sdk/application/wearable/service/msg_center/src/notify/phone_msg_notification.cpp new file mode 100644 index 000000000..eb6a40883 --- /dev/null +++ b/code/sdk/application/wearable/service/msg_center/src/notify/phone_msg_notification.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Description: phone message notification + * Create: 2025-04-25 + */ + +#include "notification_manager.h" +#include "ohos_timer.h" +#include "wearable_log.h" +#include +#include "main/MessageModel.h" + +namespace OHOS { +// 三方应用名 +static const uint32_t APP_NAME_POS_X = 180; +static const uint32_t APP_NAME_POS_Y = 82; +static const uint32_t APP_NAME_WIDTH = 200; +static const uint32_t APP_NAME_HEIGHT = 60; +// 三方消息主题 +static const uint32_t MSG_TITLE_POS_X = 81; +static const uint32_t MSG_TITLE_POS_Y = 122; +static const uint32_t MSG_TITLE_WIDTH = 409; +static const uint32_t MSG_TITLE_HEIGHT = 83; +// 三方消息内容 +static const uint32_t MSG_CONTENT_POS_X = 78; +static const uint32_t MSG_CONTENT_POS_Y = 176; +static const uint32_t MSG_CONTENT_WIDTH = 457; +static const uint32_t MSG_CONTENT_HEIGHT = 269; +// 取消通知 +static const uint32_t CANCEL_BUTTON_POS_X = 150; +static const uint32_t CANCEL_BUTTON_POS_Y = 323; +static const uint32_t CANCEL_BUTTON_WIDTH = 165; +static const uint32_t CANCEL_BUTTON_HEIGHT = 44; + +// 设置字体大小 +static const uint32_t APP_NAME_FONT_SIZE = 20; +static const uint32_t MSG_TITLE_FONT_SIZE = 20; +static const uint32_t MSG_CONTENT_FONT_SIZE = 40; + +UIViewGroup *PhoneMsgView::phoneMsgView_ = nullptr; +UILabel *PhoneMsgView::appNameLabel_ = nullptr; +UILabel *PhoneMsgView::titleLabel_ = nullptr; +UILabel *PhoneMsgView::contentLabel_ = nullptr; +GraphicTimer *PhoneMsgView::phoneMsgNotifyStop_ = nullptr; +PhoneMsg PhoneMsgView::phoneMsg_; +UILabelButtonExt *PhoneMsgView::cancelButton_ = nullptr; + +void PhoneMsgStopNotifyCallback(void *data) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PhoneMsgStopNotifyCallback"); + (void)data; + NotificationManager::GetInstance()->StopNotify(); +} + +void PhoneMsgView::StartPhoneMsgTimer(int32_t interval) +{ + uint32_t tick = GetOSTick(interval); + phoneMsgNotifyStop_ = new GraphicTimer(tick, PhoneMsgStopNotifyCallback, nullptr, true); + phoneMsgNotifyStop_->Start(); +} + +void PhoneMsgView::DisablePhoneMsgTimer() +{ + if (phoneMsgNotifyStop_ != nullptr) { + phoneMsgNotifyStop_->Stop(); + delete phoneMsgNotifyStop_; + phoneMsgNotifyStop_ = nullptr; + } +} + +UIViewGroup *PhoneMsgView::CreatePhoneMsgView() +{ + if (phoneMsgView_ == nullptr) { + phoneMsgView_ = new UIViewGroup(); + phoneMsgView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + phoneMsgView_->SetViewId("phoneMsgView"); + } + + if (appNameLabel_ == nullptr) { + appNameLabel_ = new UILabel(); + } + appNameLabel_->SetPosition(APP_NAME_POS_X, APP_NAME_POS_Y, APP_NAME_WIDTH, APP_NAME_HEIGHT); + appNameLabel_->SetText(phoneMsg_.appName.c_str()); + appNameLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, APP_NAME_FONT_SIZE); + appNameLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + // Add to rootView + phoneMsgView_->Add(appNameLabel_); + appNameLabel_->SetVisible(true); + + if (titleLabel_ == nullptr) { + titleLabel_ = new UILabel(); + } + titleLabel_->SetPosition(MSG_TITLE_POS_X, MSG_TITLE_POS_Y, MSG_TITLE_WIDTH, MSG_TITLE_HEIGHT); + titleLabel_->SetText(phoneMsg_.msgTitle.c_str()); + titleLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, MSG_TITLE_FONT_SIZE); + titleLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + // Add to rootView + phoneMsgView_->Add(titleLabel_); + titleLabel_->SetVisible(true); + + if (contentLabel_ == nullptr) { + contentLabel_ = new UILabel(); + } + contentLabel_->SetPosition(MSG_CONTENT_POS_X, MSG_CONTENT_POS_Y, MSG_CONTENT_WIDTH, MSG_CONTENT_HEIGHT); + contentLabel_->SetText(phoneMsg_.msgContent.c_str()); + contentLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, MSG_CONTENT_FONT_SIZE); + contentLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + // Add to rootView + phoneMsgView_->Add(contentLabel_); + contentLabel_->SetVisible(true); + + if (cancelButton_ == nullptr) { + cancelButton_ = new UILabelButtonExt(); + } + cancelButton_->SetPosition(CANCEL_BUTTON_POS_X, CANCEL_BUTTON_POS_Y, CANCEL_BUTTON_WIDTH, CANCEL_BUTTON_HEIGHT); + cancelButton_->SetViewId("cancelButton"); + cancelButton_->SetText("取消通知"); + cancelButton_->SetTouchable(true); + cancelButton_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, APP_NAME_FONT_SIZE); + // Add to rootView + phoneMsgView_->Add(cancelButton_); + + phoneMsgView_->SetDraggable(true); + phoneMsgView_->SetTouchable(true); + UIView::OnDragListener *dragListener = + static_cast(PhoneMsgViewEventListener::GetInstance()); + UIView::OnClickListener *clickListener = + static_cast(PhoneMsgViewEventListener::GetInstance()); + phoneMsgView_->SetOnDragListener(dragListener); + phoneMsgView_->SetOnClickListener(clickListener); + cancelButton_->SetOnClickListener(clickListener); + StartPhoneMsgTimer(PhoneMsgView::notifyTime); + NotificationManager::GetInstance()->RegisterNotifyCleanupFunction(FreePhoneMsgView); + return phoneMsgView_; +} + +void PhoneMsgView::FreePhoneMsgView(void) +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FreePhoneMsgView"); + if (phoneMsgView_ != nullptr) { + DisablePhoneMsgTimer(); + phoneMsgView_->RemoveAll(); + delete appNameLabel_; + appNameLabel_ = nullptr; + delete titleLabel_; + titleLabel_ = nullptr; + delete contentLabel_; + contentLabel_ = nullptr; + delete cancelButton_; + cancelButton_ = nullptr; + RootView::GetInstance()->Remove(phoneMsgView_); + delete phoneMsgView_; + phoneMsgView_ = nullptr; + } +} + +void PhoneMsgView::UpDatePhoneMsg(std::string appName, std::string titile, std::string content) +{ + phoneMsg_.appName = appName; + phoneMsg_.msgTitle = titile; + phoneMsg_.msgContent = content; + MessageModel::GetInstance().GetMessageInfo(appName, titile, content); +} + +PhoneMsgViewEventListener::PhoneMsgViewEventListener() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PhoneMsgViewEventListener :%p", this); +} + +PhoneMsgViewEventListener::~PhoneMsgViewEventListener() +{ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "~PhoneMsgViewEventListener"); +} + +PhoneMsgViewEventListener *PhoneMsgViewEventListener::GetInstance(void) +{ + static PhoneMsgViewEventListener phoneMsgViewEventListener; + return &phoneMsgViewEventListener; +} + +bool PhoneMsgViewEventListener::OnDrag(UIView &view, const DragEvent &event) +{ + return true; +} + +bool PhoneMsgViewEventListener::OnDragEnd(UIView &view, const DragEvent &event) +{ + std::string viewId = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PhoneMsgViewEventListener OnDragEnd %s", viewId.c_str()); + if (viewId == "phoneMsgView") { + NotificationManager::GetInstance()->StopNotify(); + } + return true; +} + +bool PhoneMsgViewEventListener::OnClick(UIView &view, const ClickEvent &event) +{ + UNUSED(event); + std::string viewId = view.GetViewId(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PhoneMsgViewEventListener ClickListener %s", viewId.c_str()); + if (viewId == "phoneMsgView") { + NotificationManager::GetInstance()->StopNotify(); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c b/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c index 6f45b72ff..3e2c29d46 100644 --- a/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c +++ b/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c @@ -23,7 +23,7 @@ #include "nandflash_to_os.h" #endif #ifdef SUPPORT_OHOSFWK -#include "ui_screennotify.h" +#include "screennotify/ui_screennotify.h" #endif #include "sys/time.h" #include "touch_screen_def.h" diff --git a/code/sdk/application/wearable/service/remote_msg/CMakeLists.txt b/code/sdk/application/wearable/service/remote_msg/CMakeLists.txt new file mode 100644 index 000000000..f8e5abb7a --- /dev/null +++ b/code/sdk/application/wearable/service/remote_msg/CMakeLists.txt @@ -0,0 +1,37 @@ +set(COMPONENT_NAME "remote_msg") + +set(PUBLIC_HEADER +) + +set(PRIVATE_HEADER + ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits + ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits +) + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/remote_msg.cpp +) + +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -std=c++11 + -Wno-missing-field-initializers +) + +set(WHOLE_LINK + true +) + +set(PUBLIC_DEFINES +) + +set(PRIVATE_DEFINES + APP_PLATFORM_WATCHGT + CONFIG_ACELITE_ENABLE +) + +build_component() + + diff --git a/code/sdk/application/wearable/service/remote_msg/remote_msg.cpp b/code/sdk/application/wearable/service/remote_msg/remote_msg.cpp new file mode 100644 index 000000000..a33965430 --- /dev/null +++ b/code/sdk/application/wearable/service/remote_msg/remote_msg.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. + * Description: ota upgrade handle. + * This file should be changed only infrequently and with great care. + */ +#include +#include "securec.h" +#include "msg_center.h" +#include "msg_center_protocol.h" +#include "msg_center_cmd.h" +#include "wearable_log.h" +#include "securec.h" +#include "msg_center.h" +#include "msg_center_common.h" +#include "ohos_init.h" +#include "remote_msg.h" +#ifdef __cplusplus +extern "C" { +#endif + +static const msg_center_cmd_map_t g_msg_center_phone_msg_tbl[] = { + {MSGCENTER_CMD_PHONE_MSG, MSGCENTER_TYPE_ID_MSG_THIRD_APP, msg_center_phone_msg_rec}, + {MSGCENTER_CMD_PHONE_MSG, MSGCENTER_TYPE_ID_MSG_SMS, msg_center_phone_msg_rec}, + {MSGCENTER_CMD_PHONE_MSG, MSGCENTER_TYPE_ID_MSG_PHONE, msg_center_phone_msg_rec}, +}; + +errcode_t msg_center_phone_msg_rec(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data); + uint16_t payload_len = usr_len - tl_len; + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); + errcode_t ret = ERRCODE_SUCC; + uint8_t msg_result = 0; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_phone_msg_rec, cmd_id = %d, type = %d\r\n", cmd_id, type); + Request request; + request.msgId = type; + request.len = payload_len; + request.data = tlv_payload; + MsgCenterNotifyProc(TOPIC_DEMO_ALL_MSG, &request); + ret = msg_center_send_data(cmd_id, type, &msg_result, sizeof(msg_result)); + if (ret != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "phone msg_result fail, ret = %d\r\n", ret); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + +errcode_t msg_center_phone_msg_type_dispatch(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) +{ + WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_phone_msg_type_dispatch, cmd_id = %d, type = %d\r\n", + cmd_id, type); + uint8_t tbl_size = sizeof(g_msg_center_phone_msg_tbl) / sizeof(g_msg_center_phone_msg_tbl[0]); + uint8_t i; + for (i = 0; i < tbl_size; i++) { + msg_center_cmd_map_t *item = (msg_center_cmd_map_t *)&g_msg_center_phone_msg_tbl[i]; + if ((item->type == type) && (item->handler != NULL)) { + item->handler(cmd_id, type, usr_data, usr_len); + return ERRCODE_SUCC; + } + } + return ERRCODE_NOT_SUPPORT; +} + +void phone_msg_init(void) +{ + msg_center_register_cmd(MSGCENTER_CMD_PHONE_MSG, msg_center_phone_msg_type_dispatch); +} + +APP_FEATURE_INIT_PRI(phone_msg_init, LAYER_INIT_LEVEL_4); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/service/remote_msg/remote_msg.h b/code/sdk/application/wearable/service/remote_msg/remote_msg.h new file mode 100644 index 000000000..2787377ff --- /dev/null +++ b/code/sdk/application/wearable/service/remote_msg/remote_msg.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: third application message + * Author: CompanyName + * Create: 2021-11-11 + */ + +#ifndef REMOTE_MSG_H +#define REMOTE_MSG_H + +#include "msg_center_protocol.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef enum msg_center_phone_msg_type_id { + MSGCENTER_TYPE_ID_MSG_THIRD_APP = 0x1, // 三方应用消息 + MSGCENTER_TYPE_ID_MSG_SMS, // 短信 + MSGCENTER_TYPE_ID_MSG_PHONE, // 电话 + MSGCENTER_TYPE_ID_MSG_MAX, +} msg_center_msg_notify_type_id_t; + +errcode_t msg_center_phone_msg_rec(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif /* REMOTE_MSG_H */ \ No newline at end of file diff --git a/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice.cpp b/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice.cpp index 6ca6ae711..9e88a4365 100644 --- a/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice.cpp +++ b/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice.cpp @@ -20,6 +20,9 @@ #include "watchdog.h" #include "js_ability.h" #include "recording_module.h" +#ifdef CONFIG_BRANDY_BLE_TRANS_OPTIMIZE +#include "bluetooth/BluetoothChangeBle.h" +#endif #ifdef __cplusplus extern "C" { @@ -62,6 +65,43 @@ static void pcm_stream_del_queue(void) return; } +static errcode_t send_pcm_stream_data(pcm_stream_queue_msg msg) +{ + uint8_t retry_cnt = 100; + uint8_t msg_send_delay = 10; + errcode_t res; + + while (retry_cnt--) { + if (msg.msg_id == MSGCENTER_TYPE_ID_XIAODU_SEND_PCM_STREAM) { + res = msg_center_xiaodu_send_pcm_stream(MSGCENTER_CMD_XIAODU, MSGCENTER_TYPE_ID_XIAODU_SEND_PCM_STREAM, + msg.data, msg.len); + } else if (msg.msg_id == MSGCENTER_TYPE_ID_XIAODU_END_RECORD) { + res = msg_center_xiaodu_send_end_record(MSGCENTER_CMD_XIAODU, MSGCENTER_TYPE_ID_XIAODU_END_RECORD, msg.data, + msg.len); +#ifdef CONFIG_BRANDY_BLE_TRANS_OPTIMIZE + ChangeBleConnectToDefault(); +#endif + } + + if (res != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send stream fail, retry_cnt: %d, type = %d\n", retry_cnt, + msg.msg_id); + osDelay(msg_send_delay); + } else { + break; + } + } + free(msg.data); + msg.data = nullptr; + if (res != ERRCODE_SUCC) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "after retry, send stream still fail, retry_cnt: %d, type = %d\n", + retry_cnt, msg.msg_id); + pcm_stream_del_queue(); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + static errcode_t pcm_stream_task_body(void *data) { UNUSED(data); @@ -75,39 +115,22 @@ static errcode_t pcm_stream_task_body(void *data) } g_pcm_stream_end_record_sended_flag = false; +#ifdef CONFIG_BRANDY_BLE_TRANS_OPTIMIZE + ChangeBleConnectToMax(); +#endif for (;;) { osStatus_t ret = osMessageQueueGet(g_pcm_stream_msg_queue_id, &msg, nullptr, osWaitForever); if (ret != osOK) { - msg.msg_id = MSGCENTER_TYPE_ID_XIAODU_END_RECORD; - msg.data = nullptr; + continue; } - if (msg.msg_id == MSGCENTER_TYPE_ID_XIAODU_SEND_PCM_STREAM) { - res = msg_center_xiaodu_send_pcm_stream(MSGCENTER_CMD_XIAODU, MSGCENTER_TYPE_ID_XIAODU_SEND_PCM_STREAM, - msg.data, msg.len); - free(msg.data); - msg.data = nullptr; - if (res != ERRCODE_SUCC) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send pcm stream failed"); - pcm_stream_del_queue(); - return ERRCODE_FAIL; - } - } else if (msg.msg_id == MSGCENTER_TYPE_ID_XIAODU_END_RECORD) { - res = msg_center_xiaodu_send_end_record(MSGCENTER_CMD_XIAODU, MSGCENTER_TYPE_ID_XIAODU_END_RECORD, msg.data, - msg.len); - free(msg.data); - msg.data = nullptr; - if (res != ERRCODE_SUCC) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "send pcm end failed"); - pcm_stream_del_queue(); - return ERRCODE_FAIL; - } - g_pcm_stream_end_record_sended_flag = true; - return ERRCODE_SUCC; + + /* pcm帧、end帧合并处理 */ + res = send_pcm_stream_data(msg); + if (res == ERRCODE_FAIL || (res == ERRCODE_SUCC && msg.msg_id == MSGCENTER_TYPE_ID_XIAODU_END_RECORD)) { + return res; } } - - return ERRCODE_SUCC; } /* @@ -163,7 +186,6 @@ errcode_t pcm_stream_create_task(void) errcode_t msg_center_xiaodu_start(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len) { - unused(usr_data); uint8_t ack = 1; errcode_t ret = ERRCODE_SUCC; @@ -174,16 +196,21 @@ errcode_t msg_center_xiaodu_start(uint8_t cmd_id, uint8_t type, void *usr_data, } display_api->set_screen_set_keepon_timeout(30000); // 30000ms #endif -#ifdef JS_ENABLE - StartJsApp("com.vendor.voiceassistant"); -#endif /* ack */ ret = msg_center_send_data(cmd_id, type, &ack, sizeof(ack)); if (ret != ERRCODE_SUCC) { return ERRCODE_FAIL; } + uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data); +#ifdef JS_ENABLE + if(tlv_payload[0] == 1) { + StartJsApp("com.vendor.Aidialogue"); + } else { + StartJsApp("com.vendor.Aidial"); + } +#endif return ERRCODE_SUCC; } @@ -407,6 +434,7 @@ errcode_t msg_center_xiaodu_send_end_record(uint8_t cmd_id, uint8_t type, void * WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "send pcm stream end, usr_data = %d, usr_len = %d\r\n", *(uint8_t *)usr_data, usr_len); /* usr_data参考协议msg_center_pcm_end_flag_t */ pcm_stream_del_queue(); + g_pcm_stream_end_record_sended_flag = true; return ERRCODE_SUCC; } diff --git a/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice_msg.cpp b/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice_msg.cpp index ebe9e4086..1d3047a54 100644 --- a/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice_msg.cpp +++ b/code/sdk/application/wearable/service/xiaodu_voice/xiaodu_voice_msg.cpp @@ -3,6 +3,9 @@ #include "msg_center_protocol.h" #include "msg_center_cmd.h" #include "ohos_init.h" +#include "msg_center_common.h" +#include "wearable_log.h" + namespace OHOS { #ifdef __cplusplus -- 2.17.1