import QtQml.Models import QtQuick import QtQuick.Controls import QtQuick.Layouts import Qt5Compat.GraphicalEffects import GeneralBiz import FusionUI import MaterialPanel import FunctionPanel import Player import Purchase import PopupWndMgr import VECreator import GeneralBizUI import VipBiz Item { id: root readonly property real margin: 12 readonly property real rowSpacing: 16 readonly property real sliderSpacing: 8 readonly property real rowHeight: 22 readonly property real valueLeftMargin: CAPCUT ? 68 : 56 property bool showUseGuide: false property int faceModeIndex: 0 property int selectedTab: viewModel.curTab property VideoBeautySettingViewModel viewModel: VideoBeautySettingViewModel{} property VideoManualBeautyViewModel manualBeautyViewModel: viewModel.manualBeautyVideoModel property VideoOneClickBeautyViewModel oneClickViewModel: VideoOneClickBeautyViewModel{} property VideoHairBeautyViewModel hairBeautyViewModel: VideoHairBeautyViewModel{} property VideoBeautyFacePresetViewModel facePresetViewModel: VideoBeautyFacePresetViewModel{} property VideoBeautyBodyPresetViewModel bodyPresetViewModel: VideoBeautyBodyPresetViewModel{} property bool showVipFeatures: VipPurchaseSettings.enable property Item controlBarContainer: internal.controlBarContainer property bool beautyControlContainerVisible: viewModel.enableBeautyPreset && (root.selectedTab == VideoBeautyTabItem.KVideoBodyBeauty || root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty) property VEFlickable parentFlickable: null QtObject { id: internal property var controlBarContainer: Item { id: controlBarContainer anchors.fill: parent Row { anchors { right: parent.right top: parent.top bottom: parent.bottom } spacing: 8 topPadding: 8 bottomPadding: 8 rightPadding: 12 layoutDirection: vePlatform.isOSWin() ? Qt.LeftToRight : Qt.RightToLeft Item { width: savePresetBtn.width height: childrenRect.height VETextButton { id: savePresetBtn // width is not fixed, and the width will be reset when completed in the control // Therefore, the external width must be set according to the width of btn, and the width of btn cannot be set according to the width of the external width width: 72 height: 20 type: VECType.VETextButton_secondary1 title: i18n.tr("pc_retouch_save_preset_btn") enabled: { if (root.selectedTab == VideoBeautyTabItem.KVideoBodyBeauty) { return root.viewModel.saveBeautyBodyPresetEnable; } else if (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty) { return root.viewModel.saveBeautyFacePresetEnable; } } onClicked: { if (root.selectedTab == VideoBeautyTabItem.KVideoBodyBeauty) { root.viewModel.saveBeautyBodyPreset() } else if (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty) { root.viewModel.saveBeautyFacePreset() } } } MouseArea { anchors.fill: savePresetBtn enabled: !savePresetBtn.enabled onClicked: { if (root.selectedTab == VideoBeautyTabItem.KVideoBodyBeauty) { root.viewModel.toastSavePresetBodyDisabled() } else if (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty) { root.viewModel.toastSavePresetFaceDisabled() } } } // VipFeatureIcon { // id: vipIcon // anchors{ // top: savePresetBtn.top // right: savePresetBtn.right // topMargin: -6 // } // iconSizeType: VipFeatureIconType.IconSizeType_small // vipIdentifier: vip.beauty_preset // sceneType: VipFeatureIconType.UseScene_button // } } } } } signal syncFaceModelIndex() function scheduleMakeupNavigationReady() { if (!viewModel) { return } const token = viewModel.makeupNavigationToken if (token.length === 0) { return } Qt.callLater(root.notifyMakeupNavigationReady, token) } function notifyMakeupNavigationReady(token) { if (!viewModel || token !== viewModel.makeupNavigationToken) { return } viewModel.notifyMakeupNavigationItemReady(token, isMakeupNavigationItemReady()) } function isMakeupNavigationItemReady() { const makeupItem = autoMakeUpLoader.item return autoMakeUpLoader.contentReady && autoMakeUpLoader.visible && root.visible && autoMakeUpLoader.width > 0 && autoMakeUpLoader.height > 0 && makeupItem !== null && makeupItem.visible && makeupItem.width > 0 && makeupItem.height > 0 } function prepareMakeupNavigation(token) { if (!viewModel || token !== viewModel.makeupNavigationToken) { return } if (!isMakeupNavigationItemReady()) { viewModel.beginMakeupNavigationPositioning(token, false) return } autoMakeUpLoader.item.sigDeepLinkBefore({}) if (!viewModel || !viewModel.beginMakeupNavigationPositioning(token, isMakeupNavigationItemReady())) { return } const makeupItem = autoMakeUpLoader.item const flickable = makeupItem ? makeupItem.getFlickableItem() : undefined if (!flickable) { viewModel.finishMakeupNavigationPositioning(token, false) return } makeupItem.forceLayoutChildItems(flickable) const pos = makeupItem.mapToItem(flickable, 0, 0) flickable.contentY = Math.min(pos.y + flickable.contentY - 12, Math.max(flickable.contentHeight - flickable.height, 0)) viewModel.finishMakeupNavigationPositioning(token, true) } height: basicContainer.height + 30 width: parent.width onVisibleChanged: { viewModel.ViewVisiableChanged(root.visible) scheduleMakeupNavigationReady() } onWidthChanged: scheduleMakeupNavigationReady() onHeightChanged: scheduleMakeupNavigationReady() Component.onDestruction: { if (viewModel) { viewModel.cancelMakeupNavigation(viewModel.makeupNavigationToken) } } Connections { target: viewModel function onPrepareMakeupNavigation(token) { root.prepareMakeupNavigation(token) } } UseGuideNew { id: userGuide needWindow: true transientParent: root.Window.window bubbleType: PopupWinMgrDefine.UserBubbleSmartSearch scene: PopupWinMgrDefine.kEditorScene text: i18n.tr(LVSystemInfo.isMobile ? "pc_recorder_retouch_info_pad" : "pc_recorder_retouch_info") btnText: i18n.tr("pc_recorder_onboarding_btn") direction: "left" hasVideo: false autoplay: false visible: guideLoaderActive deltaYOffset: height / 2 - 12 objHOffset: 0 objHCenter: false width: 176 height: 72 guideLoaderActive: root.showUseGuide && root.visible guideLoaderVisible: guideLoaderActive x: -width y: tabControl.y + tabControl.height + 10 enableAutoClose: true onGuideLoaderActiveChanged: { root.showUseGuide = false; } Connections { target: root.Window.window onXChanged: { if (visible) userGuide.updatePos() } onYChanged: { if (visible) userGuide.updatePos() } onWidthChanged: { if (visible) userGuide.updatePos() } } onLoaded: { updatePos() } onNotifyViewed: { root.showUseGuide = false; } function updatePos(){ if (windowLoaderStatus === Loader.Ready) { var pos = root.mapToGlobal(0, 0) showUseGuidePanel(pos.x - width + 10, pos.y - height / 2 + 10) } } } function checkComponetLoaded(key) { if (key == "beauty") { if(beautyPanelLoader.contentReady) viewModel.setComponetLoaded(key, true) else viewModel.setComponetLoaded(key, false) } else if( key == "body" ) { viewModel.setComponetLoaded(key, true) } else if( key == "face_shape" ) { viewModel.setComponetLoaded(key, true) } else if( key == "face" ) { viewModel.setComponetLoaded(key, true) } else if( key == "makeup" ) { viewModel.setComponetLoaded(key, true) } else if( key == "manual-figure" ) { viewModel.setComponetLoaded(key, true) } } function scrollToViewport(key) { if (key == "body") { if(viewModel.enableBeautyPreset) { viewModel.curTab = VideoBeautyTabItem.KVideoBodyBeauty; } else { beautyBodyPanelLoader.item.scrollToViewport() } } else if (key == "beauty") { beautyPanelLoader.item.scrollToViewport() } else if (key == "face_shape") { beautyFaceShapePanelLoader.item.scrollToViewport() } else if (key == "face") { if(viewModel.newUI){ beautyFiveScenesPanelLoader.item.scrollToViewport() }else{ beautyShapePanelLoader.item.scrollToViewport() } } else if (key == "makeup") { autoMakeUpLoader.item.scrollToViewport() }else if( key == "manual-figure" ) { manualBeautyBodyLoader.item.scrollToViewport() } else if (key == "OneClickBeauty") { if (parentFlickable) { parentFlickable.contentY = 0 } clickBeauty.showFunMask(false) oneClickViewModel.applyNativeEffect() } } // Hide all menus when sliding pulleys MouseArea { anchors.fill: parent propagateComposedEvents: true onWheel: (wheel) => { wheel.accepted = false parent.hideAllPopup() } } // Hide all menus signal hideAllPopup ListModel {id: autoBeautyModel} ListModel {id: skinColorModel} ListModel {id: autoBeautyShapeModel} ListModel {id: autoBeautyFaceShapeModel} ListModel {id: autoBeautyFiveScenesModel} ListModel {id: autoMakeUpModel} ListModel {id: autoBeautyBodyModel} ListModel {id: autoManualBeautyModel} Item { id: basicContainer height: basicColumn.implicitHeight + (faceBeautyPreset.visible ? faceBeautyPreset.height : 0) + (bodyBeautyPreset.visible ? bodyBeautyPreset.height : 0) + (hairBeauty.visible ? hairBeauty.height : 0) anchors.top: parent.top anchors.left: parent.left anchors.leftMargin: root.margin anchors.right: parent.right anchors.rightMargin: root.margin Column { id: basicColumn spacing: root.rowSpacing bottomPadding: root.rowSpacing width: parent.width y: root.rowSpacing property bool enableSkin: false Flow { id: tabFlow spacing: 9 width: parent.width height: implicitHeight visible: viewModel.enableBeautyPreset Repeater{ id: tabList model: viewModel.tabItemList CategoryButtonView { property bool __focusable: true title: modelData.title selected: root.selectedTab == modelData.type onClick: { viewModel.curTab = modelData.type if(viewModel.enableCheckResourceValid) viewModel.LoadAllPanelData(); } } } } VEComboBox { id: comboxFaceMode property bool __focusable: true items: viewModel.faceModeList height: root.rowHeight visible: viewModel.newUI && (viewModel.curTab == VideoBeautyTabItem.KVideoFaceBeauty || root.selectedTab === VideoBeautyTabItem.VideoBeautyTabType.kVideoHairBeauty) //anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left //anchors.leftMargin: 4 anchors.right: parent.right anchors.rightMargin: 4 opacity: enabled ? 1 : 0.4 //selectedIndex: root.faceModeIndex onSelectIndexChanged : { viewModel.SetFaceModeTypeIndex(selectedIndex) } enabled: viewModel.beautyGroupEnabled && !viewModel.isMultiSelect && root.selectedTab !== VideoBeautyTabItem.VideoBeautyTabType.kVideoHairBeauty showConstantText: viewModel.isMultiSelect constantText: viewModel.constantText() Component.onCompleted: { root.syncFaceModelIndex.connect(function(){ comboxFaceMode.selectedIndex = root.faceModeIndex }) } } //一键美颜 VideoOneClickBeautyView { id: clickBeauty width: parent.width visible: root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty && root.oneClickViewModel.visible() viewModel: root.oneClickViewModel } //皮肤管理 VideoAutoBeautyLoader { id: beautyPanelLoader deepLinkKey: FunctionPanelDeepLink.video_figure_beauty groupId: viewModel.newUI ? VideoBeautySettingViewModel.BeautySkinManagementGroup : VideoBeautySettingViewModel.BeautyGroup showFaceModeSelector: true title: viewModel.newUI ? i18n.tr("pc_retouch_face_skin") : (VECContext.copywritingABTest() ? i18n.tr("pc_new_retouch_n"):i18n.tr("beautify_pc")) recommendKey: "beauty" groupModel: autoBeautyModel visible: root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset onResetBtnClicked: { skinColorLoader.item.selectIndex = 0 } } // color (肤色) VideoAutoBeautyLoader { id: skinColorLoader deepLinkKey: FunctionPanelDeepLink.video_skin_colour active: false enabled: beautyPanelLoader.checked visible: root.showVipFeatures && active && (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset) && !beautyPanelLoader.collapsed && beautyPanelLoader.contentReady groupId: viewModel.newUI ? VideoBeautySettingViewModel.SkinColorNew : VideoBeautySettingViewModel.SkinColor recommendKey: "beauty" groupModel: skinColorModel title: i18n.tr("skin_colour") width: parent.width height: 154 } // Smart beauty (美型) VideoAutoBeautyLoader { id: beautyShapePanelLoader deepLinkKey: FunctionPanelDeepLink.video_figure_shape visible: !viewModel.newUI && (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset) groupId: VideoBeautySettingViewModel.BeautyShapeGroup showFaceModeSelector: true title: VECContext.copywritingABTest() ? i18n.tr("pc_new_auto_reshape"):i18n.tr("smart_beauty") recommendKey: "face" groupModel: autoBeautyShapeModel } // Face shape (脸型) VideoAutoBeautyLoader { id: beautyFaceShapePanelLoader deepLinkKey: FunctionPanelDeepLink.video_figure_face_shape visible: viewModel.newUI && (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset) groupId: VideoBeautySettingViewModel.BeautyFaceShapeGroup showFaceModeSelector: true title: i18n.tr("pc_retouch_face_face") recommendKey: "face_shape" groupModel: autoBeautyFaceShapeModel } // Five Officials (五官精修) VideoAutoBeautyLoader { id: beautyFiveScenesPanelLoader deepLinkKey: FunctionPanelDeepLink.video_figure_face visible: viewModel.newUI && (root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset) groupId: VideoBeautySettingViewModel.BeautyFiveSceneGroup showFaceModeSelector: true title: i18n.tr("pc_retouch_face_features") recommendKey: "face" groupModel: autoBeautyFiveScenesModel } // Beauty makeup (美妆) VideoAutoBeautyLoader { id: autoMakeUpLoader deepLinkKey: FunctionPanelDeepLink.video_figure_makeup visible: root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset groupId: VideoBeautySettingViewModel.BeautyMakeupGroup showFaceModeSelector: true title: i18n.tr("beauty") recommendKey: "makeup" groupModel: autoMakeUpModel onVisibleChanged: root.scheduleMakeupNavigationReady() onWidthChanged: root.scheduleMakeupNavigationReady() onHeightChanged: root.scheduleMakeupNavigationReady() onItemChanged: root.scheduleMakeupNavigationReady() onContentReadyChanged: root.scheduleMakeupNavigationReady() } Connections { target: autoMakeUpLoader function onLoaded() { root.scheduleMakeupNavigationReady() } } Connections { target: autoMakeUpLoader.item ignoreUnknownSignals: true function onVisibleChanged() { root.scheduleMakeupNavigationReady() } function onWidthChanged() { root.scheduleMakeupNavigationReady() } function onHeightChanged() { root.scheduleMakeupNavigationReady() } } // Manual face slimming display under beauty makeup (美妆手动精修) VideoAutoBeautyLoader { id: manualDeformationComPanelLoader deepLinkKey: FunctionPanelDeepLink.video_figure_manual_beauty visible: root.selectedTab == VideoBeautyTabItem.KVideoFaceBeauty || !viewModel.enableBeautyPreset enabled: !viewModel.isMultiSelect groupModel: autoManualBeautyModel groupId: VideoBeautySettingViewModel.BeautyManualFigureGroup } // Body beauty (智能美体) VideoAutoBeautyLoader { // Smart body beauty loader id: beautyBodyPanelLoader deepLinkKey: FunctionPanelDeepLink.video_figure_body visible: root.selectedTab == VideoBeautyTabItem.KVideoBodyBeauty || !viewModel.enableBeautyPreset groupId: VideoBeautySettingViewModel.BeautyBodyGroup showFaceModeSelector: false title: viewModel.newUI ? i18n.tr("pc_retouch_auto_body") : i18n.tr("body_shaping_pc") recommendKey: "body" groupModel: autoBeautyBodyModel } // Manual body beauty (手动美体) VideoAutoBeautyLoader { id: manualBeautyBodyLoader deepLinkKey: FunctionPanelDeepLink.video_figure_manual visible: viewModel.enableManualFigure && !viewModel.manualDeformationBrushActive && (root.selectedTab == VideoBeautyTabItem.KVideoBodyBeauty || !viewModel.enableBeautyPreset) groupId: VideoBeautySettingViewModel.BeautyManualFigureGroup showFaceModeSelector: false title: i18n.tr("pc_retouch_body_manual") recommendKey: "manual-figure" enabled: !viewModel.isMultiSelect } // components Component{ id: manualDeformationCom VideoManualDeformationView {} } Component{ id: skinColorCom VideoAutoBeautySkinColorView{} } Component{ id: makeUpCom VideoAutoBeautyMakeupView {} } Component{ id: manualBeautyBodyCom VideoManualFigureView {} } Component{ id: effectItemDelegate VideoAutoBeautySingleSliderView {} } Component{ id: singleGroupComponent VideoAutoBeautySingleGroupView {} } Component{ id: mutiSectionGroupComponent VideoAutoBeautyMultiGroupView {} } } //美发 VideoHairBeautyView { id: hairBeauty width: parent.width visible: root.selectedTab === VideoBeautyTabItem.VideoBeautyTabType.kVideoHairBeauty && root.hairBeautyViewModel.visible() viewModel: root.hairBeautyViewModel anchors { top: basicColumn.bottom } } VideoBeautyPresetView { id: faceBeautyPreset visible: root.selectedTab == VideoBeautyTabItem.KVideoFaceBeautyPreset viewModel: root.facePresetViewModel anchors { top: basicColumn.bottom topMargin: 10 } } VideoBeautyPresetView { id: bodyBeautyPreset visible: root.selectedTab == VideoBeautyTabItem.KVideoBodyBeautyPreset viewModel: root.bodyPresetViewModel anchors { top: basicColumn.bottom topMargin: 10 } } } Component.onCompleted:{ viewModel.LoadAllPanelData() viewModel.ViewVisiableChanged(root.visible) } function showPanel(loaderObj, show, muti_section){ var sourceComObj if(muti_section){ sourceComObj = mutiSectionGroupComponent } else{ sourceComObj = singleGroupComponent } if(loaderObj.sourceComponent == sourceComObj){ return } // Highly adaptable loaderObj.height = undefined // clear last component if(loaderObj.item){ loaderObj.sourceComponent = undefined } loaderObj.sourceComponent = sourceComObj loaderObj.active = show } Connections { target: viewModel function onShowUseGuide(){ root.showUseGuide = true } function onMakeupNavigationTokenChanged() { root.scheduleMakeupNavigationReady() } function onPanelLoadSuccess(objsArray, contain_sub_section, group_id){ if(group_id === VideoBeautySettingViewModel.BeautyGroup || group_id === VideoBeautySettingViewModel.BeautySkinManagementGroup){ autoBeautyModel.clear() autoBeautyModel.append(objsArray) showPanel(beautyPanelLoader, true, contain_sub_section) root.faceModeIndex = viewModel.faceModeTypeIndex } else if(group_id === VideoBeautySettingViewModel.BeautyManualBeautyGroup){ autoManualBeautyModel.clear() autoManualBeautyModel.append(objsArray) if(manualDeformationComPanelLoader.sourceComponent != manualDeformationCom){ manualDeformationComPanelLoader.height = undefined manualDeformationComPanelLoader.sourceComponent = undefined manualDeformationComPanelLoader.sourceComponent = manualDeformationCom } } else if(group_id === VideoBeautySettingViewModel.BeautyFaceShapeGroup){ autoBeautyFaceShapeModel.clear() autoBeautyFaceShapeModel.append(objsArray) showPanel(beautyFaceShapePanelLoader, true, contain_sub_section) } else if(group_id === VideoBeautySettingViewModel.BeautyFiveSceneGroup){ autoBeautyFiveScenesModel.clear() autoBeautyFiveScenesModel.append(objsArray) showPanel(beautyFiveScenesPanelLoader, true, contain_sub_section) } else if(group_id === VideoBeautySettingViewModel.BeautyShapeGroup){ autoBeautyShapeModel.clear() autoBeautyShapeModel.append(objsArray) showPanel(beautyShapePanelLoader, true, contain_sub_section) } else if(group_id === VideoBeautySettingViewModel.BeautyMakeupGroup){ if(autoMakeUpLoader.sourceComponent != makeUpCom){ autoMakeUpModel.clear() autoMakeUpModel.append(objsArray) autoMakeUpLoader.height = undefined autoMakeUpLoader.sourceComponent = makeUpCom autoMakeUpLoader.active = true } } else if(group_id === VideoBeautySettingViewModel.BeautyBodyGroup){ autoBeautyBodyModel.clear() autoBeautyBodyModel.append(objsArray) showPanel(beautyBodyPanelLoader, true, contain_sub_section) } else if(group_id === VideoBeautySettingViewModel.SkinColor || group_id === VideoBeautySettingViewModel.SkinColorNew){ skinColorModel.clear() skinColorModel.append(objsArray) skinColorModel.insert(0,{}) skinColorLoader.sourceComponent = skinColorCom skinColorLoader.active = true } else if(group_id === VideoBeautySettingViewModel.BeautyManualFigureGroup){ if(manualBeautyBodyLoader.sourceComponent != manualBeautyBodyCom){ manualBeautyBodyLoader.height = undefined manualBeautyBodyLoader.sourceComponent = undefined manualBeautyBodyLoader.sourceComponent = manualBeautyBodyCom } } } function onPanelLoadError(group_id:int, show_loading: bool){ if(group_id === VideoBeautySettingViewModel.BeautyGroup || group_id === VideoBeautySettingViewModel.BeautySkinManagementGroup){ if(show_loading) { beautyPanelLoader.isLoading = false beautyPanelLoader.showLoading() } else { beautyPanelLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyManualBeautyGroup){ if(show_loading) { manualDeformationComPanelLoader.isLoading = false manualDeformationComPanelLoader.showLoading() } else { manualDeformationComPanelLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyFaceShapeGroup){ if(show_loading) { beautyFaceShapePanelLoader.isLoading = false beautyFaceShapePanelLoader.showLoading() } else { beautyFaceShapePanelLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyFiveScenesGroup){ if(show_loading) { beautyFiveScenesPanelLoader.isLoading = false beautyFiveScenesPanelLoader.showLoading() } else { beautyFiveScenesPanelLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyShapeGroup){ if(show_loading) { beautyShapePanelLoader.isLoading = false beautyShapePanelLoader.showLoading() } else { beautyShapePanelLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyBodyGroup){ if(show_loading) { beautyBodyPanelLoader.isLoading = false beautyBodyPanelLoader.showLoading() } else { beautyBodyPanelLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyMakeupGroup){ if(show_loading) { autoMakeUpLoader.isLoading = false autoMakeUpLoader.showLoading() } else { autoMakeUpLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.SkinColor || group_id === VideoBeautySettingViewModel.SkinColorNew){ if(show_loading) { skinColorLoader.isLoading = false skinColorLoader.showLoading() } else { skinColorLoader.item.isLoading = false } } else if(group_id === VideoBeautySettingViewModel.BeautyManualFigureGroup){ if(show_loading) { manualBeautyBodyLoader.isLoading = false manualBeautyBodyLoader.showLoading() } else { manualBeautyBodyLoader.item.isLoading = false } } } function onFaceModeTypeIndexChanged() { var lastIndex = root.faceModeIndex root.faceModeIndex = viewModel.IsFaceModeTypeIndexMixed() ? 0 : viewModel.faceModeTypeIndex if(lastIndex !== root.faceModeIndex){ viewModel?.ReportSwitchBeautyModeInfo("player") } root.syncFaceModelIndex() } function onScrollView(key) { scrollToViewport(key) } } }