* Copyright (c) 2024-2024 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 {
DeviceHelper,
GlobalContext,
ViewManagerPolicy,
ViewType,
WallpaperChangeListener,
WallpaperManager,
WallpaperType,
} from '@ohos/frameworkwrapper';
import { ItemUtils } from '@ohos/componenthelper';
import { CheckEmptyUtils, LogDomain, LogHelper, Trace, SingletonHelper } from '@ohos/basicutils';
import { StyleConstants } from '../constants/StyleConstants';
import { ColorUtil } from '../utils/ColorUtil';
import { DeviceState } from '../constants/CommonConstants';
import type image from '@ohos.multimedia.image';
import effectKit from '@ohos.effectKit';
import ComponentPosShadowCache from '../cache/ComponentPosShadowCache';
import { ThemeActivationEvent } from '@ohos/frameworkwrapper/src/main/ets/eventbus/events/Events';
import { preferences } from '@kit.ArkData';
import { LaunchLayoutCacheManager, LayoutDescription } from '../TsIndex';
import { CommonConstants } from '../constants/CommonConstants';
import type ctx from '@ohos.app.ability.common';
import { componentUtils, display } from '@kit.ArkUI';
const TAG = 'TextShadowManager';
const DEFAULT_COLOR_COMPONENT = 255;
const SNAP_WALLPAPER_TIMEOUT = 500;
const SNAP_WALLPAPER_MAX_TRY_COUNT = 3;
const IS_LOAD_NEXT_FROM_PREFERENCE = 'isCanNextLoadFromSp';
const NEXT_TEXT_SHADOW_LIST = 'nextTextShadowList';
const CONTRAST2WHITE_LOW: number = 1.2;
const CONTRAST2WHITE_HIGH: number = 1.5;
const DIVIDE_TWO: number = 2.0;
const log: LogHelper = LogHelper.getLogHelper(LogDomain.HOME, TAG);
export class TextShadowManager {
private tryCount: number = 0;
private isCanLoadSinglePage: boolean | undefined = undefined;
private isCanLoadLeftPage: boolean | undefined = undefined;
private isCanLoadRightPage: boolean | undefined = undefined;
private wallPaperListener: WallpaperChangeListener = {
registeredTag: TAG,
listenerType: WallpaperType.ALL,
onWallPaperChange: (event: ThemeActivationEvent) => {
log.showInfo('WallpaperColorManager WallPaper Change');
ComponentPosShadowCache.getInstance().clearCache();
this.resetLoadShadowStatus();
this.tryUpdateWallpaper(true, true);
}
};
constructor() {
if (DeviceHelper.isPC()) {
return;
}
WallpaperManager.getInstance().addWallpaperChangeListener(this.wallPaperListener);
}
* 生成文字阴影
*
* @param info AppItemTextShadowInfo
* @param shadowKey the key to cache the textShadow
* @returns color of text shadow;
*/
public async generateShadow(info: AppItemTextShadowInfo, shadowKey: string, snap: image.PixelMap):
Promise<string | undefined> {
if (await this.isLoadFromPreference()) {
log.showWarn('not need to generateShadow as isLoadFromPreference');
return undefined;
}
if (info.screenWidth <= info.startOffsetX || info.screenHeight <= info.startOffsetY) {
log.showError(`the screen width is error screenWidth ${info.screenWidth} screenHeight ${info.screenHeight}`);
return undefined;
}
let resColorShadow: string | undefined = undefined;
let colorPickerWidth = info.nameWidth;
let colorPickerX = info.startOffsetX;
let colorPickerRegion: Array<number> = [colorPickerX / info.screenWidth, info.startOffsetY / info.screenHeight,
(colorPickerX + colorPickerWidth) / info.screenWidth, (info.startOffsetY + info.nameHeight) / info.screenHeight];
await this.getShadowColor(snap, colorPickerRegion).then((colorShadow: string | undefined) => {
if (colorShadow !== undefined) {
log.showInfo(`caching the TextShadow color ${colorShadow}, key ${shadowKey}`);
ComponentPosShadowCache.getInstance().setCache(shadowKey, colorShadow);
}
resColorShadow = colorShadow;
}).catch((error: Error) => {
log.showInfo(`generateShadow error with msg ${error?.message}`);
});
return resColorShadow;
}
* 从背景图上按区域取出背景颜色
*
* @param snap 背景图
* @param colorPickerRegion 取色的区域
*/
public async getShadowColor(snap: image.PixelMap, colorPickerRegion: Array<number>): Promise<string | undefined> {
let resultColor: string | undefined = undefined;
let cPicker: effectKit.ColorPicker | undefined = undefined;
await effectKit.createColorPicker(snap, colorPickerRegion).then((colorPicker) => {
cPicker = colorPicker;
let alpha: number = 0;
let color = colorPicker.getLargestProportionColor();
if (!color) {
log.showError('generateShadow, get largest proportion color failed.');
return undefined;
}
let backgroundLuminance = ColorUtil.rgb2Luminance(color.red, color.green, color.blue);
let contrast2White = ColorUtil.contrast2White(backgroundLuminance);
if (contrast2White >= CONTRAST2WHITE_LOW && contrast2White <= CONTRAST2WHITE_HIGH) {
alpha = StyleConstants.APP_NAME_SHADOW_PERCENT_LOWER;
} else {
alpha = ColorUtil.rgb2ShadowAlpha(color.red, color.green, color.blue);
}
log.showInfo('generateShadow, average red:%{public}d green:%{public}d blue:%{public}d alpha:%{public}d',
color.red, color.green, color.blue, alpha);
resultColor = ColorUtil.convertRGBA2ResourceColor(5, 5, 5, Math.ceil(((alpha < 0 || alpha >= 1) ? 0 : alpha) * DEFAULT_COLOR_COMPONENT));
return resultColor;
}).catch((error: Error) => {
log.showInfo(`generate the text shadow error ${error?.message}`);
resultColor = undefined;
}).finally(() => {
});
return resultColor;
}
* 尝试获取桌面壁纸组件的截图
* 时机: 1、解锁; 2、替换壁纸; 3、获取桌面壁纸失败的时候
*
* @param isForce 是否强制更新
*/
public tryUpdateWallpaper(isForce: boolean = false, isNeedDelay: boolean): void {
if (!isForce) {
log.showInfo('tryUpdateWallpaper desktopImageSnapshot is Exist, return');
return;
}
log.showInfo('tryUpdateWallpaper isForce: %{public}s, tryCount: %{public}d', isForce, this.tryCount);
let delayTime = isNeedDelay ? SNAP_WALLPAPER_TIMEOUT : 0;
setTimeout(() => {
this.handleDesktopWallpaperChange(isForce);
}, delayTime);
}
public async handleDesktopWallpaperChange(isNewWallPaper: boolean = false): Promise<void> {
let isNewStyle: boolean = AppStorage.get<boolean>('desktopNewStyle') ?? true;
let desktopTextShadow: boolean = AppStorage.get<boolean>('desktopTextShadow') ?? true;
if (!(isNewStyle && desktopTextShadow)) {
return;
}
let isLoadFromSp: boolean = await textShadowMgr.isLoadFromPreference();
if (isLoadFromSp) {
log.showWarn('handleDesktopWallpaperChange load from preference');
if (!AppStorage.Has('wallpaperSnapshotChangeFlag')) {
AppStorage.setOrCreate<boolean>('wallpaperSnapshotChangeFlag', false);
} else {
let wallpaperSnapshotChangeFlag = AppStorage.get<boolean>('wallpaperSnapshotChangeFlag');
AppStorage.setOrCreate('wallpaperSnapshotChangeFlag', !wallpaperSnapshotChangeFlag);
}
return;
}
if (ViewManagerPolicy.getViewController(ViewType.KEYGUARD)?.isShowing()) {
log.showInfo('No screenshot is taken when the screen is locked.');
return;
}
log.showInfo('start create snapshot.');
Trace.start('handleDesktopWallpaperChange');
this.getWallPaperSnap().then(pixmap => {
if (CheckEmptyUtils.isEmpty(pixmap)) {
log.error('handleDesktopWallpaperChange create wallpaperSnap failed');
if (this.tryCount < SNAP_WALLPAPER_MAX_TRY_COUNT) {
this.tryCount++;
this.tryUpdateWallpaper(false, true);
} else {
log.showError('handleDesktopWallpaperChange componentSnapshot fail, not try again');
}
return;
}
this.updateDesktopWallpaperPixmap(pixmap, isNewWallPaper);
});
Trace.end('handleDesktopWallpaperChange');
}
private async getWallPaperSnap(): Promise<image.PixelMap> {
let wallPaper: image.PixelMap = await WallpaperManager.getInstance().getWallpaperCache(WallpaperType.DESKTOP, TAG);
return wallPaper;
}
private updateDesktopWallpaperPixmap(pixmap: image.PixelMap, isNewWallPaper: boolean): void {
this.tryCount = 0;
try {
effectKit.createColorPicker(pixmap).then(colorPicker => {
let degree = colorPicker.discriminatePitureLightDegree();
log.showInfo('handleDesktopWallpaperChange degree: %{public}d', degree);
}).catch((error: Error) => {
log.showError('createColorPicker with error %{public}s', error.message);
});
} catch (error) {
log.showError('updateDesktopWallpaperPixmap with error %{public}s', error.message);
}
if (!AppStorage.has('wallpaperSnapshotChangeFlag')) {
AppStorage.setOrCreate<boolean>('wallpaperSnapshotChangeFlag', false);
} else {
let wallpaperSnapshotChangeFlag = AppStorage.get<boolean>('wallpaperSnapshotChangeFlag');
AppStorage.setOrCreate('wallpaperSnapshotChangeFlag', !wallpaperSnapshotChangeFlag);
}
log.showInfo('finish create snapshot.');
}
public resetLoadShadowStatus(): void {
this.isCanLoadSinglePage = false;
this.isCanLoadLeftPage = false;
this.isCanLoadRightPage = false;
let context = (GlobalContext.getInstance().getObject('desktopContext') as ctx.ServiceExtensionContext);
try {
preferences.getPreferences(context, 'TextShadowData').then((preference) => {
preference.put(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${TextShadowScreenType.SINGLE_PAGE}`, this.isCanLoadSinglePage);
preference.put(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${TextShadowScreenType.DOUBLE_LEFT_PAGE}`, this.isCanLoadLeftPage);
preference.put(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${TextShadowScreenType.DOUBLE_RIGHT_PAGE}`, this.isCanLoadRightPage);
preference.flush().then((res) => {
log.showInfo(TAG, `save restore data to sp success: ${res}`);
}).catch((reject) => {
log.showInfo(TAG, 'save restore data to sp fail: %{public}s', reject);
});
}).catch((error: Error) => {
log.showInfo('setCanLoadFromSp error with message %{public}s', error.message);
});
} catch (error) {
log.showError('getPreferencesSync with error %{public}s', error.message);
}
}
* 更新isLoadFromSp状态
*
* @param isLoadFromSp true可以从sp更新
* @param isLeftPage 是否是左半屏
* @param isRightPage 是否是右半屏
*/
public setCanLoadFromSp(isLoadFromSp: boolean, isLeftPage: boolean, isSinglePage: boolean): void {
this.updateShadowLoadStatus(isLoadFromSp, isLeftPage, isSinglePage);
let textShadowScreen: number = isSinglePage ? TextShadowScreenType.SINGLE_PAGE :
(isLeftPage ? TextShadowScreenType.DOUBLE_LEFT_PAGE : TextShadowScreenType.DOUBLE_RIGHT_PAGE);
let context = (GlobalContext.getInstance().getObject('desktopContext') as ctx.ServiceExtensionContext);
try {
preferences.getPreferences(context, 'TextShadowData').then((preference) => {
preference.put(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${textShadowScreen}`, isLoadFromSp);
preference.flush().then((res) => {
log.showInfo(TAG, `save restore data to sp success: ${res}`);
}).catch((reject) => {
log.showInfo(TAG, 'save restore data to sp fail: %{public}s', reject);
});
}).catch((error: Error) => {
log.showInfo('setCanLoadFromSp error with message %{public}s', error.message);
});
} catch (error) {
log.showError('getPreferences with error %{public}s', error.message);
}
}
private updateShadowLoadStatus(isLoadFromSp: boolean, isLeftPage: boolean, isSinglePage: boolean): void {
if (isSinglePage) {
this.isCanLoadSinglePage = isLoadFromSp;
} else {
if (isLeftPage) {
this.isCanLoadLeftPage = isLoadFromSp;
} else {
this.isCanLoadRightPage = isLoadFromSp;
}
}
}
* 返回是否可以从preference加载textShadow
*/
public getIsCanLoadFromPreference(folderStatus: number): boolean {
if (folderStatus === DeviceState.EXPAND_STATE) {
return (this.isCanLoadLeftPage && this.isCanLoadRightPage) ?? false;
}
return this.isCanLoadSinglePage ?? false;
}
* 是否从preference中加载文字阴影
*
* @returns true 从preference中加载
*/
public async isLoadFromPreference(): Promise<boolean> {
let result: boolean = false;
if (DeviceHelper.isFoldExpanded()) {
result = await this.getDoublePageLoadFromPreference();
} else {
result = await this.getSinglePageLoadFromPreference();
}
return result;
}
private async getSinglePageLoadFromPreference(): Promise<boolean> {
if (this.isCanLoadSinglePage === undefined) {
let context = (GlobalContext.getInstance().getObject('desktopContext') as ctx.ServiceExtensionContext);
try {
await preferences.getPreferences(context, 'TextShadowData').then((preference) => {
this.isCanLoadSinglePage = preference.getSync(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${TextShadowScreenType.SINGLE_PAGE}`, false) as boolean;
}).catch((error: Error) => {
log.showInfo('getSinglePageLoadFromPreference error with message %{public}s', error.message);
this.isCanLoadSinglePage = false;
});
} catch (error) {
log.showError('getPreferences with error %{public}s', error.message);
}
}
return this.isCanLoadSinglePage ?? false;
}
private async getDoublePageLoadFromPreference(): Promise<boolean> {
if (this.isCanLoadLeftPage === undefined || this.isCanLoadRightPage === undefined) {
let context = (GlobalContext.getInstance().getObject('desktopContext') as ctx.ServiceExtensionContext);
try {
await preferences.getPreferences(context, 'TextShadowData').then((preference) => {
this.isCanLoadLeftPage = preference.getSync(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${TextShadowScreenType.DOUBLE_LEFT_PAGE}`, false) as boolean;
this.isCanLoadRightPage = preference.getSync(`${IS_LOAD_NEXT_FROM_PREFERENCE}_${TextShadowScreenType.DOUBLE_RIGHT_PAGE}`, false) as boolean;
}).catch((error: Error) => {
this.isCanLoadLeftPage = false;
this.isCanLoadRightPage = false;
log.showInfo('getDoublePageLoadFromPreference error with message %{public}s', error.message);
});
} catch (error) {
log.showError('getPreferences with error %{public}s', error.message);
}
}
return (this.isCanLoadLeftPage && this.isCanLoadRightPage) ?? false;
}
* 从SP解析文字阴影
*
* @returns true 解析成功
*/
public async parseTextShadowPreference(isLeftPage: boolean, isSinglePage: boolean): Promise<boolean> {
log.showInfo('load textShadow from sp');
let textShadowList: string[] = [];
let textShadowScreen: number = isSinglePage ? TextShadowScreenType.SINGLE_PAGE :
(isLeftPage ? TextShadowScreenType.DOUBLE_LEFT_PAGE : TextShadowScreenType.DOUBLE_RIGHT_PAGE);
let isLoadFromSp: boolean = true;
let context = (GlobalContext.getInstance().getObject('desktopContext') as ctx.ServiceExtensionContext);
try {
await preferences.getPreferences(context, 'TextShadowData').then((preference) => {
textShadowList = preference.getSync(this.getShadowPreference(textShadowScreen), []) as string[];
}).catch((error: Error) => {
log.showInfo('get TextShadowData from preference error %{public}s', error.message);
isLoadFromSp = false;
});
} catch (error) {
log.showError('getPreferences with error %{public}s', error.message);
}
let layoutDescription: LayoutDescription = LaunchLayoutCacheManager.getInstance().selectLayoutDescription();
let maxRow: number = layoutDescription.row;
let maxColumn: number = layoutDescription.column * StyleConstants.DEFAULT_2 - 1;
if (maxRow * maxColumn !== textShadowList.length || CheckEmptyUtils.isEmpty(textShadowList)) {
log.showInfo('parseTextShadowPreference error as the length of textShadowList is error');
isLoadFromSp = false;
}
if (!isLoadFromSp) {
this.setCanLoadFromSp(isLoadFromSp, isLeftPage, isSinglePage);
return false;
}
let shadowIndex: number = 0;
let page: number = this.getTextShadowScreenType(isSinglePage, isLeftPage);
for (let i = 0; i < maxRow; i++) {
for (let j = 0; j < maxColumn; j++) {
if (shadowIndex < textShadowList.length) {
ComponentPosShadowCache.getInstance().setCache(this.generateShadowKey(page, i, j), textShadowList[shadowIndex]);
}
shadowIndex++;
}
}
return true;
}
* 存储文字阴影到sp
*/
public async storeTextShadowPreference(isLeftPage: boolean, isSinglePage: boolean): Promise<void> {
let textShadowList: string[] = [];
let isLoadFinished: boolean = this.checkAndGetAllTextShadows(textShadowList, isLeftPage, isSinglePage);
let textShadowScreen: number = isSinglePage ? TextShadowScreenType.SINGLE_PAGE :
(isLeftPage ? TextShadowScreenType.DOUBLE_LEFT_PAGE : TextShadowScreenType.DOUBLE_RIGHT_PAGE);
if (!isLoadFinished || CheckEmptyUtils.isEmptyArr(textShadowList)) {
log.showError(`isLoadFinished false or textShadowList is empty!`);
return;
}
let context = (GlobalContext.getInstance().getObject('desktopContext') as ctx.ServiceExtensionContext);
try {
await preferences.getPreferences(context, 'TextShadowData').then((preference) => {
preference.putSync(this.getShadowPreference(textShadowScreen), textShadowList);
preference.flush().then((res) => {
log.showInfo(TAG, `save restore data to sp success: ${res}`);
}).catch((reject) => {
log.showInfo(TAG, 'save restore data to sp fail: %{public}s', reject);
});
this.setCanLoadFromSp(true, isLeftPage, isSinglePage);
log.showInfo('storeTextShadowPreference success');
}).catch((error: Error) => {
log.showWarn('failed to storeTextShadowPreference error %{public}s', error.message);
this.setCanLoadFromSp(false, isLeftPage, isSinglePage);
});
} catch (error) {
log.showError('getPreferences with error %{public}s', error.message);
}
}
private getShadowPreference(textShadowScreenType: number): string {
return `${NEXT_TEXT_SHADOW_LIST}_${textShadowScreenType}`;
}
private checkAndGetAllTextShadows(textShadowList: string[], isLeftPage: boolean, isSinglePage: boolean): boolean {
let layoutDescription: LayoutDescription = LaunchLayoutCacheManager.getInstance().selectLayoutDescription();
let maxRow: number = layoutDescription.row;
let maxColumn: number = layoutDescription.column * StyleConstants.DEFAULT_2 - 1;
let page: number = this.getTextShadowScreenType(isSinglePage, isLeftPage);
for (let i = 0; i < maxRow; i++) {
for (let j = 0; j < maxColumn; j++) {
let shadowColor: string = ComponentPosShadowCache.getInstance().getCache(this.generateShadowKey(page, i, j));
if (shadowColor === CommonConstants.INVALID_VALUE.toString()) {
return false;
} else {
textShadowList.push(shadowColor);
}
}
}
return true;
}
* 预加载文字阴影缓存
*
* @param info AppItemTextShadowInfo
* @param gridItemWidth gridItemWidth
* @param gridItemHeight gridItemHeight
* @returns
*/
private async traversalToCacheTextShadow(index: number, isSinglePage: boolean, isLeftPage: boolean,
desktopStyleConfig: DesktopStyleConfig): Promise<void> {
let info: AppItemTextShadowInfo | null =
await this.getTextShadowInfo(index, isSinglePage, isLeftPage, desktopStyleConfig);
if (!info) {
return;
}
let startOffsetX: number = info.startOffsetX;
let startOffsetY: number = info.startOffsetY;
let maxRow: number = info.maxRow;
let maxCol: number = info.maxCol * StyleConstants.DEFAULT_2 - 1;
let snap: image.PixelMap = await this.getWallPaperSnap();
for (let i = 0; i < maxRow; i++) {
for (let j = 0; j < maxCol; j++) {
let shadowKey: string = this.generateShadowKey(info.textShadowScreenType ?? 0, i, j);
if (ComponentPosShadowCache.getInstance().getCache(shadowKey) !== CommonConstants.INVALID_VALUE.toString()) {
log.showInfo('the test shadow of key %{public}s is exit', shadowKey);
continue;
}
info.startOffsetX = startOffsetX + j * (desktopStyleConfig.gridItemWidth / StyleConstants.DEFAULT_2);
info.startOffsetY = startOffsetY + i * desktopStyleConfig.gridItemHeight;
if (snap) {
await this.generateShadow(info, shadowKey, snap);
}
}
}
this.storeTextShadowPreference(info.isLeftPage ?? true, info.isSinglePage ?? true);
}
public generateShadowKey(pageIndex: number, rowTrans: number, columnTrans: number): string {
return `${pageIndex}_${rowTrans}_${columnTrans}`;
}
public getTextShadowScreenType(isSinglePage: boolean, isLeftPage: boolean): number {
return isSinglePage ? TextShadowScreenType.SINGLE_PAGE :
(isLeftPage ? TextShadowScreenType.DOUBLE_LEFT_PAGE : TextShadowScreenType.DOUBLE_RIGHT_PAGE);
}
public async startToCacheShadow(folderStatus: number, mainPageIndex: number, desktopStyleConfig: DesktopStyleConfig): Promise<void> {
if (folderStatus === DeviceState.EXPAND_STATE) {
let subpageIndex = mainPageIndex % 2 === 0 ? mainPageIndex + 1 : mainPageIndex - 1;
await this.traversalToCacheTextShadow(mainPageIndex, false, (mainPageIndex % 2 === 0), desktopStyleConfig);
await this.traversalToCacheTextShadow(subpageIndex, false, (subpageIndex % 2 === 0), desktopStyleConfig);
} else {
await this.traversalToCacheTextShadow(mainPageIndex, true, true, desktopStyleConfig);
}
}
private async getTextShadowInfo(index: number, isSinglePage: boolean, isLeftPage: boolean,
desktopStyleConfig: DesktopStyleConfig): Promise<AppItemTextShadowInfo | null> {
let offsetOfScreen: componentUtils.Offset = ItemUtils.getOffsetRelativeScreenById(CommonConstants
.SWIPER_GRID_WORKSPACE_TAG + index);
if (CheckEmptyUtils.isEmpty(offsetOfScreen)) {
log.showWarn('generate the TextShadow error for page %{public}d', index);
return null;
}
let offsetX: number = px2vp(offsetOfScreen.x);
let offsetY: number = px2vp(offsetOfScreen.y) + desktopStyleConfig.iconSize + desktopStyleConfig.itemPadding +
desktopStyleConfig.iconNameMarginTop;
let textShadowScreenType: number = textShadowMgr.getTextShadowScreenType(isSinglePage, isLeftPage);
let info : AppItemTextShadowInfo = {
startOffsetX: offsetX,
startOffsetY: offsetY,
maxRow: desktopStyleConfig.row,
maxCol: desktopStyleConfig.col,
nameWidth: desktopStyleConfig.nameWidth,
nameHeight: desktopStyleConfig.nameHeight,
screenWidth: 0,
screenHeight: 0,
textShadowScreenType: textShadowScreenType,
isSinglePage: isSinglePage,
isLeftPage: isLeftPage
};
await this.completeAppTextShadowInfo(info, isSinglePage);
return info;
}
private async completeAppTextShadowInfo(info: AppItemTextShadowInfo, isSinglePage: boolean): Promise<void> {
let screenInfo: display.Display | undefined = undefined;
try {
screenInfo = display.getDefaultDisplaySync();
} catch (error) {
log.showError('get screenInfo with error %{public}s', error.message);
}
if (!screenInfo) {
log.showError('completeAppTextShadowInfo screenInfo is undefined');
return;
}
const screenWidth: number = px2vp(screenInfo.width);
const screenHeight: number = px2vp(screenInfo.height);
info.screenWidth = screenWidth;
info.screenHeight = screenHeight;
if (!DeviceHelper.isFold()) {
return;
}
let image: image.PixelMap | null = null;
try {
image = await this.getWallPaperSnap();
let imageInfo = image.getImageInfoSync();
let imageWidth: number = px2vp(imageInfo.size.width);
let imageHeight: number = px2vp(imageInfo.size.height);
if (imageWidth === 0) {
log.showError('getWallPaperSnap error with imageWidth zero');
return;
}
if (isSinglePage) {
info.startOffsetX += (imageWidth - screenWidth) / DIVIDE_TWO;
info.screenWidth = imageWidth;
} else {
let ratio: number = screenWidth / imageWidth;
imageHeight = imageHeight * ratio;
info.screenHeight = imageHeight;
info.nameHeight = info.nameHeight * ratio;
info.startOffsetY += (imageHeight - screenHeight) / DIVIDE_TWO;
}
} catch (err) {
log.showError('completeAppTextShadowInfo error with %{public}s', err.message);
}
}
public async startToParseShadow(folderStatus: number, mainPageIndex: number): Promise<boolean> {
if (folderStatus === DeviceState.EXPAND_STATE) {
let subpageIndex = mainPageIndex % 2 === 0 ? mainPageIndex + 1 : mainPageIndex - 1;
let loadMainPage: boolean = await this.parseTextShadowPreference((mainPageIndex % 2 === 0), false);
let loadSubPage: boolean = await this.parseTextShadowPreference((subpageIndex % 2 === 0), false);
return loadMainPage && loadSubPage;
} else {
return await this.parseTextShadowPreference(true, true);
}
}
}
export interface DesktopStyleConfig {
iconSize: number,
itemPadding: number,
iconNameMarginTop: number,
row: number,
col: number,
nameWidth: number,
nameHeight: number,
gridItemWidth: number,
gridItemHeight: number
}
* 文字阴影信息
*/
export interface AppItemTextShadowInfo {
startOffsetX: number,
startOffsetY: number,
maxRow: number,
maxCol: number,
nameWidth: number,
nameHeight: number,
screenWidth: number,
screenHeight: number,
textShadowScreenType?: number,
isSinglePage?: boolean,
isLeftPage?: boolean
}
enum TextShadowScreenType {
SINGLE_PAGE = 0,
DOUBLE_LEFT_PAGE = 1,
DOUBLE_RIGHT_PAGE = 2,
}
export let textShadowMgr: TextShadowManager = SingletonHelper.getInstance(TextShadowManager, TAG);