/*
* Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
* 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 {
BlurEffect,
BlurEffectType,
VisualEffectConstants,
StartExitMotionLevel,
} from '@ohos/commonconstants/src/main/ets/constants/VisualEffectConstants';
import { SingletonHelper, LogDomain, LogHelper } from '@ohos/basicutils';
import { StateEx, SCBVisualEffectMgr } from '@ohos/componenthelper';
import { GlobalContext } from '@ohos/frameworkwrapper';
import { editModeManager } from '../TsIndex';
import { ScenePanelState } from '@ohos/windowscene/src/main/ets/TsIndex';
import { folderGesData } from '../folder/model/FolderGestureData';
import { FolderManager } from '../folder/next/common/model/FolderManager'
import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';
import power from '@ohos.power';
import { StartAndExitVisualEffectManager } from './StartAndExitVisualEffectManager';
const TAG: string = 'LauncherVisualEffectManager';
const log: LogHelper = LogHelper.getLogHelper(LogDomain.HOME, TAG);
const ONE_STEP_DEFAULT: number = 0;
const ONE_STEP_SHOW_BG_AND_ICON: number = 2;
const ONE_STEP_ENTER_SPLIT: number = 3;
const ONE_STEP_ENTER_FLOATING: number = 4;
const ONE_STEP_ENTER_MID_SCENE: number = 5;
const MASK_COLOR_FOR_DEFAULT: string = '#19000000';
const MASK_COLOR_RECENT_LIGHT: string = '#3F000000';
const MASK_COLOR_RECENT_DARK: string = '#38000000';
const MASK_COLOR_FOLDER_LIGHT: string = '#12000000';
const MASK_COLOR_FOLDER_DARK: string = '#66000000';
const MASK_COLOR_NEGATIVE_DARK: string = '#4D000000';
const MASK_COLOR_GLOBALSEARCH_DARK: string = '#66000000';
const DARK_COLOR_MODE: number = 0;
const LIGHT_COLOR_MODE: number = 1;
/**
* 多任务视效框管理类
*/
export class LauncherVisualEffectManager {
// 控制桌面是否透明
public launcherOpacity: StateEx<number> = new StateEx(1);
// 是否使用模糊合并,默认关闭
public isUseEffect: boolean = false;
// 壁纸模糊效果是否开启
public isWallpaperBlurEffect: StateEx<boolean> = new StateEx(false);
// 控制壁纸模糊效果是否透明
public wallpaperBlurOpacity: StateEx<number> = new StateEx(0);
// 适配动效期间堆叠卡片背景blendMode效果
public isBlurAnimRunning: StateEx<boolean> = new StateEx(false);
// 是否显示蒙版
public isShowMask: StateEx<boolean> = new StateEx(false);
// 蒙版颜色
public maskColor: StateEx<string> = new StateEx(MASK_COLOR_FOR_DEFAULT);
//是否显示文件夹壁纸模糊效果
public isShowFolderBlurEffect: StateEx<boolean> = new StateEx(false);
public isShowGlobalSearchBlurEffect: StateEx<boolean> = new StateEx(false);
private readonly ANIMATION_CURVE: string = 'cubic-bezier(0.10, 0.34, 0.33, 1.00)';
// 当多任务显示时,控制其它视图是否透明,如负一屏、全搜、编辑模式等
private othersOpacity: StateEx<number> = new StateEx(1);
private folderOpacity: StateEx<number> = new StateEx(1);
private editModeButtonOpacity: StateEx<number> = new StateEx(1);
private isShowUIExtension: boolean = false;
private blurEffect: BlurEffect = new BlurEffect();
private isRecentBlurEffectDisable: boolean = false;
private isNegativeBlurEffectDisable: boolean = false;
private isFolderBlurEffectDisable: boolean = false;
private isGlobalSearchBlurEffectDisable: boolean = false;
private isLauncherSwiperCustomEnable: boolean = false;
private isLauncherOpAnimDisable: boolean = false;
private colorMode: number = 0;
private isTransitionBlurEffectDisable: boolean = false;
private isPowerSaveMode: boolean = false;
private mSubscriber: commonEventManager.CommonEventSubscriber | null = null;
private subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
events: [
commonEventManager.Support.COMMON_EVENT_POWER_SAVE_MODE_CHANGED
]
};
/**
* 获取视效json文件中的相关参数
*/
public initParams(): void {
this.isRecentBlurEffectDisable =
SCBVisualEffectMgr.isFeatureParamTrue(VisualEffectConstants.IS_RECENT_BLUR_DISABLED);
this.isNegativeBlurEffectDisable =
SCBVisualEffectMgr.isFeatureParamTrue(VisualEffectConstants.IS_NEGATIVESCREEN_BLUR_DISABLED);
this.isFolderBlurEffectDisable =
SCBVisualEffectMgr.isFeatureParamTrue(VisualEffectConstants.FOLDER_BLUR_EFFECT_DISABLE);
this.isGlobalSearchBlurEffectDisable =
SCBVisualEffectMgr.getFeatureParam(VisualEffectConstants.GLOBAL_SEARCH_BLUR_EFFECT_DISABLE) === 'true';
this.isLauncherSwiperCustomEnable =
SCBVisualEffectMgr.isFeatureParamTrue(VisualEffectConstants.LAUNCHER_SWIPER_CUSTOM_ENABLED);
this.colorMode = GlobalContext.getContext().config.colorMode as number;
const startExitMotionLevel: StartExitMotionLevel =
SCBVisualEffectMgr.getStartExitMotionLevel(VisualEffectConstants.ICON_START_EXIT_MOTION_BLUR_LEVEL);
const isStartExitBlurDisable =
SCBVisualEffectMgr.isFeatureParamTrue(VisualEffectConstants.ICON_START_EXIT_BLUR_DISABLE);
this.isTransitionBlurEffectDisable =
!isStartExitBlurDisable && startExitMotionLevel === StartExitMotionLevel.WALLPAPER_BLUR;
this.initPowerMode();
this.registerPowerSaveModeChange();
}
/**
* 初始化电池模式
*/
private initPowerMode(): void {
let curPowerMode: power.DevicePowerMode = power.DevicePowerMode.MODE_NORMAL;
try {
curPowerMode = power.getPowerMode();
} catch (err) {
log.showError(`Get device power mode failed , err: ${err?.code}, errMessage: ${err?.message}`);
}
if (curPowerMode === power.DevicePowerMode.MODE_POWER_SAVE ||
curPowerMode === power.DevicePowerMode.MODE_EXTREME_POWER_SAVE) {
this.isPowerSaveMode = true;
StartAndExitVisualEffectManager.getInstance().setIsPowerSaveMode(true);
}
this.updateFolderBlurEffect();
this.updateGlobalSearchBlurEffect();
}
/**
* 监听电池模式的改变
*/
private registerPowerSaveModeChange(): void {
log.showWarn('register power save mode change event');
this.mSubscriber = commonEventManager.createSubscriberSync(this.subscribeInfo);
if (this.mSubscriber === null) {
log.showError(`create subscriber error!`);
return;
}
commonEventManager.subscribe(this.mSubscriber,
(err: BusinessError, data: commonEventManager.CommonEventData) => {
if (err) {
log.showError(`Can't handle common event, err: ${err.code}, err: ${err.message}`);
return;
}
if (data?.event === commonEventManager.Support.COMMON_EVENT_POWER_SAVE_MODE_CHANGED) {
log.showWarn(`power mode changed, current mode: ${data.code}`);
if (data.code === power.DevicePowerMode.MODE_POWER_SAVE ||
data.code === power.DevicePowerMode.MODE_EXTREME_POWER_SAVE) {
this.isPowerSaveMode = true;
StartAndExitVisualEffectManager.getInstance().setIsPowerSaveMode(true);
if (!this.isRecentBlurEffectDisable) {
this.registerRecentBlurEvent();
this.registerIconStartExitBlurEvent();
this.registerFolderFullBlurEvent();
}
} else {
this.isPowerSaveMode = false;
this.isLauncherOpAnimDisable = false;
StartAndExitVisualEffectManager.getInstance().setIsPowerSaveMode(false);
this.updateFolderBlurEffect();
this.updateGlobalSearchBlurEffect();
}
}
});
}
/**
* 多任务是否禁用实时模糊
* @returns true:禁用模糊, false:不禁用
*/
public isRecentBlurEffectDisabled(): boolean {
log.showDebug(`isRecentDisable: ${this.isRecentBlurEffectDisable} ${this.isPowerSaveMode}
${this.blurEffect.isRecentBlurEffect}`);
return this.isRecentBlurEffectDisable || this.isPowerSaveMode || this.blurEffect.isRecentBlurEffect ||
this.launcherOpacity.value !== 1;
}
/**
* 负一屏是否禁用实时模糊
* @returns true:禁用模糊, false:不禁用
*/
public isNegativeBlurEffectDisabled(): boolean {
return this.isNegativeBlurEffectDisable || this.isPowerSaveMode || this.blurEffect.isNegativeScreenEffect;
}
/**
* 全搜是否禁用实时模糊
* @returns true:禁用模糊, false:不禁用
*/
public isGlobalSearchBlurEffectDisabled(): boolean {
let isGlobalSearchDisabled: boolean = this.isGlobalSearchBlurEffectDisable || this.isPowerSaveMode ||
this.blurEffect.isGlobalSearchEffect;
log.showWarn(`isGlobalSearchBlurEffectDisabled ${isGlobalSearchDisabled}`);
return isGlobalSearchDisabled;
}
/**
* 文件夹是否禁用实时模糊
* @returns true:禁用模糊, false:不禁用
*/
public isFolderBlurEffectDisabled(): boolean {
let isFolderEffect = this.isFolderBlurEffectDisable || this.isPowerSaveMode || this.blurEffect.isFolderBlurEffect;
log.showWarn(`isFolderDisabled ${isFolderEffect}`);
return isFolderEffect;
}
/**
* 启动退出是否禁用实时模糊
* @returns true:禁用模糊, false:不禁用
*/
public isTransitionBlurEffectDisabled(): boolean {
return this.isTransitionBlurEffectDisable;
}
/**
* 注册多任务模糊监听器
*/
public registerRecentBlurEvent(): void {
if (this.isRecentBlurEffectDisabled()) {
log.showInfo('registerRecentBlurEvent success');
GlobalContext.getContext()?.eventHub.on(VisualEffectConstants.IS_RECENT_BLUR_EFFECT,
(isEnabled: boolean, blurAnimDelayTime: number) =>
this.startBlurAnim(isEnabled, BlurEffectType.RECENT, false, blurAnimDelayTime));
}
}
/**
* 反注册多任务模糊监听器
*/
public unRegisterRecentBlurEvent(): void {
if (this.isRecentBlurEffectDisable || (!this.isPowerSaveMode && !this.blurEffect.isRecentBlurEffect)) {
log.showInfo('unRegisterRecentBlurEvent success');
GlobalContext.getContext()?.eventHub.off(VisualEffectConstants.IS_RECENT_BLUR_EFFECT);
}
}
/**
* 多任务模糊事件触发
*/
public triggerRecentBlurEvent(isEnabled: boolean): void {
if (this.isRecentBlurEffectDisabled()) {
GlobalContext.getContext()?.eventHub.emit(VisualEffectConstants.IS_RECENT_BLUR_EFFECT, isEnabled);
}
}
/**
* 注册启动退出模糊监听器
*/
public registerIconStartExitBlurEvent(): void {
if (this.isTransitionBlurEffectDisable) {
GlobalContext.getContext()?.eventHub.on(VisualEffectConstants.ICON_START_EXIT_BLUR_EFFECT,
(isEnabled: boolean, blurAnimDelayTime: number) =>
this.startBlurAnim(isEnabled, BlurEffectType.ICON_START_EXIT, false, blurAnimDelayTime));
}
}
/**
* 反注册启动退出模糊监听器
*/
public unRegisterIconStartExitBlurEvent(): void {
if (this.isTransitionBlurEffectDisable) {
GlobalContext.getContext()?.eventHub.off(VisualEffectConstants.ICON_START_EXIT_BLUR_EFFECT);
}
}
/**
* 启动退出模糊事件触发
*/
public triggerIconStartExitBlurEvent(isEnabled: boolean): void {
if (this.isTransitionBlurEffectDisable) {
GlobalContext.getContext()?.eventHub.emit(VisualEffectConstants.ICON_START_EXIT_BLUR_EFFECT, isEnabled);
}
}
/**
* 根据ScenePanel状态触发多任务动效,并识别桌面是否需要做淡入淡出动效
* @param fromState 上一个ScenePanel状态
* @param curState 当前ScenePanel状态
* @param blurAnimDelayTime 壁纸模糊动效的延时
* @returns true: 启用壁纸模糊效果, false: 不启用壁纸模糊效果
*/
public triggerDesktopBlurByPanelState(fromState: ScenePanelState, curState: ScenePanelState,
blurAnimDelayTime?: number): boolean {
log.showInfo(`triggerDesktopBlurByPanelState blurAnimDelayTime:${blurAnimDelayTime}, fromState: ${fromState}, curState: ${curState}`);
this.isLauncherOpAnimDisable = this.isLauncherOpAnimDisabled(fromState, curState);
let isBlurEnabled: boolean = curState === ScenePanelState.RECENT || curState === ScenePanelState.QUICK_SWITCH;
if (fromState !== ScenePanelState.QUICK_SWITCH || curState !== ScenePanelState.FULLSCENE) {
GlobalContext.getContext()?.eventHub.emit(
VisualEffectConstants.IS_RECENT_BLUR_EFFECT, isBlurEnabled, blurAnimDelayTime);
}
return isBlurEnabled;
}
/**
* 根据分屏多窗状态触发多任务动效,并识别桌面是否需要做淡入淡出动效
* @param fromState 上一个OneStep状态
* @param curState 当前OneStep状态
*/
public triggerDesktopBlurByOneStepState(fromState: number, curState: number): void {
if (!this.isRecentBlurEffectDisable || fromState !== ONE_STEP_DEFAULT || (curState !== ONE_STEP_SHOW_BG_AND_ICON &&
curState !== ONE_STEP_ENTER_SPLIT && curState !== ONE_STEP_ENTER_FLOATING &&
curState !== ONE_STEP_ENTER_MID_SCENE)) {
return;
}
log.showInfo('triggerDesktopBlurByOneStepState');
this.isLauncherOpAnimDisable = true;
GlobalContext.getContext()?.eventHub.emit(VisualEffectConstants.IS_RECENT_BLUR_EFFECT, true);
}
/**
* 退出壁纸模糊效果, 保证此场景下桌面透明渐变效果启用
*/
public exitBlurWithLauncherOpAnim(blurAnimDelayTime: number = 0): void {
if (this.isRecentBlurEffectDisabled()) {
log.showInfo('exitBlurWithLauncherOpAnim');
this.isLauncherOpAnimDisable = false;
GlobalContext.getContext()?.eventHub.emit(VisualEffectConstants.IS_RECENT_BLUR_EFFECT, false, blurAnimDelayTime);
}
}
/**
* 多任务快切场景下,等快切动效结束后退出模糊
*/
public exitBlurWithoutAnim(): void {
if (this.isRecentBlurEffectDisabled()) {
log.showInfo('exitBlurWithoutAnim');
this.onBlurAnimEvent(false, BlurEffectType.RECENT);
}
}
/**
* 注册文件夹模糊监听器
*/
public registerFolderFullBlurEvent(): void {
if (this.isFolderBlurEffectDisabled()) {
GlobalContext.getContext()?.eventHub.on(VisualEffectConstants.FOLDER_BLUR_EFFECT,
(effectValue: boolean, isFolderClosed: boolean) =>
this.startBlurAnim(effectValue, BlurEffectType.FOLDER, isFolderClosed));
}
}
/**
* 反注册文件夹模糊监听器
*/
public unRegisterFolderFullBlurEvent(): void {
if (this.isFolderBlurEffectDisable || (!this.isPowerSaveMode && !this.blurEffect.isFolderBlurEffect)) {
GlobalContext.getContext()?.eventHub.off(VisualEffectConstants.FOLDER_BLUR_EFFECT);
}
}
/**
* 文件夹模糊事件触发
* @returns true:触发, false:不触发
*/
public triggerFolderFullBlurEvent(isEnabled: boolean): boolean {
if (this.isFolderBlurEffectDisabled()) {
if (editModeManager.isInEditMode()) {
this.updateBlurEffect(isEnabled, BlurEffectType.EDIT_MODE_FOLDER);
AppStorage.setOrCreate('editModeFolderBlurEffect', isEnabled);
} else {
GlobalContext.getContext()?.eventHub.emit(VisualEffectConstants.FOLDER_BLUR_EFFECT, isEnabled, false);
}
this.updateFolderBlurEffect();
return true;
}
return false;
}
/**
* 返回模糊触发场景
* @returns true:触发, false:不触发, undefined: 不触发
*/
public isBlurEffectEnabledByType(effectType: BlurEffectType): boolean | undefined {
switch (effectType) {
case BlurEffectType.RECENT:
return this.blurEffect.isRecentBlurEffect;
case BlurEffectType.NEGATIVE_SCREEN:
return this.blurEffect.isNegativeScreenEffect;
case BlurEffectType.FOLDER:
return this.blurEffect.isFolderBlurEffect;
case BlurEffectType.EDIT_MODE_FOLDER:
return this.blurEffect.isEditModeFolderEffect;
case BlurEffectType.GLOBAL_SEARCH:
return this.blurEffect.isGlobalSearchEffect;
case BlurEffectType.ICON_START_EXIT:
return this.blurEffect.isStartExitBlurEffect;
default:
return undefined;
}
}
/**
* 从应用内手势上滑前隐藏桌面,避免后续跟手时漏桌面图标
*/
public hideLauncher(): void {
if (launcherVisualEffectMgr.isRecentBlurEffectDisabled() && this.launcherOpacity.value === 1) {
log.showWarn('hideLauncher');
this.launcherOpacity.value = 0;
}
}
private isLauncherOpAnimDisabled(fromState: ScenePanelState, curState: ScenePanelState): boolean {
return this.launcherOpacity.value === 0 &&
(fromState === ScenePanelState.RECENT && curState === ScenePanelState.FULLSCENE ||
fromState === ScenePanelState.FULLSCENE && curState === ScenePanelState.RECENT ||
fromState === ScenePanelState.FULLSCENE && curState === ScenePanelState.QUICK_SWITCH ||
fromState === ScenePanelState.QUICK_SWITCH && curState === ScenePanelState.FULLSCENE ||
fromState === ScenePanelState.HOME && curState === ScenePanelState.QUICK_SWITCH);
}
/**
* 是否启用壁纸模糊效果
* @returns true:启用, false:不启用
*/
private isWallpaperBlurEffectEnabled(): boolean {
const isWallpaperBlurEffectEnabled: boolean =
this.blurEffect.isRecentBlurEffect || this.blurEffect.isNegativeScreenEffect ||
this.blurEffect.isFolderBlurEffect || this.blurEffect.isGlobalSearchEffect ||
this.blurEffect.isStartExitBlurEffect
log.showWarn(`isWallpaperBlurEffectEnabled: ${isWallpaperBlurEffectEnabled}, isRecentBlurEffect: ` +
`${this.blurEffect.isRecentBlurEffect}, isNegativeScreenEffect: ${this.blurEffect.isNegativeScreenEffect}` +
`isFolderBlurEffect: ${this.blurEffect.isFolderBlurEffect}, isGlobalSearchEffect:` +
`${this.blurEffect.isGlobalSearchEffect}, isStartExitBlurEffect: ${this.blurEffect.isStartExitBlurEffect}`);
return isWallpaperBlurEffectEnabled;
}
private checkBlurAnimIsInvalid(newState: boolean, effectType: BlurEffectType): boolean {
let oldState: boolean | undefined = this.isBlurEffectEnabledByType(effectType);
log.showWarn(`oldState: ${oldState}, newState: ${newState} effectType: ${effectType}`);
if (oldState === newState) {
if (newState) {
return this.launcherOpacity.value === 0 && this.wallpaperBlurOpacity.value === 1;
} else {
return this.launcherOpacity.value === 1 && this.wallpaperBlurOpacity.value === 0;
}
}
return false;
}
private startBlurAnim(isEnabled: boolean, effectType: BlurEffectType, isFolderClosed: boolean = false,
blurAnimDelayTime: number = 0): void {
log.showWarn(`startBlurAnim isEnabled: ${isEnabled}, effectType: ${effectType}`);
if (this.checkBlurAnimIsInvalid(isEnabled, effectType)) {
log.showWarn('checkBlurAnimIsInvalid return.');
return;
}
if (effectType === BlurEffectType.ICON_START_EXIT && !isEnabled) {
this.updateBlurEffect(isEnabled, effectType);
return;
}
if (effectType === BlurEffectType.ICON_START_EXIT && isEnabled) {
this.onPreBlurAnim(effectType);
animateToImmediately({
duration: 100,
curve: Curve.Smooth,
onFinish: () => {
this.onBlurAnimFinish();
}
}, () => {
this.isUseEffect = true;
this.updateBlurEffect(isEnabled, effectType);
this.setWallpaperBlurActive();
});
return;
}
if (isFolderClosed) {
this.onBlurAnimEvent(isEnabled, effectType);
} else {
this.onPreBlurAnim(effectType);
animateTo({
delay: blurAnimDelayTime,
duration: 200,
curve: effectType === BlurEffectType.RECENT ? this.ANIMATION_CURVE : Curve.Smooth,
onFinish: () => {
this.onBlurAnimFinish();
}
}, () => {
this.isUseEffect = true;
this.onBlurAnimEvent(isEnabled, effectType);
});
}
}
private onBlurAnimEvent(isEnabled: boolean, effectType: BlurEffectType, progress: number = -1): void {
this.updateBlurEffect(isEnabled, effectType);
this.addMaskByBlurEffect();
this.setLauncherOpacity(progress, effectType);
this.setWallpaperBlurOpacity(progress, effectType);
if (effectType === BlurEffectType.RECENT) {
this.setOthersOpacity(isEnabled);
if (!folderGesData.isAddDialogOpening()) {
this.folderOpacity.value = this.othersOpacity.value;
}
if (!this.isShowUIExtension) {
this.editModeButtonOpacity.value = this.othersOpacity.value;
}
}
}
/**
* 根据负一屏,全搜滑动进度处理动效
* @param progress 负一屏,全搜滑动进度值,effectType:默认负一屏
*/
public onProgressChange(progress: number, effectType: BlurEffectType = BlurEffectType.NEGATIVE_SCREEN): void {
log.showInfo(`onProgressChange start:${progress}; effectType:${effectType}`);
// 负一屏合全搜拉起时必须要隐藏图标,其他场景按需维护
if (![BlurEffectType.NEGATIVE_SCREEN, BlurEffectType.GLOBAL_SEARCH].includes(effectType)) {
const isFolderOpen: boolean = FolderManager.getInstance().isFolderOpen();
log.showInfo(`onProgressChange isFolderOpen:${isFolderOpen}; effectType:${effectType}`);
if (isFolderOpen) {
log.showWarn('onProgressChange isFolderOpen return.');
return;
}
}
let isEnable: boolean = progress > 0;
this.onBlurAnimEvent(isEnable, effectType, progress);
this.isUseEffect = this.isWallpaperBlurEffectEnabled();
log.showInfo(`onProgressChange end`);
}
public updateBlurEffect(isEnabled: boolean, effectType: BlurEffectType): void {
log.showInfo(`updateBlurEffect isEnabled: ${isEnabled}, effectType: ${effectType}`);
switch (effectType) {
case BlurEffectType.FOLDER:
this.blurEffect.isFolderBlurEffect = isEnabled;
this.updateFolderBlurEffect();
break;
case BlurEffectType.RECENT:
this.blurEffect.isRecentBlurEffect = isEnabled;
break;
case BlurEffectType.NEGATIVE_SCREEN:
this.blurEffect.isNegativeScreenEffect = isEnabled;
break;
case BlurEffectType.EDIT_MODE_FOLDER:
this.blurEffect.isEditModeFolderEffect = isEnabled;
break;
case BlurEffectType.GLOBAL_SEARCH:
this.blurEffect.isGlobalSearchEffect = isEnabled;
this.updateGlobalSearchBlurEffect();
break;
case BlurEffectType.ICON_START_EXIT:
this.blurEffect.isStartExitBlurEffect = isEnabled;
break;
default:
break;
}
if (this.blurEffect.isRecentBlurEffect || this.blurEffect.isFolderBlurEffect) {
this.blurEffect.isStartExitBlurEffect = false;
}
this.isWallpaperBlurEffect.value = this.isWallpaperBlurEffectEnabled();
}
private setLauncherOpacity(progress: number, reason?: string): void {
if (this.isLauncherOpAnimDisable || this.isShowUIExtension) {
return;
}
let launcherOpacity: number = 0;
if (progress < 0) {
launcherOpacity = this.isWallpaperBlurEffect.value ? 0 : 1;
} else {
launcherOpacity = 1 - progress;
}
this.setLauncherOpacityWithDfx(launcherOpacity, reason)
}
private setWallpaperBlurOpacity(progress: number, reason?: string): void {
let wallpaperBlurOpacity: number = 0;
if (progress < 0) {
wallpaperBlurOpacity = this.isWallpaperBlurEffect.value ? 1 : 0;
} else {
wallpaperBlurOpacity = progress;
}
this.setWallpaperBlurOpacityWithDfx(wallpaperBlurOpacity, reason);
}
/**
* 设置桌面透明度
* @param value 桌面透明度
* @param callerFunctionName 调用来源
*/
public setLauncherOpacityWithDfx(value: number, callerFunctionName?: string): void {
if (this.launcherOpacity.value === value) {
return;
}
log.showWarn(`setLauncherOpacityValue ${value}, caller function name: ${callerFunctionName}`);
this.launcherOpacity.value = value;
}
/**
* 设置壁纸模糊透明度
* @param value 壁纸模糊透明度
* @param callerFunctionName 调用来源
*/
public setWallpaperBlurOpacityWithDfx(value: number, callerFunctionName?: string): void {
if (this.wallpaperBlurOpacity.value === value) {
return;
}
log.showWarn(`setWallpaperBlurOpacityValue ${value}, caller function name: ${callerFunctionName}`);
this.wallpaperBlurOpacity.value = value;
}
/**
* 设置去壁纸模糊
* @param callerFunctionName
*/
public setWallpaperBlurInactive(callerFunctionName: string = 'sceneContainerTransitionOut'): void {
if (this.blurEffect.isStartExitBlurEffect || this.blurEffect.isFolderBlurEffect) {
this.setLauncherOpacityWithDfx(1, callerFunctionName);
this.setWallpaperBlurOpacityWithDfx(0, callerFunctionName);
}
}
/**
* 设置上壁纸模糊
* @param callerFunctionName
*/
public setWallpaperBlurActive(callerFunctionName: string = 'sceneContainerTransitionIn'): void {
if (this.blurEffect.isStartExitBlurEffect) {
this.setLauncherOpacityWithDfx(0, callerFunctionName);
this.setWallpaperBlurOpacityWithDfx(1, callerFunctionName);
}
}
private setOthersOpacity(isEnabled: boolean): void {
this.othersOpacity.value = isEnabled ? 0 : 1;
}
/**
* 当多任务显示时,负一屏需要透明
* @returns 负一屏透明度
*/
public getNegativeScreenOpacity(): StateEx<number> {
return this.othersOpacity;
}
/**
* 当多任务显示时,全搜需要透明
* @returns 全搜透明度
*/
public getGlobalSearchOpacity(): StateEx<number> {
return this.othersOpacity;
}
/**
* 当多任务显示时,打开的文件夹需要透明
* @returns 文件夹组件透明度
*/
public getOpenFolderOpacity(): StateEx<number> {
return this.folderOpacity;
}
/**
* 当多任务显示时,编辑模式下按钮需要透明
* @returns 编辑模式下按钮透明度
*/
public getEditModeButtonOpacity(): StateEx<number> {
return this.editModeButtonOpacity;
}
/**
* 当多任务显示时,编辑模式下topBar需要透明
* @returns 编辑模式下topBar透明度
*/
public getEditModeTopBarOpacity(): StateEx<number> {
return this.othersOpacity;
}
/**
* 当多任务显示时,桌面弹框需要透明
* @returns 桌面弹框透明度
*/
public getDesktopDialogOpacity(): StateEx<number> {
return this.othersOpacity;
}
/**
* 当多任务显示时,编辑模式下UI需要透明
* @returns 编辑模式下UI透明度
*/
public getEditModeExtensionUIOpacity(): StateEx<number> {
return this.othersOpacity;
}
/**
* 桌面滑动定制裁剪是否启用
* @returns true:启用定制裁剪, false:不启用定制裁剪
*/
public isLauncherSwiperCustomEnabled(): boolean {
return this.isLauncherSwiperCustomEnable;
}
/**
* 编辑模式下UIExtension是否显示
* @param isShow: UIExtension是否显示
*/
public setShowUIExtension(isShow: boolean): void {
this.isShowUIExtension = isShow;
}
private onPreBlurAnim(effectType: BlurEffectType): void {
this.isBlurAnimRunning.value = true;
this.hideLauncherForUIExtension();
if (effectType !== BlurEffectType.FOLDER) {
this.hideFolderForAddDialog();
}
}
private onBlurAnimFinish(): void {
this.isBlurAnimRunning.value = false;
this.unRegisterRecentBlurEventIfNeed();
if (!this.isWallpaperBlurEffect.value) {
this.resetAnimData();
} else {
this.showFolderForAddDialog();
}
log.showWarn(`startBlurAnim onFinish => launcherOpacity: ${this.launcherOpacity.value}` +
`, wallpaperBlurOpacity: ${this.wallpaperBlurOpacity.value}`);
}
private hideLauncherForUIExtension(): void {
if (this.isShowUIExtension) {
this.launcherOpacity.value = 0;
this.editModeButtonOpacity.value = 0;
}
}
private hideFolderForAddDialog(): void {
if (folderGesData.isAddDialogOpening()) {
this.folderOpacity.value = 0;
}
}
private showFolderForAddDialog(): void {
if (folderGesData.isAddDialogOpening() && !this.blurEffect.isRecentBlurEffect) {
this.folderOpacity.value = 1;
}
}
private resetAnimData(): void {
this.isUseEffect = false;
this.setLauncherOpacityWithDfx(1, 'resetAnimData');
this.editModeButtonOpacity.value = 1;
this.folderOpacity.value = 1;
this.isShowMask.value = false;
}
private resetLauncherVisualEffect(): void {
this.isUseEffect = false;
this.setLauncherOpacityWithDfx(1, 'reset');
this.setWallpaperBlurOpacity(0, 'reset');
this.isShowMask.value = false;
this.othersOpacity.value = 1;
this.editModeButtonOpacity.value = 1;
this.folderOpacity.value = 1;
}
/**
* 更新颜色模式
*/
public updateColorMode(colorMode: number): void {
this.colorMode = colorMode;
}
private addMaskByBlurEffect(): void {
this.isShowMask.value = true;
this.updateMastColor();
}
private updateMastColor(): void {
const isLightColorMode: boolean = this.colorMode === LIGHT_COLOR_MODE;
const isDarkColorMode: boolean = this.colorMode === DARK_COLOR_MODE;
if (!isLightColorMode && !isDarkColorMode) {
this.maskColor.value = MASK_COLOR_FOR_DEFAULT;
return;
}
if (this.blurEffect.isRecentBlurEffect) {
this.maskColor.value = isLightColorMode ? MASK_COLOR_RECENT_LIGHT : MASK_COLOR_RECENT_DARK;
} else if (this.blurEffect.isFolderBlurEffect) {
this.maskColor.value = isLightColorMode ? MASK_COLOR_FOLDER_LIGHT : MASK_COLOR_FOLDER_DARK;
} else if (this.blurEffect.isNegativeScreenEffect) {
this.maskColor.value = isLightColorMode ? MASK_COLOR_FOR_DEFAULT : MASK_COLOR_NEGATIVE_DARK;
} else {
this.maskColor.value = isLightColorMode ? MASK_COLOR_FOR_DEFAULT : MASK_COLOR_GLOBALSEARCH_DARK;
}
}
private unRegisterRecentBlurEventIfNeed(): void {
if (!this.isRecentBlurEffectDisable && !this.isPowerSaveMode && !this.blurEffect.isRecentBlurEffect &&
this.launcherOpacity.value === 1) {
GlobalContext.getContext()?.eventHub.off(VisualEffectConstants.IS_RECENT_BLUR_EFFECT);
}
}
private updateFolderBlurEffect(): void {
log.showWarn(`updateFolderBlurEffect disable:${this.isFolderBlurEffectDisable} powerSaveMode:${this.isPowerSaveMode}
isFolderBulr:${this.blurEffect.isFolderBlurEffect}`);
this.isShowFolderBlurEffect.value =
this.isFolderBlurEffectDisable || this.isPowerSaveMode || this.blurEffect.isFolderBlurEffect;
}
private updateGlobalSearchBlurEffect():void{
this.isShowGlobalSearchBlurEffect.value = this.isGlobalSearchBlurEffectDisable || this.isPowerSaveMode ||
this.blurEffect.isGlobalSearchEffect;
}
}
// 单例
export let launcherVisualEffectMgr: LauncherVisualEffectManager =
SingletonHelper.getInstance(LauncherVisualEffectManager, TAG);