diff --git a/application/AppScope/app.json b/application/AppScope/app.json index d98cf43d465e75a9327e0b0741870def01cb03de..1575faf16e305bf3e84735290661312338e922fc 100644 --- a/application/AppScope/app.json +++ b/application/AppScope/app.json @@ -2,8 +2,8 @@ "app": { "bundleName": "com.ohos.dhardwareui", "vendor": "example", - "versionCode": 10000043, - "versionName": "1.0.43", + "versionCode": 10000044, + "versionName": "1.0.44", "icon": "$media:app_icon", "label": "$string:app_name", "minAPIVersion": 12, diff --git a/application/AppScope/app.json5 b/application/AppScope/app.json5 index 6f9175cb4395e374d5f743b05aff4792e2a08e2b..b5e6fcb3370c5bdac068960b0dc3256901514a2c 100644 --- a/application/AppScope/app.json5 +++ b/application/AppScope/app.json5 @@ -16,8 +16,8 @@ "app": { "bundleName": "com.ohos.dhardwareui", "vendor": "example", - "versionCode": 10000043, - "versionName": "1.0.43", + "versionCode": 10000044, + "versionName": "1.0.44", "icon": "$media:app_icon", "label": "$string:app_name", "minAPIVersion": 12, diff --git a/application/entry/src/main/ets/common/constants/CommonConstants.ets b/application/entry/src/main/ets/common/constants/CommonConstants.ets index 1912d5e5fa9b8d9415e1b7a1cdf92b14d66bd493..3207450acee9fda5dd0c6c0c283cd704ccebfc32 100644 --- a/application/entry/src/main/ets/common/constants/CommonConstants.ets +++ b/application/entry/src/main/ets/common/constants/CommonConstants.ets @@ -58,6 +58,122 @@ export default class CommonConstants { public static readonly MIRROR_LANGUAGES: Array = ['ug', 'ar']; // isTibetanLanguages public static readonly TIBETAN_LANGUAGES: Array = ['bo']; + + /** + * Button click Scale. + */ + public static readonly BUTTON_CLICK_SCALE: number = 0.9; + + /** + * Animation duration. + */ + public static readonly ANIMATE_DURATION: number = 150; + + /** + * Line height. + */ + public static readonly LINE_HEIGHT: number = 16; + + /** + * Text Margin top 4. + */ + public static readonly TEXT_MARGIN_TOP: number = 4; + + /** + * Text Margin left 20. + */ + public static readonly TEXT_MARGIN_LEFT: number = 20; + + /** + * Text Max font size. + */ + public static readonly MAX_FONT_SCALE: number = 1.5; + + /** + * Left Icon margin left. + */ + public static readonly LEFT_ICON_MARGIN_LEFT: number = 30; + + /** + * Other layout Icon margin left. + */ + public static readonly OTHER_ICON_MARGIN_LEFT: number = 36; + + /** + * Switch icon size. + */ + public static readonly SWITCH_ICON_SIZE: number = 20; + + /** + * Switch icon margin. + */ + public static readonly SWITCH_ICON_MARGIN: number = 3; + + /** + * Small line height. + */ + public static readonly SMALL_LINE_HEIGHT: number = 13; + + /** + * Button size. + */ + public static readonly BUTTON_SIZE: string = '40vp'; + + /** + * Small text margin top. + */ + public static readonly SMALL_TEXT_MARGIN_TOP: number = 2; + + /** + * Translate x distance. + */ + public static readonly TRANSLATE_X: number = 60; + + /** + * Animation springMotion response. + */ + public static readonly SPRING_MOTION_RESPONSE: number = 0.55; + + /** + * Animation springMotion dampingFraction. + */ + public static readonly SPRING_MOTION_DAMPING_FRACTION: number = 0.825; + + /** + * Animation springMotion overlapDuration. + */ + public static readonly SPRING_MOTION_OVERLAP_DURATION: number = 0.15; + + /** + * Normal switch margin left. + */ + public static readonly NORMAL_SWITCH_MARGIN_LEFT: number = 60; + + /** + * Max scale switch margin left. + */ + public static readonly MAX_SWITCH_MARGIN_LEFT: number = 75; + + /** + * Normal Layout margin left. + */ + public static readonly NORMAL_LAYOUT_MARGIN_LEFT: number = 55; + + /** + * Max Layout margin left. + */ + public static readonly MAX_LAYOUT_MARGIN_LEFT: number = 65; + + /** + * Bundle name. + */ + public static readonly BUNDLE_NAME: string = 'com.ohos.dhardwareui'; + + /** + * Switch off offset. + */ + public static readonly SWITCH_OFF_OFFSET: number = 4; + } export enum FontSizeScale { @@ -70,4 +186,4 @@ export enum FontSizeScale { XXL1 = 1.75, XXL2 = 2, XXL3 = 3.2, -} \ No newline at end of file +} diff --git a/application/entry/src/main/ets/mechextability/MechExtAbility.ets b/application/entry/src/main/ets/mechextability/MechExtAbility.ets index 2f91fdad346a27a0f9381ae280657ce1fd362060..e374d69d10d0bd3ad3113f5886df298900647f62 100644 --- a/application/entry/src/main/ets/mechextability/MechExtAbility.ets +++ b/application/entry/src/main/ets/mechextability/MechExtAbility.ets @@ -16,12 +16,52 @@ import UIExtensionAbility from '@ohos.app.ability.UIExtensionAbility'; import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; import Want from '@ohos.app.ability.Want'; import { logger } from '../utils/Logger'; +import mechanicManager from '@ohos.distributedHardware.mechanicManager'; +import { BusinessError } from '@ohos.base'; const TAG: string = '[MechExtAbility]'; export default class MechExtAbility extends UIExtensionAbility { + private callback = (result: mechanicManager.TrackingEventInfo) => { + logger.info(`${TAG} result.event = ${result.event}`); + if (result.event === mechanicManager.TrackingEvent.CAMERA_TRACKING_USER_ENABLED) { + mechanicManager.setCameraTrackingEnabled(true); + AppStorage.set('isTrackingEnabled', true); + } else if (result.event === mechanicManager.TrackingEvent.CAMERA_TRACKING_USER_DISABLED) { + mechanicManager.setCameraTrackingEnabled(false); + AppStorage.set('isTrackingEnabled', false); + } + logger.info(`${TAG}trackingStateChange callback end, AppStorage.get(isTrackingEnabled) = + ${AppStorage.get('isTrackingEnabled')}`); + }; + + onTrackingStateChange() { + logger.info(`${TAG} onTrackingStateChange in`); + try { + mechanicManager.on('trackingStateChange', this.callback); + } catch (error) { + let code: number = error.code; + let message: string = error.message; + logger.error(`${TAG}trackingStateChange on failed. error.code: ${code}, message: ${message}`); + } + } + + offTrackingStateChange() { + logger.info(`${TAG} offTrackingStateChange in`); + try { + mechanicManager.off('trackingStateChange', this.callback); + } catch (error) { + let code: number = (error as BusinessError).code; + let message: string = (error as BusinessError).message; + logger.error(`${TAG}trackingStateChange off failed. error.code: ${code}, message: ${message}`); + } + } + onCreate() { logger.info(`${TAG} UIExtAbility onCreate`); + AppStorage.setOrCreate('isTrackingEnabled', true); + AppStorage.setOrCreate('currentLayout', mechanicManager.CameraTrackingLayout.DEFAULT); + this.onTrackingStateChange(); } onForeground() { @@ -34,10 +74,12 @@ export default class MechExtAbility extends UIExtensionAbility { onDestroy() { logger.info(`${TAG} UIExtAbility onDestroy`); + this.offTrackingStateChange(); } onSessionCreate(want: Want, session: UIExtensionContentSession) { logger.info(`${TAG} UIExtAbility onSessionCreate.`); + let param: Record = { 'session': session }; diff --git a/application/entry/src/main/ets/pages/MechControl.ets b/application/entry/src/main/ets/pages/MechControl.ets index 674a61aaecc149cc0c40ace72be004ac056cb737..9334de86933b243dd17539ff9eb104ccd711e9bc 100644 --- a/application/entry/src/main/ets/pages/MechControl.ets +++ b/application/entry/src/main/ets/pages/MechControl.ets @@ -12,125 +12,256 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { logger } from '../utils/Logger'; import mechanicManager from '@ohos.distributedHardware.mechanicManager'; import { BusinessError } from '@ohos.base'; +import router from '@ohos.router'; +import curves from '@ohos.curves'; +import accessibility from '@ohos.accessibility'; +import common from '@ohos.app.ability.common'; +import CommonConstants,{ FontSizeScale } from '../common/constants/CommonConstants'; const TAG = '[MechControl_Page] : '; +let localStorage = LocalStorage.getShared(); -@Entry +@Entry(localStorage) @Component struct MechControl { - @State isTrackingEnabled: boolean = false; - @State currentTrackingLayoutText: ResourceStr = $r('app.string.mech_center'); - @State currentTrackingLayoutImage: ResourceStr = $r('app.media.track_layout_center'); + @StorageLink('isTrackingEnabled') @Watch('onSwitchChange') isTrackingEnabled: boolean = + this.getDefaultValue('isTrackingEnabled', true); + @StorageLink('currentLayout') @Watch('onLayoutChange') currentLayout: mechanicManager.CameraTrackingLayout = + this.getDefaultValue('currentLayout', mechanicManager.CameraTrackingLayout.DEFAULT); + @StorageLink('currentTrackingLayoutText') currentTrackingLayoutText: ResourceStr = $r('app.string.mech_center'); + @StorageLink('currentTrackingLayoutImage') currentTrackingLayoutImage: ResourceStr = + $r('app.media.track_layout_center'); + @State fontSizeScale: number = AppStorage.get('currentFontSizeScale') as number; + private context = getContext(this) as common.UIAbilityContext; + + private getDefaultValue(key: string, defaultValue: T): T { + const value = AppStorage.get(key); + return value !== undefined ? value : defaultValue; + } + + pageTransition() { + PageTransitionEnter({ type: RouteType.None, duration: 0 }) + PageTransitionExit({ type: RouteType.None, duration: 0 }) + } + + onSwitchChange() { + logger.info(`${TAG} onSwitchChange in`); + } + + onLayoutChange() { + logger.info(`${TAG} onLayoutChange in`); + switch (this.currentLayout) { + case mechanicManager.CameraTrackingLayout.DEFAULT: + case mechanicManager.CameraTrackingLayout.MIDDLE: { + this.currentTrackingLayoutImage = $r('app.media.track_layout_center'); + this.currentTrackingLayoutText = $r('app.string.mech_center'); + break; + } + case mechanicManager.CameraTrackingLayout.LEFT: { + this.currentTrackingLayoutImage = $r('app.media.track_layout_left'); + this.currentTrackingLayoutText = $r('app.string.mech_left'); + break; + } + case mechanicManager.CameraTrackingLayout.RIGHT: { + this.currentTrackingLayoutImage = $r('app.media.track_layout_right'); + this.currentTrackingLayoutText = $r('app.string.mech_right'); + break; + } + } + } + + toggleEffectChange(){ + logger.info(`${TAG} toggleEffectChange in`); + const originalState = this.isTrackingEnabled; + try { + if (!this.isTrackingEnabled) { + logger.info(`${TAG} enable camera tracking`); + mechanicManager.setCameraTrackingEnabled(true); + this.isTrackingEnabled = true; + } else { + logger.info(`${TAG} disable camera tracking`); + mechanicManager.setCameraTrackingEnabled(false); + this.isTrackingEnabled = false; + } + } catch (error) { + let code: number = (error as BusinessError).code; + let message: string = (error as BusinessError).message; + logger.error(`${TAG} setUserOperation switch failed. error.code: ${code}, message: ${message}`); + this.isTrackingEnabled = originalState; + } + } + getSwitchStateInfo(isTrackingEnabled: boolean): string { + if (isTrackingEnabled) { + logger.info(`SwitchState is on. isTrackingEnabled: ${isTrackingEnabled}`); + return this.context.resourceManager.getStringSync($r('app.string.audio_tracking_switch_on').id); + } else { + logger.info(`SwitchState is off. isTrackingEnabled: ${isTrackingEnabled}`); + return this.context.resourceManager.getStringSync($r('app.string.audio_tracking_switch_off').id); + } + } aboutToAppear() { logger.info(`${TAG} aboutToAppear in`); + this.fontSizeScale = this.context.config?.fontSizeScale ?? FontSizeScale.DEFAULT; + logger.info(`${TAG} this.fontSizeScale: ${this.fontSizeScale}`); + try { + this.isTrackingEnabled = mechanicManager.getCameraTrackingEnabled(); + } catch (error) { + let code: number = (error as BusinessError).code; + let message: string = (error as BusinessError).message; + logger.error(`${TAG} getCameraTrackingEnabled failed. error.code: ${code}, message: ${message}`); + this.isTrackingEnabled = this.getDefaultValue('isTrackingEnabled', true); + } + + try { + this.currentLayout = mechanicManager.getCameraTrackingLayout(); + } catch (error) { + let code: number = (error as BusinessError).code; + let message: string = (error as BusinessError).message; + logger.error(`${TAG} getCameraTrackingLayout failed. error.code: ${code}, message: ${message}`); + this.currentLayout = mechanicManager.CameraTrackingLayout.DEFAULT; + } + logger.info(`${TAG} aboutToAppear end. isTrackingEnabled: ${this.isTrackingEnabled}, currentLayout: ${this.currentLayout}`); + } + + aboutToDisappear(): void { + logger.info(`${TAG} aboutToDisappear in`); } @Builder - IntelligentTracking(){ - Column(){ + IntelligentTracking() { + Column() { Button() { - Image(this.isTrackingEnabled ? $r('app.media.intelligent_tracking') :$r('app.media.intelligent_tracking_dark')) - .width(20) - .height(20) - .margin({left: 3, top: 3}) + Image(this.isTrackingEnabled ? $r('app.media.intelligent_tracking') : $r('app.media.intelligent_tracking_dark')) + .width(CommonConstants.SWITCH_ICON_SIZE) + .height(CommonConstants.SWITCH_ICON_SIZE) + .margin({ left: CommonConstants.SWITCH_ICON_MARGIN, top: CommonConstants.SWITCH_ICON_MARGIN }) } - .width('40vp') - .height('40vp') - .backgroundColor(this.isTrackingEnabled ? $r('app.color.color_0A59F7_blue') : $r('sys.color.ohos_id_color_component_normal')) + .width(CommonConstants.BUTTON_SIZE) + .height(CommonConstants.BUTTON_SIZE) + .backgroundColor(this.isTrackingEnabled ? $r('app.color.color_0A59F7_blue') : + $r('sys.color.ohos_id_color_component_normal')) + .accessibilityText($r('app.string.mech_intelligent_tracking')) + .type(ButtonType.Circle) + .clickEffect({ level: ClickEffectLevel.LIGHT, scale: CommonConstants.BUTTON_CLICK_SCALE }) .onClick(() => { - const originalState = this.isTrackingEnabled; + this.toggleEffectChange(); try { - if (!this.isTrackingEnabled) { - logger.info(`${TAG} enable camera tracking`); - mechanicManager.setCameraTrackingEnabled(true); - this.isTrackingEnabled = true; - } else { - logger.info(`${TAG} disable camera tracking`); - mechanicManager.setCameraTrackingEnabled(false); - this.isTrackingEnabled = false; - } + let eventInfo: accessibility.EventInfo = ({ + type: 'announceForAccessibility', + bundleName: CommonConstants.BUNDLE_NAME, + triggerAction: 'click', + textAnnouncedForAccessibility: this.getSwitchStateInfo(this.isTrackingEnabled) + }); + accessibility.sendAccessibilityEvent(eventInfo).then(() => { + logger.info(`Succeeded in send event, eventInfo is ${JSON.stringify(eventInfo)}`); + }).catch((err: Error) => { + logger.error('Failed to send accessibility event'); + }); } catch (error) { let code: number = (error as BusinessError).code; let message: string = (error as BusinessError).message; - logger.error(`${TAG} setCameraTrackingEnabled failed. error.code: ${code}, message: ${message}`); - this.isTrackingEnabled = originalState; + logger.error(`${TAG} sendAccessibilityEvent failed,error code: ${code},message: ${message}.`); } logger.info(`${TAG} onClick end, isTrackingEnabled = ${this.isTrackingEnabled}`); }) Text($r('app.string.mech_intelligent_tracking')) - .fontSize(12) - .lineHeight(16) + .fontSize($r('sys.float.ohos_id_text_size_body3')) + .lineHeight(CommonConstants.LINE_HEIGHT) .fontWeight(FontWeight.Medium) - .fontColor($r('app.color.color_black')) - .margin({ left: 0, top: 4, right: 0 }) + .fontColor($r('sys.color.font_primary')) + .margin({ top: CommonConstants.TEXT_MARGIN_TOP }) .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) - Text(this.isTrackingEnabled ? $r('app.string.mech_enable'): $r('app.string.mech_close')) - .fontSize(10) - .lineHeight(13) + Text(this.isTrackingEnabled ? $r('app.string.mech_enable') : $r('app.string.mech_close')) + .fontSize($r('sys.float.Caption_M')) + .lineHeight(CommonConstants.SMALL_LINE_HEIGHT) .fontWeight(FontWeight.Regular) - .fontColor($r('app.color.color_black')) - .margin({ top: 2 }) + .fontColor($r('sys.color.font_secondary')) + .margin({ top: CommonConstants.SMALL_TEXT_MARGIN_TOP }) .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) } + .transition(TransitionEffect.OPACITY.animation({ duration: CommonConstants.ANIMATE_DURATION, curve: Curve.Sharp })) + .translate({ x: this.isTrackingEnabled ? 0 : CommonConstants.TRANSLATE_X }) + .animation({ + curve: curves.springMotion(CommonConstants.SPRING_MOTION_RESPONSE, + CommonConstants.SPRING_MOTION_DAMPING_FRACTION, CommonConstants.SPRING_MOTION_OVERLAP_DURATION) + }) + .margin({ + left: this.isTrackingEnabled ? + (this.fontSizeScale > FontSizeScale.XL ? CommonConstants.NORMAL_SWITCH_MARGIN_LEFT : + CommonConstants.MAX_SWITCH_MARGIN_LEFT) : + (this.fontSizeScale > FontSizeScale.XL ? CommonConstants.NORMAL_SWITCH_MARGIN_LEFT : + CommonConstants.MAX_SWITCH_MARGIN_LEFT) - CommonConstants.SWITCH_OFF_OFFSET + }) } @Builder - TrackingLayout(){ - Column(){ + TrackingLayout() { + Column() { Button() { Image(this.currentTrackingLayoutImage) - .width(20) - .height(20) + .width(CommonConstants.SWITCH_ICON_SIZE) + .height(CommonConstants.SWITCH_ICON_SIZE) } - .width('40vp') - .height('40vp') + .width(CommonConstants.BUTTON_SIZE) + .height(CommonConstants.BUTTON_SIZE) + .accessibilityText($r('app.string.mech_tracking_layout')) .backgroundColor($r('app.color.color_0A59F7_blue')) + .type(ButtonType.Circle) + .clickEffect({ level: ClickEffectLevel.LIGHT, scale: CommonConstants.BUTTON_CLICK_SCALE }) .onClick(() => { logger.info(`${TAG} onClick TrackingLayout in`); + router.pushUrl({ url: 'pages/TrackingLayout' }, () => { + }) }) Text($r('app.string.mech_tracking_layout')) - .fontSize(12) - .lineHeight(16) + .fontSize($r('sys.float.ohos_id_text_size_body3')) + .lineHeight(CommonConstants.LINE_HEIGHT) .fontWeight(FontWeight.Medium) - .fontColor($r('app.color.color_black')) - .margin({ left: 0, top: 4, right: 0 }) + .fontColor($r('sys.color.font_primary')) + .margin({ top: CommonConstants.TEXT_MARGIN_TOP }) .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) Text(this.currentTrackingLayoutText) - .fontSize(10) - .lineHeight(13) + .fontSize($r('sys.float.Caption_M')) + .lineHeight(CommonConstants.SMALL_LINE_HEIGHT) .fontWeight(FontWeight.Regular) - .fontColor($r('app.color.color_black')) - .margin({ top: 2 }) + .fontColor($r('sys.color.font_secondary')) + .margin({ top: CommonConstants.SMALL_TEXT_MARGIN_TOP }) .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) } + .transition(TransitionEffect.OPACITY.animation({ duration: CommonConstants.ANIMATE_DURATION, curve: Curve.Sharp })) + .margin({ + left: this.fontSizeScale > FontSizeScale.DEFAULT ? CommonConstants.NORMAL_LAYOUT_MARGIN_LEFT : + CommonConstants.MAX_LAYOUT_MARGIN_LEFT + }) } build() { Column() { + Row() { + this.IntelligentTracking(); - Flex({ - direction: FlexDirection.Row, - justifyContent: FlexAlign.SpaceEvenly, - alignItems: ItemAlign.Center - }) { - this.IntelligentTracking(); + if (this.isTrackingEnabled) { + this.TrackingLayout(); + } - if (this.isTrackingEnabled) { - this.TrackingLayout(); } - } - .width('100%') - .height('100%') - + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Start) } .width('100%') .height('100%') diff --git a/application/entry/src/main/ets/pages/TrackingLayout.ets b/application/entry/src/main/ets/pages/TrackingLayout.ets new file mode 100644 index 0000000000000000000000000000000000000000..36ed03ed059e0a1ce61900aa24cb88724150c01b --- /dev/null +++ b/application/entry/src/main/ets/pages/TrackingLayout.ets @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +import { logger } from '../utils/Logger'; +import router from '@ohos.router'; +import mechanicManager from '@ohos.distributedHardware.mechanicManager'; +import { BusinessError } from '@ohos.base'; +import CommonConstants from '../common/constants/CommonConstants'; + +const TAG = '[TrackingLayout_Page] : '; +let localStorage = LocalStorage.getShared(); + +@Entry(localStorage) +@Component +struct TrackingLayout { + @State trackingLayoutLeftImage: ResourceStr = $r('app.media.track_layout_left'); + @State trackingLayoutRightImage: ResourceStr = $r('app.media.track_layout_right'); + @State trackingLayoutCenterImage: ResourceStr = $r('app.media.track_layout_center'); + @StorageLink('currentTrackingLayoutText') currentTrackingLayoutText: ResourceStr = $r('app.string.mech_center'); + @StorageLink('currentTrackingLayoutImage') currentTrackingLayoutImage: ResourceStr = + $r('app.media.track_layout_center'); + @StorageLink('currentLayout') @Watch('onLayoutChange') currentLayout: mechanicManager.CameraTrackingLayout = + this.getDefaultValue('currentLayout', mechanicManager.CameraTrackingLayout.DEFAULT);; + @State isIconHover:boolean = false; + @State longPressCanceled: boolean = false; + + private getDefaultValue(key: string, defaultValue: T): T { + const value = AppStorage.get(key); + return value !== undefined ? value : defaultValue; + } + + pageTransition() { + PageTransitionEnter({ type: RouteType.None, duration: 0 }) + PageTransitionExit({ type: RouteType.None, duration: 0 }) + } + + aboutToAppear() { + logger.info(`${TAG} aboutToAppear in. currentLayout: ${this.currentLayout}`); + } + + onLayoutChange() { + logger.info(`${TAG} onLayoutChange in`); + switch (this.currentLayout) { + case mechanicManager.CameraTrackingLayout.DEFAULT: + case mechanicManager.CameraTrackingLayout.MIDDLE: { + this.currentTrackingLayoutImage = $r('app.media.track_layout_center'); + this.currentTrackingLayoutText = $r('app.string.mech_center'); + break; + } + case mechanicManager.CameraTrackingLayout.LEFT: { + this.currentTrackingLayoutImage = $r('app.media.track_layout_left'); + this.currentTrackingLayoutText = $r('app.string.mech_left'); + break; + } + case mechanicManager.CameraTrackingLayout.RIGHT: { + this.currentTrackingLayoutImage = $r('app.media.track_layout_right'); + this.currentTrackingLayoutText = $r('app.string.mech_right'); + break; + } + } + } + + @Builder + BackButton() { + Column() { + Button() { + SymbolGlyph($r('sys.symbol.chevron_backward')) + .fontWeight(FontWeight.Medium) + .fontSize(CommonConstants.SWITCH_ICON_SIZE) + .fontColor([$r('sys.color.ohos_id_color_primary')]) + } + .width(CommonConstants.BUTTON_SIZE) + .height(CommonConstants.BUTTON_SIZE) + .accessibilityText($r('app.string.audio_back')) + .backgroundColor($r('sys.color.ohos_id_color_component_normal')) + .onClick(() => { + logger.info(`${TAG} onClick BackButton`); + router.back(); + }) + .type(ButtonType.Circle) + .clickEffect({ level: ClickEffectLevel.LIGHT, scale: CommonConstants.BUTTON_CLICK_SCALE }) + + Text(' ') + .fontSize($r('sys.float.Body_S')) + .lineHeight(CommonConstants.LINE_HEIGHT) + .fontWeight(FontWeight.Regular) + .fontColor($r('sys.color.font_primary')) + .margin({ top: CommonConstants.TEXT_MARGIN_TOP }) + .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) + } + .transition(TransitionEffect.OPACITY.animation({ duration: CommonConstants.ANIMATE_DURATION, curve: Curve.Sharp })) + .margin({left: CommonConstants.TEXT_MARGIN_LEFT}) + } + + @Builder + TrackingLayoutLeft() { + Column() { + Button() { + Image(this.currentLayout == mechanicManager.CameraTrackingLayout.LEFT ? $r('app.media.track_layout_left') : + $r('app.media.track_layout_left_dark')) + .width(CommonConstants.SWITCH_ICON_SIZE) + .height(CommonConstants.SWITCH_ICON_SIZE) + } + .width(CommonConstants.BUTTON_SIZE) + .height(CommonConstants.BUTTON_SIZE) + .accessibilityText($r('app.string.mech_left')) + .backgroundColor(this.currentLayout == mechanicManager.CameraTrackingLayout.LEFT ? + $r('app.color.color_0A59F7_blue') : $r('sys.color.ohos_id_color_component_normal')) + .onClick(() => { + logger.info(`${TAG} onClick TrackingLayoutLeft in`); + this.onLeftIconClick(); + }) + .type(ButtonType.Circle) + .clickEffect({ level: ClickEffectLevel.LIGHT, scale: CommonConstants.BUTTON_CLICK_SCALE }) + + Text($r('app.string.mech_left')) + .fontSize($r('sys.float.Body_S')) + .lineHeight(CommonConstants.LINE_HEIGHT) + .fontWeight(FontWeight.Regular) + .fontColor($r('sys.color.font_primary')) + .margin({ top: CommonConstants.TEXT_MARGIN_TOP }) + .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) + } + .transition(TransitionEffect.OPACITY.animation({ duration: CommonConstants.ANIMATE_DURATION, curve: Curve.Sharp })) + .margin({ left: CommonConstants.LEFT_ICON_MARGIN_LEFT }) + } + + @Builder + TrackingLayoutCenter() { + Column() { + Button() { + Image((this.currentLayout == mechanicManager.CameraTrackingLayout.MIDDLE || + this.currentLayout == mechanicManager.CameraTrackingLayout.DEFAULT) ? + $r('app.media.track_layout_center') : + $r('app.media.track_layout_center_dark')) + .width(CommonConstants.SWITCH_ICON_SIZE) + .height(CommonConstants.SWITCH_ICON_SIZE) + } + .width(CommonConstants.BUTTON_SIZE) + .height(CommonConstants.BUTTON_SIZE) + .accessibilityText($r('app.string.mech_center')) + .backgroundColor((this.currentLayout == mechanicManager.CameraTrackingLayout.MIDDLE || + this.currentLayout == mechanicManager.CameraTrackingLayout.DEFAULT) ? $r('app.color.color_0A59F7_blue') : + $r('sys.color.ohos_id_color_component_normal')) + .onClick(() => { + logger.info(`${TAG} onClick TrackingLayoutCenter in`); + this.onCenterIconClick(); + }) + .type(ButtonType.Circle) + .clickEffect({ level: ClickEffectLevel.LIGHT, scale: CommonConstants.BUTTON_CLICK_SCALE }) + + Text($r('app.string.mech_center')) + .fontSize($r('sys.float.Body_S')) + .lineHeight(CommonConstants.LINE_HEIGHT) + .fontWeight(FontWeight.Regular) + .fontColor($r('sys.color.font_primary')) + .margin({ top: CommonConstants.TEXT_MARGIN_TOP }) + .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) + } + .transition(TransitionEffect.OPACITY.animation({ duration: CommonConstants.ANIMATE_DURATION, curve: Curve.Sharp })) + .margin({ left: CommonConstants.OTHER_ICON_MARGIN_LEFT }) + } + + @Builder + TrackingLayoutRight() { + Column() { + Button() { + Image(this.currentLayout == mechanicManager.CameraTrackingLayout.RIGHT ? + $r('app.media.track_layout_right') : + $r('app.media.track_layout_right_dark')) + .width(CommonConstants.SWITCH_ICON_SIZE) + .height(CommonConstants.SWITCH_ICON_SIZE) + } + .width(CommonConstants.BUTTON_SIZE) + .height(CommonConstants.BUTTON_SIZE) + .accessibilityText($r('app.string.mech_right')) + .backgroundColor(this.currentLayout == mechanicManager.CameraTrackingLayout.RIGHT ? + $r('app.color.color_0A59F7_blue') : $r('sys.color.ohos_id_color_component_normal')) + .onClick(() => { + logger.info(`${TAG} onClick TrackingLayoutRight in`); + this.onRightIconClick(); + }) + .type(ButtonType.Circle) + .clickEffect({ level: ClickEffectLevel.LIGHT, scale: CommonConstants.BUTTON_CLICK_SCALE }) + + Text($r('app.string.mech_right')) + .fontSize($r('sys.float.Body_S')) + .lineHeight(CommonConstants.LINE_HEIGHT) + .fontWeight(FontWeight.Regular) + .fontColor($r('sys.color.font_primary')) + .margin({ top: CommonConstants.TEXT_MARGIN_TOP }) + .textAlign(TextAlign.Center) + .maxFontScale(CommonConstants.MAX_FONT_SCALE) + } + .transition(TransitionEffect.OPACITY.animation({ duration: CommonConstants.ANIMATE_DURATION, curve: Curve.Sharp })) + .margin({ left: CommonConstants.OTHER_ICON_MARGIN_LEFT }) + } + + build() { + Column() { + Flex({ + direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center + }) { + this.BackButton(); + this.TrackingLayoutLeft(); + this.TrackingLayoutCenter(); + this.TrackingLayoutRight(); + } + .width('100%') + .height('100%') + + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + } + + setCameraTrackingLayout(layout: mechanicManager.CameraTrackingLayout) { + logger.info(`${TAG} setCameraTrackingLayout: ${layout}`); + let originalLayout = this.currentLayout; + try { + mechanicManager.setCameraTrackingLayout(layout); + this.currentLayout = layout; + } catch (error) { + this.currentLayout = originalLayout; + let code: number = (error as BusinessError).code; + let message: string = (error as BusinessError).message; + logger.error(`${TAG} setCameraTrackingLayout failed. Layout: ${layout}, error.code: ${code}, message: ${message}`); + } + } + + onLeftIconClick = () => { + logger.info(`${TAG} onLeftIconClick in`); + this.setCameraTrackingLayout(mechanicManager.CameraTrackingLayout.LEFT); + } + + onCenterIconClick = () => { + logger.info(`${TAG} onCenterIconClick in`); + this.setCameraTrackingLayout(mechanicManager.CameraTrackingLayout.MIDDLE); + } + + onRightIconClick = () => { + logger.info(`${TAG} onRightIconClick in`); + this.setCameraTrackingLayout(mechanicManager.CameraTrackingLayout.RIGHT); + } +} \ No newline at end of file diff --git a/application/entry/src/main/module.json5 b/application/entry/src/main/module.json5 index ddfce3b718fb05f238801c2b28eecbb5a8d0feef..70cec13af2a339fb8dfa0405ca2f3e4983a65250 100644 --- a/application/entry/src/main/module.json5 +++ b/application/entry/src/main/module.json5 @@ -66,6 +66,9 @@ }, { "name": "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS_EXTENSION" + }, + { + "name": "ohos.permission.CONNECT_MECHANIC_HARDWARE" } ], "extensionAbilities": [ diff --git a/application/entry/src/main/resources/base/media/track_layout_center.svg b/application/entry/src/main/resources/base/media/track_layout_center.svg index 7abb97c027b0fe5913e5f8fbc8c9c45e253dfc56..490885c89905e4c4239527b6f85b588892c697b0 100644 --- a/application/entry/src/main/resources/base/media/track_layout_center.svg +++ b/application/entry/src/main/resources/base/media/track_layout_center.svg @@ -1,6 +1,4 @@ - - - - - + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/base/media/track_layout_center_dark.svg b/application/entry/src/main/resources/base/media/track_layout_center_dark.svg index 6dc793cd347fc08a86f51484d7877dd880618045..72c6286db8c6cbd6d437c5991e46e78aff6c4f7f 100644 --- a/application/entry/src/main/resources/base/media/track_layout_center_dark.svg +++ b/application/entry/src/main/resources/base/media/track_layout_center_dark.svg @@ -1,6 +1,4 @@ - - - - - + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/base/media/track_layout_left.svg b/application/entry/src/main/resources/base/media/track_layout_left.svg index 4efb202a6d94024dc7257dc1121e2bf1353c8d21..9a3a28b5532757b03dde75ad1b35a5358cd201b5 100644 --- a/application/entry/src/main/resources/base/media/track_layout_left.svg +++ b/application/entry/src/main/resources/base/media/track_layout_left.svg @@ -1,5 +1,4 @@ - - - - + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/base/media/track_layout_left_dark.svg b/application/entry/src/main/resources/base/media/track_layout_left_dark.svg index e06939a71286a02a747185aff0da2fdda05dee37..49e54332fc6622e05ae932a85045eda66c1bde22 100644 --- a/application/entry/src/main/resources/base/media/track_layout_left_dark.svg +++ b/application/entry/src/main/resources/base/media/track_layout_left_dark.svg @@ -1,5 +1,4 @@ - - - - + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/base/media/track_layout_right.svg b/application/entry/src/main/resources/base/media/track_layout_right.svg index c7d0a930dfd023935e969367887b7f698e8982dc..e28476becb308a7ef4da7938d14c91f0c6d17b67 100644 --- a/application/entry/src/main/resources/base/media/track_layout_right.svg +++ b/application/entry/src/main/resources/base/media/track_layout_right.svg @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/base/media/track_layout_right_dark.svg b/application/entry/src/main/resources/base/media/track_layout_right_dark.svg index 343e3eb5a7517962e951e25d14b5e36e139e7c8a..907fc7fe30eb5da608604338bf54260198423d11 100644 --- a/application/entry/src/main/resources/base/media/track_layout_right_dark.svg +++ b/application/entry/src/main/resources/base/media/track_layout_right_dark.svg @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/base/profile/main_pages.json b/application/entry/src/main/resources/base/profile/main_pages.json index ad262871755261c6da53b863f5a76577a5f1c370..c9abbdea51a45a0d8171a158ee6e08cb0b0d5576 100644 --- a/application/entry/src/main/resources/base/profile/main_pages.json +++ b/application/entry/src/main/resources/base/profile/main_pages.json @@ -2,6 +2,7 @@ "src": [ "pages/DHardwareUI", "pages/ContinueSwitch", - "pages/MechControl" + "pages/MechControl", + "pages/TrackingLayout" ] } \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/intelligent_tracking.svg b/application/entry/src/main/resources/dark/media/intelligent_tracking.svg new file mode 100644 index 0000000000000000000000000000000000000000..aee450d9ca66e9b1d8735661e5b158896dba556f --- /dev/null +++ b/application/entry/src/main/resources/dark/media/intelligent_tracking.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/intelligent_tracking_dark.svg b/application/entry/src/main/resources/dark/media/intelligent_tracking_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..aee450d9ca66e9b1d8735661e5b158896dba556f --- /dev/null +++ b/application/entry/src/main/resources/dark/media/intelligent_tracking_dark.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/track_layout_center.svg b/application/entry/src/main/resources/dark/media/track_layout_center.svg new file mode 100644 index 0000000000000000000000000000000000000000..490885c89905e4c4239527b6f85b588892c697b0 --- /dev/null +++ b/application/entry/src/main/resources/dark/media/track_layout_center.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/track_layout_center_dark.svg b/application/entry/src/main/resources/dark/media/track_layout_center_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..490885c89905e4c4239527b6f85b588892c697b0 --- /dev/null +++ b/application/entry/src/main/resources/dark/media/track_layout_center_dark.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/track_layout_left.svg b/application/entry/src/main/resources/dark/media/track_layout_left.svg new file mode 100644 index 0000000000000000000000000000000000000000..9a3a28b5532757b03dde75ad1b35a5358cd201b5 --- /dev/null +++ b/application/entry/src/main/resources/dark/media/track_layout_left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/track_layout_left_dark.svg b/application/entry/src/main/resources/dark/media/track_layout_left_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..9a3a28b5532757b03dde75ad1b35a5358cd201b5 --- /dev/null +++ b/application/entry/src/main/resources/dark/media/track_layout_left_dark.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/track_layout_right.svg b/application/entry/src/main/resources/dark/media/track_layout_right.svg new file mode 100644 index 0000000000000000000000000000000000000000..e28476becb308a7ef4da7938d14c91f0c6d17b67 --- /dev/null +++ b/application/entry/src/main/resources/dark/media/track_layout_right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/application/entry/src/main/resources/dark/media/track_layout_right_dark.svg b/application/entry/src/main/resources/dark/media/track_layout_right_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..e28476becb308a7ef4da7938d14c91f0c6d17b67 --- /dev/null +++ b/application/entry/src/main/resources/dark/media/track_layout_right_dark.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file