!93 Launcher 3.1_release features update

Merge pull request !93 from 周靖/master
This commit is contained in:
openharmony_ci 2022-03-10 03:55:10 +00:00 committed by Gitee
commit b30d7d9dd6
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
73 changed files with 3766 additions and 907 deletions

18
feature/form/build.gradle Normal file
View File

@ -0,0 +1,18 @@
apply plugin: 'com.huawei.ohos.library'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 8
defaultConfig {
compatibleSdkVersion 8
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
}

View File

@ -0,0 +1,22 @@
{
"app": {
"bundleName": "com.ohos.launcher",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.ohos.launcher",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "form",
"moduleType": "har"
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 FormLayoutConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/FormLayoutConfig';
import Log from '../../../../../../../common/src/main/ets/default/utils/Log';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import FeatureConstants from './constants/FeatureConstants';
const TAG = 'FormDetailLayoutConfig';
/**
* Folder information data model
*/
export default class FormDetailLayoutConfig extends FormLayoutConfig{
private constructor() {
super();
}
/**
* Get form detail layout info object
*
* @return Single instance of form data model
*/
static getInstance(): FormDetailLayoutConfig {
if (globalThis.FormDetailLayoutConfigInstance == null) {
globalThis.FormDetailLayoutConfigInstance = new FormDetailLayoutConfig();
globalThis.FormDetailLayoutConfigInstance.initConfig();
}
return globalThis.FormDetailLayoutConfigInstance;
}
initConfig() {
}
getConfigLevel(): string {
return CommonConstants.LAYOUT_CONFIG_LEVEL_FEATURE;
}
getFeatureName() {
return FeatureConstants.FEATURE_NAME;
}
}

View File

@ -13,25 +13,27 @@
* limitations under the License.
*/
import BaseModulePreLoader from '../../../../../../../common/src/main/ets/default/base/BaseModulePreLoader.ets';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager.ets';
import RecentModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/RecentModeConfig.ets';
import BaseModulePreLoader from '../../../../../../../common/src/main/ets/default/base/BaseModulePreLoader';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import FormStyleConfig from './FormStyleConfig';
import FormLayoutConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/FormLayoutConfig';
/**
*
* Form layer initialization loader
*/
class RecentsPreLoader extends BaseModulePreLoader {
class FormPreLoader extends BaseModulePreLoader {
protected loadConfig(): void {
LayoutConfigManager.addConfigToManager(RecentModeConfig.getInstance());
LayoutConfigManager.addConfigToManager(FormLayoutConfig.getInstance());
LayoutConfigManager.addConfigToManager(FormStyleConfig.getInstance());
}
protected loadData(): void {
}
public releaseConfigAndData(): void {
releaseConfigAndData(): void {
LayoutConfigManager.removeConfigFromManager();
}
}
let recentsPreLoader = new RecentsPreLoader();
export default recentsPreLoader;
const formPreLoader = new FormPreLoader();
export default formPreLoader;

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2021 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 AppListStyleConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/AppListStyleConfig';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import FeatureConstants from './constants/FeatureConstants';
/**
* Form style config
*/
export default class FormStyleConfig extends AppListStyleConfig {
mFormWidth: Map<string,number> = new Map<string,number>();
mFormHeight: Map<string,number> = new Map<string,number>();
/**
* Form name size
*/
mFormNameSize = 20;
/**
* Form name height
*/
mFolderNameHeight = 25;
/**
* Form dimension width 1 * 2
*/
mDimensionWidth_1_2 = 54;
/**
* Form dimension height 1 * 2
*/
mDimensionHeight_1_2 = 128;
/**
* Form dimension width 2 * 2
*/
mDimensionWidth_2_2 = 128;
/**
* Form dimension height 2 * 2
*/
mDimensionHeight_2_2 = 128;
/**
* Form dimension width 2 * 4
*/
mDimensionWidth_2_4 = 128;
/**
* Form dimension height 2 * 4
*/
mDimensionHeight_2_4 = 202;
/**
* Form dimension width 4 * 4
*/
mDimensionWidth_4_4 = 202;
/**
* Form dimension height 4 * 4
*/
mDimensionHeight_4_4 = 202;
/**
* Form list blur
*/
mBackdropBlur = 20;
protected constructor() {
super();
}
/**
* get form style config instance
*/
static getInstance() {
if (globalThis.FormStyleConfigInstance == null) {
globalThis.FormStyleConfigInstance = new FormStyleConfig();
}
return globalThis.FormStyleConfigInstance;
}
initConfig(): void {
}
getConfigLevel(): string {
return CommonConstants.LAYOUT_CONFIG_LEVEL_FEATURE;
}
getFeatureName() {
return FeatureConstants.FEATURE_NAME;
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2021 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.
*/
export default class FeatureConstants {
static readonly FEATURE_NAME = 'featureForm';
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 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.
*/
export default class StyleConstants {
//image resources
static readonly DEFAULT_FORM_MGR_BACKGROUND_IMAGE = '/common/pics/ic_wallpaper_form_manager.jpg';
static readonly DEFAULT_FORM_MGR_BACK_IMAGE = '/common/pics/ic_form_mgr_back.jpg';
// style
static readonly DEFAULT_FORM_MARGIN = 10;
static readonly FORM_MANAGER_VIEW_CARD_WIDTH = 300;
static readonly FORM_MANAGER_VIEW_CARD_HEIGHT = 300;
static readonly FORM_MANAGER_VIEW_WIDTH = 402;
static readonly FORM_MANAGER_VIEW_HEIGHT = 528;
static readonly FORM_MANAGER_VIEW_FORM_NAME_HEIGHT = 28;
static readonly FORM_MANAGER_VIEW_FORM_SUB_NAME_HEIGHT = 22;
// font resources
static readonly DEFAULT_FORM_MGR_TEXT_FONT_SIZE = 20;
static readonly DEFAULT_FORM_MGR_FONT_COLOR = '#ffffff';
static readonly DEFAULT_FORM_DIALOG_BUTTON_COLOR = '#007dff';
// layout percentage adaptation resources
static readonly DEFAULT_LAYOUT_PERCENTAGE = '100%';
static readonly FORM_MGR_BOTTOM_WIDTH_PERCENTAGE = '80%';
static readonly FORM_MGR_BOTTOM_HEIGHT_PERCENTAGE = '10%';
static readonly FORM_MGR_SWIPER_WIDTH_PERCENTAGE = '80%';
static readonly FORM_MGR_SWIPER_HEIGHT_PERCENTAGE = '50%';
static readonly FORM_MGR_TEXT_HEIGHT_PERCENTAGE = '20%';
static readonly FORM_MGR_TOP_HEIGHT_PERCENTAGE = '10%';
}

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) 2021 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 CommonConstants from '../../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import ResourceManager from '../../../../../../../../common/src/main/ets/default/manager/ResourceManager';
import CommonStyleConstants from '../../../../../../../../common/src/main/ets/default/constants/StyleConstants';
import StyleConstants from '../constants/StyleConstants';
import Log from '../../../../../../../../common/src/main/ets/default/utils/Log';
import FormModel from '../../../../../../../../common/src/main/ets/default/model/FormModel';
const TAG = 'FormManagerDialog';
@CustomDialog
export default struct FormManagerDialog {
@StorageLink('formMgrItem') mFormItem: any = [];
@State allowUpdate: boolean = false;
private mSwiperController: SwiperController = new SwiperController()
private mFormModel: FormModel;
private mSwiperIndex: number = 0;
private mFormIdList: number[] = [];
private mFormComponentWidth: number[] =
[StyleConstants.FORM_MANAGER_VIEW_CARD_WIDTH / 2,
StyleConstants.FORM_MANAGER_VIEW_CARD_WIDTH / 2,
StyleConstants.FORM_MANAGER_VIEW_CARD_WIDTH,
StyleConstants.FORM_MANAGER_VIEW_CARD_WIDTH];
private mFormComponentHeight: number[] =
[StyleConstants.FORM_MANAGER_VIEW_CARD_HEIGHT / 4,
StyleConstants.FORM_MANAGER_VIEW_CARD_HEIGHT / 2,
StyleConstants.FORM_MANAGER_VIEW_CARD_HEIGHT / 2,
StyleConstants.FORM_MANAGER_VIEW_CARD_HEIGHT];
mFormDialogController: CustomDialogController;
cancel: () => void;
confirm: (formCardItem) => void;
bundleName: string;
appName: string;
appLabelId: string;
private aboutToAppear(): void {
this.mFormModel = FormModel.getInstance();
this.getCurrentFormInfo();
}
private async getCurrentFormInfo() {
this.mFormModel.getFormsInfoByBundleName(this.bundleName);
}
private getChooseCard() {
let formCardItem: any = {};
formCardItem.id = this.mFormIdList[this.mSwiperIndex];
let count = 0;
let isStop = false;
for (let i = 0; i < this.mFormItem.length; i++) {
if (isStop) break;
for (let j = 0; j < this.mFormItem[i].supportDimensions.length; j++) {
if (count == this.mSwiperIndex) {
formCardItem.name = this.mFormItem[i].cardName;
formCardItem.bundleName = this.mFormItem[i].bundleName;
formCardItem.abilityName = this.mFormItem[i].abilityName;
formCardItem.moduleName = this.mFormItem[i].moduleName;
formCardItem.dimension = this.mFormItem[i].supportDimensions[j];
formCardItem.formConfigAbility = this.mFormItem[i].formConfigAbility;
formCardItem.appLabelId = this.appLabelId;
isStop = true;
break;
}
count++;
}
}
for (let i = 0; i < this.mFormIdList.length; i++) {
if (count != i) {
this.mFormModel.deleteFormByFormID(this.mFormIdList[i]);
}
}
return formCardItem;
}
private deleteAllFormById() {
for (let i = 0; i < this.mFormIdList.length; i++) {
this.mFormModel.deleteFormByFormID(this.mFormIdList[i]);
}
}
build() {
Column() {
Text(this.appName)
.width('70%')
.fontSize(StyleConstants.DEFAULT_FORM_MGR_TEXT_FONT_SIZE)
.margin({ top: StyleConstants.DEFAULT_FORM_MARGIN, bottom: StyleConstants.DEFAULT_FORM_MARGIN })
.textAlign(TextAlign.Center)
Column({ space: 5 }) {
Swiper(this.mSwiperController) {
ForEach(this.mFormItem, (formItem) => {
ForEach(formItem.supportDimensions, (dimensionItem) => {
Column() {
Text(formItem.description)
.width('70%')
.fontSize(StyleConstants.DEFAULT_FORM_MGR_TEXT_FONT_SIZE)
.margin({ top: StyleConstants.DEFAULT_FORM_MARGIN, bottom: StyleConstants.DEFAULT_FORM_MARGIN })
.textAlign(TextAlign.Center)
Column() {
Flex({
direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
FormComponent({
id: formItem.cardId,
name: formItem.cardName,
bundle: formItem.bundleName,
ability: formItem.abilityName,
module: formItem.moduleName,
dimension: dimensionItem,
})
.clip(new Rect({
width: this.mFormComponentWidth[dimensionItem - 1],
height: this.mFormComponentHeight[dimensionItem - 1],
radius: 24
}))
.size({
width: this.mFormComponentWidth[dimensionItem - 1],
height: this.mFormComponentHeight[dimensionItem - 1]
})
.allowUpdate(this.allowUpdate)
.visibility(Visibility.Visible)
.onAcquired((form) => {
console.info(`FormComponent card id is: ${form.id}`);
this.mFormIdList.push(form.id);
})
.onError((error) => {
console.info(`FormComponent error msg: ${error.msg}`);
})
}
}
.height('70%')
}
}, (dimensionItem) => JSON.stringify(dimensionItem))
}, (formItem) => JSON.stringify(formItem))
}
.height('100%')
.loop(false)
.index(0)
.onChange((index: number) => {
this.mSwiperIndex = index;
})
}
.height('85%')
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button() {
Text($r('app.string.cancel'))
.fontSize(CommonStyleConstants.DEFAULT_BADGE_FONT_SIZE)
.fontColor(CommonStyleConstants.BUTTON_FONT_COLOR)
}
.backgroundColor(CommonStyleConstants.DEFAULT_BG_COLOR)
.height(CommonStyleConstants.DEFAULT_BUTTON_HEIGHT)
.onClick(() => {
this.mFormDialogController.close();
this.cancel();
})
Divider()
.vertical(true)
.color(CommonStyleConstants.DEFAULT_DIVIDER_COLOR)
.height(CommonStyleConstants.DEFAULT_BUTTON_HEIGHT)
Button() {
Text($r('app.string.add_to_desktop'))
.fontSize(CommonStyleConstants.DEFAULT_BADGE_FONT_SIZE)
.fontColor(CommonStyleConstants.BUTTON_FONT_COLOR)
}
.backgroundColor(CommonStyleConstants.DEFAULT_BG_COLOR)
.height(CommonStyleConstants.DEFAULT_BUTTON_HEIGHT)
.onClick(() => {
this.mFormDialogController.close();
this.confirm(this.getChooseCard());
})
}
}
.backgroundColor(Color.White)
.padding({
bottom: CommonStyleConstants.DEFAULT_DIALOG_BOTTOM_MARGIN
})
.border({
radius: CommonStyleConstants.DEFAULT_DIALOG_RADIUS
})
.width(StyleConstants.FORM_MANAGER_VIEW_WIDTH)
.height(StyleConstants.FORM_MANAGER_VIEW_HEIGHT)
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2021 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 StyleConstants from '../constants/StyleConstants';
import Log from '../../../../../../../../common/src/main/ets/default/utils/Log';
const TAG = 'FormMgrBottomComponent';
@Component
export default struct FormMgrBottomComponent {
private aboutToAppear(): void {
}
build() {
Column() {
}
.height(StyleConstants.FORM_MGR_BOTTOM_HEIGHT_PERCENTAGE)
.width(StyleConstants.FORM_MGR_BOTTOM_WIDTH_PERCENTAGE)
.onClick(() => {
})
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 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 StyleConstants from '../constants/StyleConstants';
import Log from '../../../../../../../../common/src/main/ets/default/utils/Log';
const TAG = 'FormMgrSwiperComponent';
@Component
export default struct FormMgrSwiperComponent {
@State formItemInfo: any = {};
private Number: String[] = ['1', '2', '3', '4'];
private aboutToAppear(): void {
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Swiper() {
ForEach(this.Number, (day: string) => {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('20%')
.height('60%')
.textAlign(TextAlign.Center)
}, day => day)
}
.height(StyleConstants.FORM_MGR_SWIPER_HEIGHT_PERCENTAGE)
.width(StyleConstants.FORM_MGR_SWIPER_WIDTH_PERCENTAGE)
.loop(false)
.index(0)
.onChange((index) => {
})
}
.height(StyleConstants.FORM_MGR_SWIPER_HEIGHT_PERCENTAGE)
.width(StyleConstants.FORM_MGR_SWIPER_WIDTH_PERCENTAGE)
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2021 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 StyleConstants from '../constants/StyleConstants';
import Log from '../../../../../../../../common/src/main/ets/default/utils/Log';
const TAG = 'FormMgrTitleComponent';
@Component
export default struct FormMgrTitleComponent {
@Link mFormMgrTitleComponent: any;
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.mFormMgrTitleComponent)
.fontColor(StyleConstants.DEFAULT_FORM_MGR_FONT_COLOR)
.fontSize(StyleConstants.DEFAULT_FORM_MGR_TEXT_FONT_SIZE)
}
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.FORM_MGR_TEXT_HEIGHT_PERCENTAGE)
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 FormMgrBottomComponent from '../common/uicomponents/FormMgrBottomComponent.ets';
import FormMgrTitleComponent from '../common/uicomponents/FormMgrTitleComponent.ets';
import FormMgrSwiperComponent from '../common/uicomponents/FormMgrSwiperComponent.ets';
import StyleConstants from '../common/constants/StyleConstants';
import Log from '../../../../../../../common/src/main/ets/default/utils/Log';
const TAG = 'FormManagerComponent';
@Component
export default struct FormManagerComponent {
@State formInfo: any;
@State isClickedForm: boolean = false;
private aboutToAppear(): void {
}
build() {
Column() {
Column() {
Image(StyleConstants.DEFAULT_FORM_MGR_BACK_IMAGE)
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.FORM_MGR_TOP_HEIGHT_PERCENTAGE)
.align(Alignment.Bottom)
}.alignItems(HorizontalAlign.Center)
.height(StyleConstants.FORM_MGR_TOP_HEIGHT_PERCENTAGE)
.onClick(() => {
// back view
})
FormMgrTitleComponent({mFormMgrTitleComponent: $appInfo.formName});
FormMgrSwiperComponent({formItemInfo: this.formItemInfo});
FormMgrBottomComponent();
}
.height(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.backgroundImage(StyleConstants.DEFAULT_FORM_MGR_BACKGROUND_IMAGE)
.onClick(() => {
})
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2021 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 router from '@system.router';
import Log from '../../../../../../../common/src/main/ets/default/utils/Log';
import FormModel from '../../../../../../../common/src/main/ets/default/model/FormModel';
import EventConstants from '../../../../../../../common/src/main/ets/default/constants/EventConstants';
import PageDesktopViewModel from '../../../../../../pagedesktop/src/main/ets/default/common/viewmodel/PageDesktopViewModel';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import FormStyleConfig from '../common/FormStyleConfig';
import FeatureConstants from '../common/constants/FeatureConstants';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import FormListInfoCacheManager from '../../../../../../../common/src/main/ets/default/cache/FormListInfoCacheManager';
const TAG = 'FormViewModel';
const KEY_FORM_LIST = 'formListInfo';
/**
* Class FormViewModel.
*/
export default class FormViewModel {
private readonly mPageDesktopViewModel: PageDesktopViewModel;
private readonly mFormModel: FormModel;
private readonly mFormStyleConfig: FormStyleConfig;
private readonly mFormListInfoCacheManager: FormListInfoCacheManager;
private mAllFormsInfo;
private constructor() {
Log.showInfo(TAG, 'constructor start');
this.mFormModel = FormModel.getInstance();
this.mFormStyleConfig = LayoutConfigManager.getStyleConfig(FormStyleConfig.APP_LIST_STYLE_CONFIG,
FeatureConstants.FEATURE_NAME);
this.mPageDesktopViewModel = PageDesktopViewModel.getInstance();
this.mFormListInfoCacheManager = FormListInfoCacheManager.getInstance();
}
/**
* Return an instance of FormViewModel.
*/
static getInstance() {
if (globalThis.FormViewModelInstance == null) {
globalThis.FormViewModelInstance = new FormViewModel();
}
return globalThis.FormViewModelInstance;
}
getFormStyleConfig(): FormStyleConfig {
return this.mFormStyleConfig;
}
private readonly mLocalEventListener = {
onReceiveEvent: (event, params) => {
Log.showInfo(TAG, `Launcher FormViewModel receive event: ${event}, params: ${JSON.stringify(params)}`);
if (event === EventConstants.EVENT_REQUEST_JUMP_TO_FORM_VIEW) {
this.jumpToFormManagerView(params);
}
}
};
/**
* jump to form view
*/
async jumpToFormManagerView(params) {
Log.showInfo(TAG, `Launcher FormViewModel jumpToFormManagerView params: ${JSON.stringify(params)}`);
const options = {
uri: 'pages/FormManagerView',
params: params
};
try {
await router.push(options);
} catch (err) {
Log.showInfo(TAG, `fail callback, code: ${err.code}, msg: ${err.msg}`);
}
}
/**
* Judge whether the current application supports form
*
* @param {any} appInfo
*/
async isSupportForm(appInfo) {
const formInfoList = await this.mFormModel.getAllFormsInfo();
const formInfo: any = formInfoList.find(item => {
if (item.bundleName == appInfo.bundleName) {
return true;
}
});
let isSupportForm = false;
if (formInfo.length > 0) {
isSupportForm = true;
}
return isSupportForm;
}
/**
* Obtains the FormInfo objects provided by all ohos applications on the device.
*/
async getForms() {
console.info('Launcher FormViewModel getForms');
this.mAllFormsInfo = await this.mFormModel.getAllFormsInfo();
AppStorage.SetOrCreate('allFormsInfo', this.mAllFormsInfo);
}
/**
* Delete form
*
* @param {number} cardId.
*/
async deleteForm(cardId) {
Log.showInfo(TAG, 'deleteForm start');
let gridLayoutInfo = {
layoutInfo: []
};
gridLayoutInfo = this.mPageDesktopViewModel.getLayoutInfo();
const cardIndex = gridLayoutInfo.layoutInfo.findIndex(item => {
return item.type === CommonConstants.TYPE_CARD && item.cardId === cardId;
});
if (cardIndex != CommonConstants.INVALID_VALUE) {
this.mFormModel.deleteFormById(cardId);
gridLayoutInfo.layoutInfo.splice(cardIndex, 1);
this.mPageDesktopViewModel.setLayoutInfo(gridLayoutInfo);
}
const formInfoList: any = this.mFormListInfoCacheManager.getCache(KEY_FORM_LIST);
if (formInfoList == CommonConstants.INVALID_VALUE) {
return;
}
for(let i = 0; i < formInfoList.length; i++) {
if (formInfoList[i].cardId == cardId){
formInfoList.splice(i, 1);
break;
}
}
if (formInfoList.length == 0) {
this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, null);
} else {
this.mFormListInfoCacheManager.setCache(KEY_FORM_LIST, formInfoList);
}
}
}

View File

@ -1,9 +1,9 @@
apply plugin: 'com.huawei.ohos.hap'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 7
compileSdkVersion 8
defaultConfig {
compatibleSdkVersion 4
compatibleSdkVersion 8
}
buildTypes {
release {

View File

@ -9,53 +9,14 @@
},
"deviceConfig": {},
"module": {
"package": "com.ohos.launcher.recents",
"name": ".MyApplication",
"mainAbility": "com.ohos.launcher.recents.MainAbility",
"package": "com.ohos.launcher",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "recents",
"moduleType": "feature",
"installationFree": true
},
"abilities": [
{
"visible": true,
"name": "com.ohos.launcher.recents.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:recents_MainAbility",
"type": "page",
"launchType": "singleton",
"srcPath": "default",
"srcLanguage": "ets",
"metaData": {
"customizeData": [
{
"name": "hwc-theme"
}
]
}
}
],
"js": [
{
"mode": {
"syntax": "ets",
"type": "pageAbility"
},
"pages": [
"pages/recents"
],
"name": "default",
"window": {
"designWidth": 720,
"autoDesignWidth": false
}
}
]
"moduleType": "har"
}
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 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 BaseModulePreLoader from '../../../../../../../common/src/main/ets/default/base/BaseModulePreLoader';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import RecentModeFeatureConfig from './layoutconfig/RecentModeFeatureConfig';
import RecentModePadConfig from './layoutconfig/RecentModePadConfig.ets';
import PageDesktopModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/PageDesktopModeConfig';
import SettingsModel from '../../../../../../../common/src/main/ets/default/model/SettingsModel';
/**
* Common layer initialization loader
*/
class RecentMissionsPreLoader extends BaseModulePreLoader {
private mSettingsModel: SettingsModel = null;
protected loadConfig(): void {
LayoutConfigManager.addConfigToManager(PageDesktopModeConfig.getInstance());
this.mSettingsModel = SettingsModel.getInstance();
if (this.mSettingsModel.getDevice() === 'phone') {
LayoutConfigManager.addConfigToManager(RecentModeFeatureConfig.getInstance());
} else {
LayoutConfigManager.addConfigToManager(RecentModePadConfig.getInstance());
}
}
protected loadData(): void {
}
releaseConfigAndData(): void {
LayoutConfigManager.removeConfigFromManager();
}
}
const recentMissionsPreLoader = new RecentMissionsPreLoader();
export default recentMissionsPreLoader;

View File

@ -12,25 +12,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import BaseStage from '../../../../../../../common/src/main/ets/default/base/BaseStage.ets';
import recentsPreLoader from './RecentsPreLoader.ets';
import BaseStage from '../../../../../../../common/src/main/ets/default/base/BaseStage';
import recentMissionsPreLoader from './RecentMissionsPreLoader';
/**
* Stage
* Recent missions feature stage
*/
export default class RecentsStage extends BaseStage {
export default class RecentMissionsStage extends BaseStage {
/**
* Stage启动时的回调
* The callback of stage start
*/
public onCreate(): void {
recentsPreLoader.load();
onCreate(): void {
recentMissionsPreLoader.load();
}
/**
* Stage退出时的回调
* The callback of stage exit
*/
public onDestroy(): void {
recentsPreLoader.releaseConfigAndData();
onDestroy(): void {
recentMissionsPreLoader.releaseConfigAndData();
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2021 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.
*/
const PadRecentsModeInfo = {
PadRecentMissionsRowConfig: 'double',
};
export default PadRecentsModeInfo;

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2021 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.
*/
export default class StyleConstants {
// image resources
static readonly DEFAULT_APP_ICON_IMAGE: any = $r('app.media.icon');
static readonly DEFAULT_APP_IMAGE: any = $r('app.media.img_app_default');
static readonly DEFAULT_DELETE_IMAGE: any = '/common/pics/ic_public_delete.svg';
static readonly DEFAULT_RECENT_BACKGROUND_IMAGE = '/common/pics/ic_wallpaper_recent.jpg';
static readonly DEFAULT_LOCKED_IMAGE: any = '/common/pics/ic_public_lock.svg';
// font style resources
static readonly DEFAULT_FONT_COLOR = '#ffffff';
static readonly DEFAULT_FONT_SIZE = 20;
static readonly DEFAULT_APP_NAME_SIZE = 16;
static readonly SINGLE_LIST_DEFAULT_APP_ICON_SIZE = 28;
static readonly DOUBLE_LIST_DEFAULT_APP_ICON_SIZE = 28;
// layout percentage adaptation resources
static readonly DEFAULT_LAYOUT_PERCENTAGE = '100%';
static readonly RECENT_MISSION_CARD_IMAGE_HEIGHT_PERCENTAGE = '70%';
static readonly RECENT_MISSION_CARD_MISSION_HEIGHT_PERCENTAGE = '75%';
static readonly SINGLE_LIST_DELETE_HEIGHT_PERCENTAGE = '15%';
static readonly SINGLE_LIST_SCROLL_HEIGHT_PERCENTAGE = '85%';
static readonly DOUBLE_LIST_GRID_HEIGHT_PERCENTAGE = '80%';
static readonly DOUBLE_LIST_DELETE_HEIGHT_PERCENTAGE = '10%';
// layout size
static readonly SINGLE_LIST_TOP_AERA_HEIGHT: number = 107;
static readonly SINGLE_LIST_MIDDLE_AERA_HEIGHT: number = 497;
static readonly SINGLE_LIST_BOTTOM_AERA_HEIGHT: number = 176;
// image size resources
static readonly SINGLE_LIST_APP_IMAGE_WIDTH = 216;
static readonly SINGLE_LIST_APP_IMAGE_HEIGHT = 458;
static readonly SINGLE_LIST_MISSION_HEIGHT: number = 497;
static readonly DOUBLE_LIST_APP_IMAGE_WIDTH = 282;
static readonly DOUBLE_LIST_APP_IMAGE_HEIGHT = 176;
static readonly DOUBLE_LIST_MISSION_HEIGHT = 214;
// style resources
static readonly APP_NAME_MARGIN = 5;
static readonly DEFAULT_DELETE_IMAGE_OPACITY = 0.5;
static readonly RECENT_IMAGE_RADIUS = 20;
static readonly RECENT_DELETE_IMAGE_RADIUS = 24;
static readonly RECENT_DELETE_IMAGE_SIZE = 24;
static readonly RECENT_DELETE_IMAGE_COLUMN_SIZE = 40;
static readonly SINGLE_LIST_APP_INFO_LAYOUT_WEIGHT = 1;
static readonly SINGLE_LIST_LAYOUT_MARGIN = 10;
static readonly DOUBLE_LIST_APP_INFO_LAYOUT_WEIGHT = 2;
static readonly DOUBLE_LIST_LAYOUT_MARGIN = 20;
static readonly DOUBLE_LIST_RIGHT_MARGIN = 72;
static readonly DOUBLE_LIST_TOP_MARGIN = 24;
static readonly DOUBLE_LIST_BOTTOM_MARGIN = 24;
// the dpi of phone should be 480, but it is 320 currently.
// so all dimensions have to be multiplied by 1.5
static readonly DPI_RATIO = 1.5;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2021 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 CommonConstants from '../../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import RecentsModeConfig from '../../../../../../../../common/src/main/ets/default/layoutconfig/RecentsModeConfig';
/**
* Recent missions layout mode configuration
*/
export default class RecentModeFeatureConfig extends RecentsModeConfig {
protected constructor() {
super();
}
protected getPersistConfigJson(): string {
const persistConfig = JSON.parse(super.getPersistConfigJson());
return JSON.stringify(persistConfig);
}
/**
* Get the instance of recent missions layout mode configuration
*/
static getInstance() {
if (globalThis.RecentModeFeatureConfigInstance == null) {
globalThis.RecentModeFeatureConfigInstance = new RecentModeFeatureConfig();
globalThis.RecentModeFeatureConfigInstance.initConfig();
}
return globalThis.RecentModeFeatureConfigInstance;
}
initConfig(): void {
super.initConfig();
}
getConfigLevel(): string {
return CommonConstants.LAYOUT_CONFIG_LEVEL_FEATURE;
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 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 CommonConstants from '../../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import PadRecentsModeInfo from '../configs/PadRecentsModeInfo';
import RecentModeFeatureConfig from './RecentModeFeatureConfig';
/**
* Pad recents mode configuration
*/
export default class RecentModePadConfig extends RecentModeFeatureConfig {
protected constructor() {
super()
this.mRecentMissionsRowType = PadRecentsModeInfo.PadRecentMissionsRowConfig;
}
/**
* Get recent mode configuration instance
*/
public static getInstance() {
if (globalThis.RecentModePadConfigInstance == null) {
globalThis.RecentModePadConfigInstance = new RecentModePadConfig();
globalThis.RecentModePadConfigInstance.initConfig();
}
return globalThis.RecentModePadConfigInstance;
}
public getConfigLevel(): string {
return CommonConstants.LAYOUT_CONFIG_LEVEL_PRODUCT;
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Public/ic_public_delete_filled</title>
<defs>
<path d="M19.905,7 L18.7182288,19.0681369 C18.5545878,20.7318206 17.1555495,22 15.4838372,22 L15.4838372,22 L8.51616277,22 C6.84445049,22 5.44541221,20.7318206 5.28177119,19.0681369 L5.28177119,19.0681369 L4.094,7 L19.905,7 Z M10,11.75 C9.58578644,11.75 9.25,12.0857864 9.25,12.5 L9.25,12.5 L9.25,18.5 C9.25,18.9142136 9.58578644,19.25 10,19.25 C10.4142136,19.25 10.75,18.9142136 10.75,18.5 L10.75,18.5 L10.75,12.5 C10.75,12.0857864 10.4142136,11.75 10,11.75 Z M14,11.75 C13.5857864,11.75 13.25,12.0857864 13.25,12.5 L13.25,12.5 L13.25,18.5 C13.25,18.9142136 13.5857864,19.25 14,19.25 C14.4142136,19.25 14.75,18.9142136 14.75,18.5 L14.75,18.5 L14.75,12.5 C14.75,12.0857864 14.4142136,11.75 14,11.75 Z M12,1.75 C13.5727118,1.75 14.862769,2.9601879 14.9897427,4.50013463 L21.25,4.5 C21.6642136,4.5 22,4.83578644 22,5.25 C22,5.64942022 21.68777,5.97591522 21.2940682,5.99872683 L21.25,6 L2.75,6 C2.33578644,6 2,5.66421356 2,5.25 C2,4.85057978 2.31222999,4.52408478 2.7059318,4.50127317 L2.75,4.5 L9.01025734,4.50013463 C9.13723098,2.9601879 10.4272882,1.75 12,1.75 Z" id="path-1"></path>
</defs>
<g id="Public/ic_public_delete_filled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<mask id="mask-2" fill="none">
<use xlink:href="#path-1"></use>
</mask>
<use id="形状结合" fill="#ffffff" fill-rule="nonzero" xlink:href="#path-1"></use>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Public/ic_public_lock</title>
<defs>
<path d="M12,2 C14.3202308,2 16.206199,3.85929891 16.249248,6.16924008 L16.25,6.25 L16.25,9 L16.5,9 C18.1568542,9 19.5,10.3431458 19.5,12 L19.5,18.5 C19.5,20.1568542 18.1568542,21.5 16.5,21.5 L7.5,21.5 C5.84314575,21.5 4.5,20.1568542 4.5,18.5 L4.5,12 C4.5,10.3431458 5.84314575,9 7.5,9 L7.75,9 L7.75,6.25 C7.75,3.90278981 9.65278981,2 12,2 Z M16.5,10.5 L7.5,10.5 C6.69040076,10.5 6.03060706,11.1413937 6.00103462,11.9437654 L6,12 L6,18.5 C6,19.3095992 6.64139372,19.9693929 7.44376543,19.9989654 L7.5,20 L16.5,20 C17.3095992,20 17.9693929,19.3586063 17.9989654,18.5562346 L18,18.5 L18,12 C18,11.1904008 17.3586063,10.5306071 16.5562346,10.5010346 L16.5,10.5 Z M12,13.25 C13.1045695,13.25 14,14.1454305 14,15.25 C14,16.3545695 13.1045695,17.25 12,17.25 C10.8954305,17.25 10,16.3545695 10,15.25 C10,14.1454305 10.8954305,13.25 12,13.25 Z M12,3.5 C10.5053246,3.5 9.28915871,4.69244089 9.25092685,6.17789813 L9.25,9 L14.75,9 L14.75,6.25 C14.75,4.73121694 13.5187831,3.5 12,3.5 Z" id="path-1"></path>
</defs>
<g id="Public/ic_public_lock" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<mask id="mask-2" fill="none">
<use xlink:href="#path-1"></use>
</mask>
<use id="形状结合" fill="#ffffff" fill-rule="nonzero" xlink:href="#path-1"></use>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 ResourceManager from '../../../../../../../../common/src/main/ets/default/manager/ResourceManager';
import StyleConstants from '../constants/StyleConstants';
const TAG = 'Recent-RecentMissionAppIcon';
@Component
export default struct RecentMissionAppIcon {
@Prop iconSize: number;
@Prop @Watch("updateIcon") appIcon: string;
@Prop bundleName: string;
@Prop labelId: string;
@State icon: string = ' ';
@State useCache: boolean = true;
private mResourceManager;
private mDefaultAppIcon;
public aboutToAppear(): void {
this.mDefaultAppIcon = StyleConstants.DEFAULT_APP_ICON_IMAGE;
this.icon = this.mDefaultAppIcon;
this.mResourceManager = ResourceManager.getInstance();
this.updateIcon();
}
public iconLoadCallback(image) {
this.icon = image;
}
public updateIcon() {
this.mResourceManager.getAppIconWithCache(this.appIcon, this.bundleName, this.iconLoadCallback.bind(this), this.mDefaultAppIcon);
}
build() {
Column() {
Image(this.icon)
}
.width(this.iconSize)
.height(this.iconSize)
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 ResourceManager from '../../../../../../../../common/src/main/ets/default/manager/ResourceManager';
import StyleConstants from '../constants/StyleConstants';
const TAG = 'Recent-RecentMissionAppName';
@Component
export default struct RecentMissionAppName {
@Prop @Watch("updateName") appName: string;
@State nameSize: number = StyleConstants.DEFAULT_FONT_SIZE;
@State margin: number = StyleConstants.APP_NAME_MARGIN;
@State name: string = ''
@Prop bundleName: string;
@Prop labelId: string;
private mResourceManager;
public aboutToAppear(): void {
this.mResourceManager = ResourceManager.getInstance();
this.updateName();
}
public appNameLoadCallback(name: string) {
this.name = name;
}
public updateName() {
if (this.bundleName && this.bundleName.length > 0) {
this.mResourceManager.getAppNameWithCache(this.labelId, this.bundleName, this.appName, this.appNameLoadCallback.bind(this));
}
}
build() {
Column() {
Text(this.name)
.fontSize(this.nameSize)
.fontColor(StyleConstants.DEFAULT_FONT_COLOR)
.textOverflow({overflow: TextOverflow.Ellipsis})
.margin({ left: this.margin })
}
}
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../common/src/main/ets/default/utils/Log';
import CommonStyleConstants from '../../../../../../../../common/src/main/ets/default/constants/StyleConstants';
import StyleConstants from '../../common/constants/StyleConstants';
import RecentMissionAppIcon from './RecentMissionAppIcon.ets';
import RecentMissionAppName from './RecentMissionAppName.ets';
import RecentMissionsViewModel from '../../viewmodel/RecentMissionsViewModel';
import windowManager from '../../../../../../../../common/src/main/ets/default/manager/WindowManager';
const TAG = 'Recent-RecentMissionCard';
@Component
export default struct RecentMissionCard {
@Link mIsClickSubComponent: boolean;
@Prop missionId: number;
@Prop appIconId: string;
@Prop appLabelId: string;
@Prop appName: string;
@Prop bundleName: string;
@Prop abilityName: string;
@Prop lockedState: boolean;
@State margin: number = StyleConstants.SINGLE_LIST_LAYOUT_MARGIN;
@State layoutWeight: number = StyleConstants.SINGLE_LIST_APP_INFO_LAYOUT_WEIGHT;
@State mRecentImage: any = '';
private mDefaultSnapShot: string = '';
private mIsSingleLayout: boolean = true;
private mSnapshotList: any = [];
private mRecentMissionsViewModel: RecentMissionsViewModel;
public aboutToAppear(): void {
Log.showInfo(TAG, `aboutToAppear start`);
this.mRecentMissionsViewModel = RecentMissionsViewModel.getInstance();
this.mIsSingleLayout = this.mRecentMissionsViewModel.getRecentMissionsRowType() === 'single' ? true : false;
this.margin = this.mRecentMissionsViewModel.getRecentMissionsRowType() === 'single' ?
StyleConstants.SINGLE_LIST_LAYOUT_MARGIN * StyleConstants.DPI_RATIO : StyleConstants.DOUBLE_LIST_LAYOUT_MARGIN;
this.layoutWeight = this.mRecentMissionsViewModel.getRecentMissionsRowType() === 'single' ?
StyleConstants.SINGLE_LIST_APP_INFO_LAYOUT_WEIGHT : StyleConstants.DOUBLE_LIST_APP_INFO_LAYOUT_WEIGHT;
this.mDefaultSnapShot = StyleConstants.DEFAULT_APP_IMAGE;
this.mRecentImage = this.mDefaultSnapShot;
this.mRecentMissionsViewModel.getMissionSnapShot(this.missionId, this.recentMissionsSnapshotCallback.bind(this));
}
public recentMissionsSnapshotCallback(missionId: number, snapShot: any) {
console.info(`Launcher recentMissions ${missionId} ${this.missionId}`);
if (missionId === this.missionId) {
this.mRecentImage = snapShot.image;
let width = snapShot.width;
let height = snapShot.height;
console.info("Launcher recentMissions this.mRecentImage:" + JSON.stringify(this.mRecentImage));
console.info("Launcher recentMissions this.mRecentImage width:" + JSON.stringify(width));
console.info("Launcher recentMissions this.mRecentImage height:" + JSON.stringify(height));
}
}
build() {
Column() {
Row() {
Row() {
RecentMissionAppIcon({
iconSize: this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_DEFAULT_APP_ICON_SIZE * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_DEFAULT_APP_ICON_SIZE,
appIcon: this.appIconId,
bundleName: this.bundleName,
labelId: this.appLabelId,
useCache: false
})
RecentMissionAppName({
appName: this.appName,
nameSize: this.mIsSingleLayout ?
StyleConstants.DEFAULT_APP_NAME_SIZE * StyleConstants.DPI_RATIO :
StyleConstants.DEFAULT_APP_NAME_SIZE,
bundleName: this.bundleName,
labelId: this.appLabelId,
margin: this.margin / 2
})
}
.layoutWeight(this.layoutWeight)
.margin({ left: this.margin / 2 })
Column() {
Image(StyleConstants.DEFAULT_LOCKED_IMAGE)
.visibility(this.lockedState? Visibility.Visible: Visibility.Hidden)
.width((this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_DEFAULT_APP_ICON_SIZE * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_DEFAULT_APP_ICON_SIZE) - 10)
.height((this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_DEFAULT_APP_ICON_SIZE * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_DEFAULT_APP_ICON_SIZE) - 10)
.margin({ right: this.margin / 2 })
.onClick(() => {
this.mIsClickSubComponent = true;
Log.showInfo(TAG, `set recent mission Locked status`);
this.mRecentMissionsViewModel.setRecentMissionLock(this.missionId, !this.lockedState);
this.mIsClickSubComponent = false;
})
}
.layoutWeight(1)
}
.margin({ bottom: this.margin / 2 })
Image(this.mRecentImage)
.objectFit(ImageFit.Contain)
.borderRadius(StyleConstants.RECENT_IMAGE_RADIUS)
.width(this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_APP_IMAGE_WIDTH * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_APP_IMAGE_WIDTH)
.height(this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_APP_IMAGE_HEIGHT * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_APP_IMAGE_HEIGHT)
.onClick(() => {
this.mIsClickSubComponent = true;
Log.showInfo(TAG, `start launcher ability`);
windowManager.hideWindow(windowManager.RECENT_WINDOW_NAME);
this.mRecentMissionsViewModel.moveMissionToFront(this.missionId);
})
}
.width(this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_APP_IMAGE_WIDTH * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_APP_IMAGE_WIDTH)
.height(this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_MISSION_HEIGHT * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_MISSION_HEIGHT)
.margin({ right: this.margin })
.backgroundColor(CommonStyleConstants.DEFAULT_BG_COLOR)
.gesture(
PanGesture({ fingers: 1, direction: PanDirection.Vertical, distance: 5 })
.onActionEnd((e) => {
let mOffectWidth = (this.mIsSingleLayout ?
StyleConstants.SINGLE_LIST_APP_IMAGE_WIDTH * StyleConstants.DPI_RATIO :
StyleConstants.DOUBLE_LIST_APP_IMAGE_WIDTH) / 2;
if (e.offsetY < -50 && e.offsetX <= mOffectWidth && -mOffectWidth <= e.offsetX) {
this.mRecentMissionsViewModel.deleteRecentMission(false, this.missionId);
} else if (e.offsetY > 50 && e.offsetX <= mOffectWidth && -mOffectWidth <= e.offsetX) {
this.lockedState = this.lockedState? false : true;
this.mRecentMissionsViewModel.setRecentMissionLock(this.missionId, this.lockedState);
}
}))
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2021 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.
*/
const TAG = 'EmptyMsgDisplay';
import StyleConstants from '../common/constants/StyleConstants';
@Component
export default struct EmptyMsgDisplay {
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text($r('app.string.No_running_apps_recently'))
.fontColor(StyleConstants.DEFAULT_FONT_COLOR)
.fontSize(StyleConstants.DEFAULT_FONT_SIZE)
}
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../common/src/main/ets/default/utils/Log';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import StyleConstants from '../common/constants/StyleConstants';
import RecentMissionCard from '../common/uicomponents/RecentMissionCard.ets';
import RecentMissionsViewModel from '../viewmodel/RecentMissionsViewModel';
const TAG = 'RecentMissionsDoubleLayout';
@Component
export default struct RecentMissionsDoubleLayout {
@Link mRecentMissionsDoubleList: [];
@Link mIsClickSubComponent: boolean;
private mRecentMissionsViewModel: RecentMissionsViewModel;
private mScroll: Scroller = new Scroller();
private aboutToAppear(): void {
this.mRecentMissionsViewModel = RecentMissionsViewModel.getInstance();
}
build() {
Column() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Center }) {
Grid() {
ForEach(this.mRecentMissionsDoubleList, (item) => {
GridItem() {
RecentMissionCard({
missionId: item.missionId,
appIconId: item.appIconId,
appLabelId: item.appLabelId,
appName: item.appName,
bundleName: item.bundleName,
abilityName: item.abilityName,
lockedState: item.lockedState,
mIsClickSubComponent: $mIsClickSubComponent
})
}
.height(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.align(Alignment.Center)
},(item) => JSON.stringify(item))
}
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.rowsTemplate('1fr 1fr')
.columnsGap(StyleConstants.DOUBLE_LIST_LAYOUT_MARGIN)
.rowsGap(StyleConstants.DOUBLE_LIST_LAYOUT_MARGIN)
}
.margin({top: StyleConstants.DOUBLE_LIST_TOP_MARGIN})
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.DOUBLE_LIST_GRID_HEIGHT_PERCENTAGE)
Column() {
Image(StyleConstants.DEFAULT_DELETE_IMAGE)
.width(StyleConstants.RECENT_DELETE_IMAGE_SIZE)
.height(StyleConstants.RECENT_DELETE_IMAGE_SIZE)
}
.width(StyleConstants.RECENT_DELETE_IMAGE_COLUMN_SIZE)
.height(StyleConstants.RECENT_DELETE_IMAGE_COLUMN_SIZE)
.opacity(StyleConstants.DEFAULT_DELETE_IMAGE_OPACITY)
.backgroundColor(StyleConstants.DEFAULT_FONT_COLOR)
.borderRadius(StyleConstants.RECENT_DELETE_IMAGE_RADIUS)
.padding(8)
.margin({top: StyleConstants.DOUBLE_LIST_BOTTOM_MARGIN})
.onClick(() => {
this.mIsClickSubComponent = true;
Log.showInfo(TAG, `click delete button`);
this.mRecentMissionsViewModel.deleteRecentMission(true, CommonConstants.INVALID_VALUE);
this.mRecentMissionsViewModel.backView();
})
}
.height(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../common/src/main/ets/default/utils/Log';
import RecentMissionCard from '../common/uicomponents/RecentMissionCard.ets';
import RecentMissionsViewModel from '../viewmodel/RecentMissionsViewModel';
import StyleConstants from '../common/constants/StyleConstants';
const TAG = 'RecentMissionsSingleLayout';
@Component
export default struct RecentMissionsSingleLayout {
@Link mRecentMissionsSingleList: [];
@Link mIsClickSubComponent: boolean;
private mRecentMissionsViewModel: RecentMissionsViewModel;
private mScroll: Scroller = new Scroller();
private aboutToAppear(): void {
this.mRecentMissionsViewModel = RecentMissionsViewModel.getInstance();
}
build() {
Column() {
// top blank area
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center })
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.SINGLE_LIST_TOP_AERA_HEIGHT * StyleConstants.DPI_RATIO)
// middle area, mission list
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Center }) {
Scroll(this.mScroll) {
Row() {
ForEach(this.mRecentMissionsSingleList, (item) => {
RecentMissionCard({
missionId: item.missionId,
appIconId: item.appIconId,
appLabelId: item.appLabelId,
appName: item.appName,
bundleName: item.bundleName,
abilityName: item.abilityName,
lockedState: item.lockedState,
mIsClickSubComponent: $mIsClickSubComponent
})
}, (item) => JSON.stringify(item))
}
}.height(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.scrollable(ScrollDirection.Horizontal)
}
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.SINGLE_LIST_MIDDLE_AERA_HEIGHT * StyleConstants.DPI_RATIO)
// bottom area, button for cleaning up running applications
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center })
{
Column() {
Image(StyleConstants.DEFAULT_DELETE_IMAGE)
.width(StyleConstants.RECENT_DELETE_IMAGE_SIZE * StyleConstants.DPI_RATIO)
.height(StyleConstants.RECENT_DELETE_IMAGE_SIZE * StyleConstants.DPI_RATIO)
}
.width(StyleConstants.RECENT_DELETE_IMAGE_COLUMN_SIZE * StyleConstants.DPI_RATIO)
.height(StyleConstants.RECENT_DELETE_IMAGE_COLUMN_SIZE * StyleConstants.DPI_RATIO)
.opacity(StyleConstants.DEFAULT_DELETE_IMAGE_OPACITY)
.backgroundColor(StyleConstants.DEFAULT_FONT_COLOR)
.borderRadius(StyleConstants.RECENT_DELETE_IMAGE_COLUMN_SIZE * StyleConstants.DPI_RATIO / 2)
.padding(8 * StyleConstants.DPI_RATIO)
.onClick(() => {
this.mIsClickSubComponent = true;
Log.showInfo(TAG, `click delete button`);
this.mRecentMissionsViewModel.deleteRecentMission(true, -1);
this.mRecentMissionsViewModel.backView();
})
}
.width(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
.height(StyleConstants.SINGLE_LIST_BOTTOM_AERA_HEIGHT * StyleConstants.DPI_RATIO)
}
.height(StyleConstants.DEFAULT_LAYOUT_PERCENTAGE)
}
}

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 2021 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 featureAbility from '@ohos.ability.featureAbility';
import launcherAbilityManager from '../../../../../../../common/src/main/ets/default/manager/LauncherAbilityManager';
import amsMissionManager from '../../../../../../../common/src/main/ets/default/manager/AmsMissionManager';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import Log from '../../../../../../../common/src/main/ets/default/utils/Log';
import RecentMissionInfo from '../../../../../../../common/src/main/ets/default/bean/RecentMissionInfo';
import RecentMissionsModel from '../../../../../../../common/src/main/ets/default/model/RecentMissionsModel';
import RecentModeFeatureConfig from '../common/layoutconfig/RecentModeFeatureConfig';
const TAG = 'RecentMissionsViewModel';
/**
* Class RecentMissionsViewModel.
*/
export default class RecentMissionsViewModel {
private mRecentMissionsModel: RecentMissionsModel;
private mRecentModeFeatureConfig: RecentModeFeatureConfig;
private mRecentMissionsLimit: number;
private mRecentMissionsList: RecentMissionInfo[] = [];
private constructor() {
Log.showInfo(TAG, `constructor start`);
this.mRecentMissionsModel = RecentMissionsModel.getInstance();
let config = LayoutConfigManager.getModeConfig(RecentModeFeatureConfig.RECENT_MISSIONS_MODE_CONFIG);
if (config instanceof RecentModeFeatureConfig) {
this.mRecentModeFeatureConfig = <RecentModeFeatureConfig>config;
this.mRecentMissionsLimit = this.mRecentModeFeatureConfig.getRecentMissionsLimit();
}
}
/**
* Delete recent missions.
*
*/
private async deleteRecentMissions() {
await amsMissionManager.clearAllMissions();
}
/**
* lockMission
*
* @param missionId
*/
private async lockMission(missionId: number) {
console.info("Launcher AmsMissionManager lockMission start!");
await amsMissionManager.lockMission(missionId);
}
/**
* unlockMission
*
* @param missionId
*/
private async unlockMission(missionId: number) {
console.info("Launcher AmsMissionManager unlockMission start!");
await amsMissionManager.unlockMission(missionId);
}
/**
* Return an instance of RecentMissionsViewModel.
*/
public static getInstance() {
if (globalThis.RecentMissionsViewModelInstance == null) {
globalThis.RecentMissionsViewModelInstance = new RecentMissionsViewModel();
}
return globalThis.RecentMissionsViewModelInstance;
}
public getRecentMissionsRowType() {
return this.mRecentModeFeatureConfig.getRecentMissionsRowType();
}
/**
* Callback function of getRecentMissionsList.
*/
public async getRecentMissionsList() {
Log.showInfo(TAG, `getRecentMissionsList start`);
this.mRecentMissionsList = await amsMissionManager.getRecentMissionsList();
Log.showInfo(TAG, `getRecentMissionsList length: ${this.mRecentMissionsList.length}`);
AppStorage.SetOrCreate('recentMissionsList', this.mRecentMissionsList);
}
/**
* Delete recent mission.
*
* @param {boolean} isClickDelBtn - The flag of click delete button.
* @param {number} missionId - The missionId of current recent mission.
*/
public async deleteRecentMission(isClickDelBtn: boolean, missionId: number) {
Log.showInfo(TAG, `deleteRecentMissions missionId: ${missionId}`);
let missionIds = [];
if (!isClickDelBtn && missionId != -1) {
missionIds.push(missionId);
await amsMissionManager.clearMission(missionId);
for (let iRecentMissionsIndex = 0; iRecentMissionsIndex < this.mRecentMissionsList.length; iRecentMissionsIndex++) {
if (this.mRecentMissionsList[iRecentMissionsIndex].missionId === missionId) {
this.mRecentMissionsList.splice(iRecentMissionsIndex, 1);
break;
}
}
} else {
for (let iRecentMissionsIndex = 0; iRecentMissionsIndex < this.mRecentMissionsList.length; iRecentMissionsIndex++) {
if (!this.mRecentMissionsList[iRecentMissionsIndex].lockedState) {
missionIds.push(this.mRecentMissionsList[iRecentMissionsIndex].missionId);
}
}
await this.deleteRecentMissions();
}
animateTo({
duration: 200,
curve: Curve.EaseInOut,
delay: 100,
playMode: PlayMode.Normal,
tempo: 0.5,
iterations: 1,
onFinish: () => {
}
}, () => {
AppStorage.SetOrCreate('recentMissionsList', this.mRecentMissionsList);
})
if(this.mRecentMissionsList.length == 0) {
this.terminateRecentIfAllClear();
}
}
/**
* Set recent mission locked status.
*
* @param {string} missionId - The missionId of current recent mission.
*/
public async setRecentMissionLock(missionId: number, lockedState: boolean) {
Log.showInfo(TAG, `setRecentMissionLock missionId: ${missionId}, lockedState: ${lockedState}`);
if (lockedState) {
this.lockMission(missionId);
} else {
this.unlockMission(missionId);
}
this.getRecentMissionsList();
}
/**
* Get mission snapshot
*
* @param missionId
*
* @return snapshot
*/
public async getMissionSnapShot(missionId: number, callback?: any) {
Log.showInfo(TAG, `getMissionSnapShot missionId: ${missionId}`);
let snapShot = await amsMissionManager.getMissionSnapShot(missionId);
if (callback != undefined) {
callback(missionId, snapShot);
} else {
return snapShot;
}
}
/**
* Move mission to front
*
* @param missionId
*/
public async moveMissionToFront(missionId: number) {
await amsMissionManager.moveMissionToFront(missionId);
}
/**
* Terminate recent.
*/
public terminateRecentIfAllClear(): void {
Log.showInfo(TAG, `terminateRecentIfAllClear start`);
setTimeout(() => {
if (this.mRecentMissionsList.length === 0) {
Log.showInfo(TAG, `terminateRecentIfAllClear all recent cleared`);
featureAbility.terminateAbility();
}
}, 1000);
}
/**
* Back to desktop.
*/
public backView() {
Log.showInfo(TAG, `backView start`);
let bundleName = 'com.ohos.launcher';
let abilityName = 'com.ohos.launcher.MainAbility';
launcherAbilityManager.startLauncherAbility(abilityName, bundleName);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,118 +0,0 @@
/*
* Copyright (c) 2021 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 router from '@system.router';
import featureAbility from '@ohos.ability.featureAbility';
import launcherAbilityManager from '../../../../../../../../common/src/main/ets/default/manager/LauncherAbilityManager.ets';
import RecentsModel from '../../../../../../../../common/src/main/ets/default/model/RecentsModel.ets';
import LayoutConfigManager from '../../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager.ets';
import RecentModeConfig from '../../../../../../../../common/src/main/ets/default/layoutconfig/RecentModeConfig.ets';
/**
* Class RecentsPresenter.
*/
export default class RecentsPresenter {
private static sRecentsPresenter: RecentsPresenter = null;
private mRecentsModel: RecentsModel;
private mRecentModeConfig: RecentModeConfig;
private mRecentsLimit: number;
private mRecentProcessList = [];
private constructor() {
this.mRecentsModel = new RecentsModel();
this.mRecentModeConfig = LayoutConfigManager.getModeConfig(RecentModeConfig.RECENT_MODE_CONFIG);
this.mRecentsLimit = this.mRecentModeConfig.getRecentProcessLimit();
}
/**
* Return an instance of RecentsPresenter.
*/
public static getInstance(): RecentsPresenter {
if (RecentsPresenter.sRecentsPresenter == null) {
RecentsPresenter.sRecentsPresenter = new RecentsPresenter();
}
return RecentsPresenter.sRecentsPresenter;
}
/**
* Callback function of getRecentProcessList.
*/
public async getRecentProcessList() {
console.info("Launcher recents RecentsPresenter getRecentProcessList start");
this.mRecentProcessList = [];
let allRecentList = await this.mRecentsModel.getRecentProcessList();
for (let i = 0; i < this.mRecentsLimit && i < allRecentList.length; i++) {
this.mRecentProcessList.push(allRecentList[i])
}
console.info("Launcher recents RecentsPresenter getRecentProcessList length" + this.mRecentProcessList.length);
AppStorage.SetOrCreate('recentProcessList', this.mRecentProcessList);
}
/**
* Clear recent process.
*/
public async clearRecentProcess() {
console.info("Launcher recents RecentsPresenter clearRecentProcess");
await launcherAbilityManager.clearRecentTask();
this.mRecentProcessList = [];
AppStorage.SetOrCreate('recentProcessList', this.mRecentProcessList);
this.terminateRecentIfAllClear();
}
/**
* Remove recent process.
*
* @param {string} missionId - The missionId of recent process.
*/
public async removeRecentProcess(missionId) {
console.info("Launcher recents RecentsPresenter removeRecentProcess missionId " + missionId);
await launcherAbilityManager.removeRecentTask(missionId);
for (let i = 0; i < this.mRecentProcessList.length; i++) {
if (this.mRecentProcessList[i].missionId === missionId) {
this.mRecentProcessList.splice(i, 1);
break;
}
}
AppStorage.SetOrCreate('recentProcessList', this.mRecentProcessList);
this.terminateRecentIfAllClear();
}
private terminateRecentIfAllClear(): void {
setTimeout(() => {
if (this.mRecentProcessList.length == 0) {
console.info("Launcher recents all recent cleared");
featureAbility.terminateAbility();
}
},1000);
}
/**
* Back to desktop.
*/
public back() {
console.info("Launcher recents RecentsPresenter back");
router.back();
}
/**
* Start app.
*
* @param {object} appInfo - The app info.
*/
public startUpApp(abilityName, bundleName) {
console.info("Launcher recents RecentsPresenter startUpApp abilityName: " + abilityName);
launcherAbilityManager.startLauncherAbility(abilityName, bundleName);
}
}

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) 2021 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 GridName from '../../../../../../../common/src/main/ets/default/uicomponents/GridName.ets';
import AppIcon from '../../../../../../../common/src/main/ets/default/uicomponents/AppIcon.ets';
import StyleConstants from '../../../../../../../common/src/main/ets/default/constants/StyleConstants.ets';
import RecentsPresenter from '../common/presenter/RecentsPresenter.ets';
import RecentsStage from '../common/RecentsStage.ets';
let mRecentsPresenter: RecentsPresenter;
@Entry
@Component
struct Recent {
@StorageLink('recentProcessList') mRecentProcessList: [] = [];
@State size: string = StyleConstants.PERCENTAGE_100;
private mRecentsStage = new RecentsStage();
onPageShow() {
console.log("Launcher recents onPageShow");
this.mRecentsStage.onCreate();
mRecentsPresenter = RecentsPresenter.getInstance();
mRecentsPresenter.getRecentProcessList();
}
onPageHide() {
console.info("Launcher recents onPageHide");
this.mRecentProcessList = [];
this.mRecentsStage.onDestroy();
}
build() {
Column() {
if (this.mRecentProcessList.length === 0) {
emptyMsgDisplay();
}
recentProcessListDisplay({ recentProcessList: $mRecentProcessList });
}
.width(this.size)
.height(this.size)
.backgroundImage(StyleConstants.DEFAULT_BACKGROUND_IMAGE_RECENT)
}
}
@Component
struct recentProcessListDisplay {
@Link recentProcessList: [];
scroller: Scroller = new Scroller();
@State AppIconSize: number = 55;
@State AppItemHeight: number = StyleConstants.DEFAULT_APP_ITEM_HEIGHT;
@State AppItemWidth: number = StyleConstants.DEFAULT_APP_ITEM_WIDTH;
@State heightSize: string = StyleConstants.PERCENTAGE_100;
@State appHeightSize: string = StyleConstants.PERCENTAGE_85;
@State deleteHeightSize: string = StyleConstants.PERCENTAGE_15;
@State AppborderRadius: number = 10;
@State DeleteImageSize: number = 50;
@State DeleteOpacity: number = 0.5;
@State margin: number = 10;
build() {
Column() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Center }) {
Scroll(this.scroller) {
Row() {
ForEach(this.recentProcessList, (item) => {
Column() {
Column() {
AppIcon({
iconSize: this.AppIconSize,
appIcon: item.appIconId,
bundleName: item.bundleName,
labelId: item.appLabelId,
useCache: false
})
GridName({
appName: item.appName,
nameHeight: this.AppItemHeight - this.AppItemWidth,
nameWidth: this.AppItemWidth,
bundleName: item.bundleName,
labelId: item.appLabelId,
useCache: false
})
}
.margin({ bottom: this.margin })
Image(StyleConstants.DEFAULT_APP_IMAGE)
.borderRadius(this.AppborderRadius)
.width(StyleConstants.PERCENTAGE_100)
.height(StyleConstants.PERCENTAGE_70)
}
.width(StyleConstants.APP_IMAGE_WIDTH)
.height(this.heightSize)
.margin({ right: this.margin })
.onClick(() => {
mRecentsPresenter.startUpApp(item.abilityName, item.bundleName);
})
.gesture(
PanGesture({ fingers: 1, direction: PanDirection.Vertical, distance: 5 })
.onActionEnd((e) => {
let mOffectWidth = (StyleConstants.APP_IMAGE_WIDTH) / 2;
if (e.offsetY < -50 && e.offsetX <= mOffectWidth && -mOffectWidth <= e.offsetX) {
mRecentsPresenter.removeRecentProcess(item.missionId);
}
}))
},(item) => JSON.stringify(item))
}
}.height(this.appHeightSize)
.scrollable(ScrollDirection.Horizontal)
}
.width(this.heightSize)
.height(this.appHeightSize)
Column() {
Image(StyleConstants.DEFAULT_DELETE_IMAGE)
.width(this.DeleteImageSize)
.height(this.DeleteImageSize)
.opacity(this.DeleteOpacity)
.align(Alignment.Bottom)
.onClick(() => {
mRecentsPresenter.clearRecentProcess();
setTimeout(() => {
console.info("Launcher recents clearAll this.mRecentsPresenter.back()");
mRecentsPresenter.back();
}, 1500);
})
}.alignItems(HorizontalAlign.Center)
.width(this.heightSize)
.height(this.deleteHeightSize)
}
}
}
@Component
struct emptyMsgDisplay {
@State size: string = StyleConstants.PERCENTAGE_100;
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text($r('app.string.No_running_apps_recently'))
.fontColor(StyleConstants.DEFAULT_FONT_COLOR)
.fontSize(StyleConstants.DEFAULT_NUMBER)
}
.width(this.size)
.height(this.size)
}
}

View File

@ -1,16 +0,0 @@
{
"string": [
{
"name": "recents_MainAbility",
"value": "recents_MainAbility"
},
{
"name": "mainability_description",
"value": "ETS_Empty Feature Ability"
},
{
"name": "No_running_apps_recently",
"value": "No running apps recently"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -1,16 +0,0 @@
{
"string": [
{
"name": "recents_MainAbility",
"value": "recents_MainAbility"
},
{
"name": "mainability_description",
"value": "ETS_Empty Feature Ability"
},
{
"name": "No_running_apps_recently",
"value": "No running apps recently"
}
]
}

View File

@ -1,16 +0,0 @@
{
"string": [
{
"name": "recents_MainAbility",
"value": "recents_MainAbility"
},
{
"name": "mainability_description",
"value": "ETS_Empty Feature Ability"
},
{
"name": "No_running_apps_recently",
"value": "最近无运行应用"
}
]
}

View File

@ -1,9 +1,10 @@
apply plugin: 'com.huawei.ohos.hap'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 7
compileSdkVersion 8
defaultConfig {
compatibleSdkVersion 4
compatibleSdkVersion 8
}
buildTypes {
release {

View File

@ -9,9 +9,10 @@
},
"deviceConfig": {},
"module": {
"srcPath": "",
"package": "com.ohos.launcher.settings",
"name": ".MyApplication",
"mainAbility": "com.ohos.launcher.settings.MainAbility",
"mainAbility": ".MainAbility",
"deviceType": [
"phone"
],
@ -23,14 +24,14 @@
},
"abilities": [
{
"visible": true,
"name": "com.ohos.launcher.settings.MainAbility",
"visible": false,
"name": ".MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:settings_MainAbility",
"type": "page",
"launchType": "singleton",
"srcPath": "default",
"srcPath": "MainAbility",
"srcLanguage": "ets"
}
],
@ -43,7 +44,7 @@
"pages": [
"pages/Settings"
],
"name": "default",
"name": ".MainAbility",
"window": {
"designWidth": 720,
"autoDesignWidth": false

View File

@ -0,0 +1,7 @@
import AbilityStage from '@ohos.application.AbilityStage';
export default class MyAbilityStage extends AbilityStage {
onCreate() {
console.log('settings MyAbilityStage onCreate is called');
}
}

View File

@ -0,0 +1,30 @@
import Ability from '@ohos.application.Ability';
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log('settings MainAbility onCreate is called');
}
onDestroy() {
console.log('settings MainAbility onDestroy is called');
}
onWindowStageCreate(windowStage) {
console.log('settings MainAbility onWindowStageCreate is called');
globalThis.settingsContext = this.context;
windowStage.setUIContent(this.context, 'pages/Settings', null);
}
onWindowStageDestroy() {
console.log('settings MainAbility onWindowStageDestroy is called');
}
onForeground() {
console.log('settings MainAbility onForeground is called');
}
onBackground() {
console.log('settings MainAbility onBackground is called');
globalThis.settingsContext.terminateSelf();
}
}

View File

@ -13,28 +13,29 @@
* limitations under the License.
*/
import BaseModulePreLoader from '../../../../../../../common/src/main/ets/default/base/BaseModulePreLoader.ets';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager.ets';
import RecentModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/RecentModeConfig.ets';
import WorkSpaceModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/WorkSpaceModeConfig.ets';
import BaseModulePreLoader from '../../../../../../../common/src/main/ets/default/base/BaseModulePreLoader';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import RecentsModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/RecentsModeConfig';
import PageDesktopLayoutConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/PageDesktopLayoutConfig';
import PageDesktopModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/PageDesktopModeConfig';
/**
*
*/
class SettingsPreLoader extends BaseModulePreLoader {
protected loadConfig(): void {
LayoutConfigManager.addConfigToManager(RecentModeConfig.getInstance());
LayoutConfigManager.addConfigToManager(WorkSpaceModeConfig.getInstance());
LayoutConfigManager.addConfigToManager(RecentsModeConfig.getInstance());
LayoutConfigManager.addConfigToManager(PageDesktopModeConfig.getInstance());
LayoutConfigManager.addConfigToManager(PageDesktopLayoutConfig.getInstance());
}
protected loadData(): void {
}
public releaseConfigAndData(): void {
releaseConfigAndData(): void {
LayoutConfigManager.removeConfigFromManager();
}
}
let settingsPreLoader = new SettingsPreLoader();
const settingsPreLoader = new SettingsPreLoader();
export default settingsPreLoader;

View File

@ -13,8 +13,8 @@
* limitations under the License.
*/
import BaseStage from '../../../../../../../common/src/main/ets/default/base/BaseStage.ets';
import settingsPreLoader from './SettingsPreLoader.ets';
import BaseStage from '../../../../../../../common/src/main/ets/default/base/BaseStage';
import settingsPreLoader from './SettingsPreLoader';
/**
* Stage
@ -23,14 +23,14 @@ export default class SettingsStage extends BaseStage {
/**
* Stage启动时的回调
*/
public onCreate(): void {
onCreate(): void {
settingsPreLoader.load();
}
/**
* Stage退出时回调
* Stage退出时回调
*/
public onDestroy(): void {
onDestroy(): void {
settingsPreLoader.releaseConfigAndData();
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 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.
*/
export default class StyleConstants {
static readonly DEFAULT_LAYOUT_FONT_COLOR = '#696969';
static readonly DEFAULT_BACKGROUND_COLOR = '#F0EEEE';
static readonly DEFAULT_DIALOG_FONT_COLOR = '#000000';
static readonly DEFAULT_SETTING_PAGE_COLOR = '#FFFFFF';
static readonly PERCENTAGE_100 = '100%';
static readonly PERCENTAGE_90 = '90%';
static readonly PERCENTAGE_85 = '85%';
static readonly PERCENTAGE_60 = '60%';
static readonly DEFAULT_VP_10 = 10;
static readonly DEFAULT_VP_14 = 14;
static readonly DEFAULT_VP_16 = 16;
static readonly DEFAULT_VP_20 = 20;
static readonly DEFAULT_VP_24 = 24;
static readonly DEFAULT_VP_25 = 25;
static readonly DEFAULT_VP_30 = 30;
static readonly DEFAULT_VP_35 = 35;
static readonly DEFAULT_VP_48 = 48;
static readonly DEFAULT_VP_80 = 80;
static readonly DEFAULT_VP_56 = 56;
static readonly DEFAULT_VP_60 = 60;
static readonly DEFAULT_VP_75 = 75;
static readonly DEFAULT_VP_100 = 100;
static readonly DEFAULT_VP_120 = 120;
static readonly DEFAULT_VP_340 = 340;
static readonly DEFAULT_VP_462 = 462;
static readonly DEFAULT_VP_692 = 692;
static readonly DEFAULT_VP_772 = 772;
static readonly DEFAULT_VP_812 = 812;
}

View File

@ -0,0 +1,239 @@
/*
* Copyright (c) 2021 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 featureAbility from '@ohos.ability.featureAbility';
import SettingItemOptionsChecker from '../../../../../../../../common/src/main/ets/default/settings/SettingItemOptionsChecker';
import SettingItemsManager from '../../../../../../../../common/src/main/ets/default/settings/SettingItemsManager';
import SettingItemInfo from '../../../../../../../../common/src/main/ets/default/bean/SettingItemInfo';
import SettingItemsConfig from '../../../../../../../../common/src/main/ets/default/configs/SettingItemsConfig';
import SettingsModel from '../../../../../../../../common/src/main/ets/default/model/SettingsModel';
/**
* Class SettingsPresenter.
*/
export default class SettingsPresenter {
/**
* style: list or grid
*/
static SETTINGS_INDEX_STYLE = 0;
/**
* grid layout: row x column
*/
static SETTINGS_INDEX_GRID_LAYOUT = 1;
private static sSettingPresenter: SettingsPresenter = null;
private readonly mSettingsModel: SettingsModel = null;
private readonly mCallbackList = [];
private readonly mSettingItemsManager: SettingItemsManager;
private readonly mLayoutOptionsChecker: SettingItemOptionsChecker = ()=> {
const layout = this.mSettingsModel.getAppPageStartConfig();
console.info('Launcher SettingsPresenter mLayoutOptionsChecker layout is ' + layout);
return layout;
};
private readonly mGridLayOutOptionsChecker: SettingItemOptionsChecker = ()=> {
const gridLayout = this.mSettingsModel.getGridConfig().layout;
console.info('Launcher SettingsPresenter mGridLayOutOptionsChecker layout is ' + gridLayout);
return gridLayout;
};
/**
* Constructor.
*
* @param {object} settingsModel - model of setting.
*/
constructor() {
this.mSettingsModel = SettingsModel.getInstance();
this.mSettingItemsManager = (new SettingItemsManager()).
withChecker(SettingItemsConfig.SETTING_ITEM_LAYOUT_OPTIONS, this.mLayoutOptionsChecker).
withChecker(SettingItemsConfig.SETTING_ITEM_PHONE_GRID_LAYOUT_OPTIONS, this.mGridLayOutOptionsChecker).
withChecker(SettingItemsConfig.SETTING_ITEM_PAD_GRID_LAYOUT_OPTIONS, this.mGridLayOutOptionsChecker);
}
/**
* Get settingsPresenter instance.
*
* @return {settingPresenter} - settingPresenter.
*/
static getInstance(): SettingsPresenter{
if (SettingsPresenter.sSettingPresenter == null) {
SettingsPresenter.sSettingPresenter = new SettingsPresenter();
}
return SettingsPresenter.sSettingPresenter;
}
/**
* Get setting list.
*
* @return [settingList] - setting list.
*/
getSettingList(): SettingItemInfo[] {
const deviceType = this.mSettingsModel.getDevice() == 'phone' ?
SettingItemsConfig.DEVICE_TYPE_PHONE : SettingItemsConfig.DEVICE_TYPE_PAD;
const condition = this.mSettingsModel.getAppPageStartConfig() == 'Grid' ?
SettingItemsConfig.CONDITION_GRID_LAYOUT_ENABLE : SettingItemsConfig.CONDITION_LIST_LAYOUT_ENABLE;
console.info('Launcher SettingsPresenter getSettingList, deviceType is '+ deviceType + ', condition is ' + condition);
return this.mSettingItemsManager.get(deviceType, condition);
}
/**
* Set system setting value.
*
* @param {string} settingsName - setting name.
* @param {string} settingValue - setting value.
*/
setSettingsValue(ida, settingValue) {
console.info('Launcher SettingsPresenter setSettingsValue, ida is '+ ida + ', settingValue is ' + settingValue);
if (ida == SettingsPresenter.SETTINGS_INDEX_STYLE) {
this.setAppPageStartConfig(settingValue);
} else if (ida == SettingsPresenter.SETTINGS_INDEX_GRID_LAYOUT) {
const idx = this.mSettingItemsManager.gridLayoutValue2Idx(settingValue);
console.info('Launcher SettingsPresenter setSettingsValue, idx is '+ idx);
this.setGridConfig(idx);
} else {
this.setRecentMissionsLimit(settingValue);
}
this.settingUpdate();
}
/**
* Set app start config.
*
* @param {string} type - the type of config.
*/
setAppPageStartConfig(type) {
this.mSettingsModel.setAppPageStartConfig(type);
}
/**
* Update setting.
*
*/
settingUpdate() {
console.info('Launcher settings SettingsModel settingUpdate start');
globalThis.settingsContext.terminateSelf()
.then(data => console.info('Launcher settings terminateSelf promise::then : ' + data))
.catch(error => console.info('Launcher settings terminateSelf promise::catch : ' + error));
console.info('Launcher settings terminateSelf end ');
}
/**
* Set grid config.
*
* @param {string} id - the id of grid config.
*/
setGridConfig(id) {
this.mSettingsModel.setGridConfig(id);
}
/**
* Set recent missions limit.
*
* @param {number} num - the num of recent missions.
*/
setRecentMissionsLimit(num) {
this.mSettingsModel.setRecentMissionsLimit(num);
}
/**
* Back to the desktop interface.
*
*/
backToTheDesktop() {
console.info('Launcher settings backToTheDesktop!');
this.settingUpdate();
}
/**
* Register value callback.
*
* @param {string} settingsName - setting name.
* @param {function()} settingValue - setting value.
*/
registerValueCallback(ida, settingValue) {
this.mCallbackList.push({
id: ida,
fun: settingValue
});
}
/**
* Change page setting value.
*
* @param {string} settingsName - setting name.
* @param {string} settingValue - setting value.
*/
changeSettingValue(ida, settingValue) {
for (let i = 0;i < this.mCallbackList.length; i++) {
if (this.mCallbackList[i].id == ida) {
this.mCallbackList[i].fun(settingValue);
break;
}
}
}
/**
* get the device type.
*
* @return {string} device type
*/
getDevice(): string {
return this.mSettingsModel.getDevice();
}
setValue(value: string) {
console.info(`Launcher SettingsPresenter setValue setValue: ${value}`);
if (value != '1' && value != '0') {
console.info('Launcher SettingsPresenter setValue error');
return;
}
try{
this.mSettingsModel.setValue(value);
} catch (e) {
console.info(`Launcher SettingsPresenter setValue error: ${e.toString()}`);
}
this.mSettingsModel.setValue(value);
}
initNavigationBarStatusValue() {
try {
const initValue = this.mSettingsModel.getValue();
const navigationBarStatusValue = initValue == '0' ? true : false;
console.info(`Launcher SettingsPresenter initNavigationBarStatusValue initValue:${initValue}, navigationBarStatusValue:${navigationBarStatusValue}`);
AppStorage.SetOrCreate('NavigationBarStatusValue', navigationBarStatusValue);
this.mSettingsModel.registerListenForDataChanges(this.dataChangesCallback.bind(this));
} catch (e) {
console.info(`Launcher SettingsPresenter initNavigationBarStatusValue error: ${e.toString()}`);
}
}
private dataChangesCallback(data: any) {
if (data.code !== 0) {
console.log(`Launcher SettingsPresenter dataChangesCallback failed, because ${data.message}`);
} else {
const getRetValue = this.mSettingsModel.getValue();
console.log(`Launcher SettingsPresenter dataChangesCallback getRetValue ${getRetValue}`);
AppStorage.SetOrCreate('NavigationBarStatusValue', getRetValue == '0' ? true : false);
}
}
}

View File

@ -0,0 +1,251 @@
/*
* Copyright (c) 2021 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 StyleConstants from '../common/constants/StyleConstants';
import SettingsPresenter from '../common/presenter/SettingsPresenter';
import SettingsStage from '../common/SettingsStage';
import SettingItemInfo from '../../../../../../../common/src/main/ets/default/bean/SettingItemInfo';
import Trace from '../../../../../../../common/src/main/ets/default/utils/Trace';
let mSettingsPresenter: SettingsPresenter;
@Entry
@Component
struct Index {
private mSettingsStage = new SettingsStage();
onPageShow(): void {
Trace.end(Trace.CORE_METHOD_START_SETTINGS)
}
aboutToAppear(): void {
this.mSettingsStage.onCreate();
mSettingsPresenter = SettingsPresenter.getInstance();
}
aboutToDisappear() {
this.mSettingsStage.onDestroy();
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
Row() {
top_bar()
}
Column() {
Text($r('app.string.layout'))
.fontSize($r("app.float.layout_title_font_size"))
.fontColor(StyleConstants.DEFAULT_LAYOUT_FONT_COLOR)
.height(StyleConstants.DEFAULT_VP_48)
.width($r("app.float.layout_title_width"))
}
Column() {
SettingPage()
}
}.width(StyleConstants.PERCENTAGE_100)
.height(StyleConstants.PERCENTAGE_100)
.backgroundColor(StyleConstants.DEFAULT_BACKGROUND_COLOR)
}
}
@Component
struct top_bar {
build() {
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Column(){
Image($r('app.media.ic_back'))
.margin({ right: StyleConstants.DEFAULT_VP_20 })
.width($r("app.float.top_bar_icon_size"))
.height($r("app.float.top_bar_icon_size"))
.objectFit(ImageFit.Contain)
}
.onClick(() => {
mSettingsPresenter.backToTheDesktop();
})
Text($r('app.string.into_settings'))
.fontSize($r("app.float.top_bar_font_size"))
}
.margin({ top: StyleConstants.DEFAULT_VP_24 })
.height(StyleConstants.DEFAULT_VP_56)
.width($r("app.float.top_bar_width"))
}
}
@Component
struct SettingPage {
@State SettingList: SettingItemInfo[] = [];
private aboutToAppear(): void {
this.SettingList = mSettingsPresenter.getSettingList();
console.info('Launcher SettingPage aboutToAppear SettingList ' + JSON.stringify(this.SettingList));
}
private onPageShow(): void {
this.SettingList = mSettingsPresenter.getSettingList();
}
build() {
Column() {
ForEach(this.SettingList, (item: any) => {
SettingItem({
ida: item.ida,
settingName: item.settingName,
settingValue: item.settingValue,
valueList: item.valueList,
settingType: item.settingType
})
},(item: any) => JSON.stringify(item))
}
.padding(StyleConstants.DEFAULT_VP_20)
.borderRadius(StyleConstants.DEFAULT_VP_30)
.backgroundColor(StyleConstants.DEFAULT_SETTING_PAGE_COLOR)
.align(Alignment.Center)
}
}
@Component
struct SettingItem {
@State ida: number = 0;
@State settingValue: string = ' ';
@State settingName: string = ' ';
@StorageLink('NavigationBarStatusValue') navigationBarStatusValue: boolean = false;
private settingType: number;
private valueList: SettingItemInfo[] = [];
dialogController: CustomDialogController = new CustomDialogController({
builder: SettingsDialog(),
cancel: this.cancelDialog,
autoCancel: true
});
cancelDialog() {
console.info('cancelDialog');
}
private aboutToAppear(): void {
mSettingsPresenter.initNavigationBarStatusValue();
if (this.settingType == 1) {
mSettingsPresenter.registerValueCallback(this.ida, this.callback.bind(this));
}
}
callback(data) {
this.settingValue = data;
}
build() {
Flex({
direction: FlexDirection.Row,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.SpaceBetween
}) {
Column() {
Text(this.settingName)
.lineHeight(StyleConstants.DEFAULT_VP_48)
.height(StyleConstants.DEFAULT_VP_48)
.width($r("app.float.setting_item_title_width"))
.fontSize($r("app.float.setting_item_title_font_size"))
.align(Alignment.Start)
}
if (this.settingType == 1) {
Column() {
Row (){
Text(this.settingValue)
.lineHeight(StyleConstants.DEFAULT_VP_48)
.height(StyleConstants.DEFAULT_VP_48)
.width(StyleConstants.DEFAULT_VP_60)
.fontSize(StyleConstants.DEFAULT_VP_16)
.align(Alignment.End)
Image($r('app.media.ic_settings_arrow'))
.margin({ top: StyleConstants.DEFAULT_VP_16 })
.height(StyleConstants.DEFAULT_VP_16)
.width(StyleConstants.DEFAULT_VP_20)
.align(Alignment.End)
}
}
.onClick(() => {
AppStorage.SetOrCreate('ida', this.ida);
AppStorage.SetOrCreate('valueList', this.valueList);
AppStorage.SetOrCreate('settingValue', this.settingValue);
this.dialogController.open();
})
} else {
Toggle({ type: ToggleType.Switch, isOn: this.navigationBarStatusValue })
.width(50)
.height(40)
.onChange((isOn: boolean) => {
console.info('Launcher SettingItemToggle onChange for Wlan Enable:' + isOn);
mSettingsPresenter.setValue(isOn ? "0" : "1");
})
}
}
.width($r("app.float.setting_item_width"))
.height(StyleConstants.DEFAULT_VP_48)
}
}
@CustomDialog
@Component
struct SettingsDialog {
controller: CustomDialogController;
action: () => void;
cancel: () => void;
@StorageLink('valueList') valueList: SettingItemInfo[] = [];
@StorageLink('ida') ida: number = 0;
@StorageLink('settingValue') settingValue: String = '';
build() {
Column() {
ForEach(this.valueList, (item: any) => {
Row() {
Text(item.name)
.margin({ left: StyleConstants.DEFAULT_VP_10 })
.align(Alignment.Start)
.width(StyleConstants.PERCENTAGE_85)
.fontSize(StyleConstants.DEFAULT_VP_30)
.fontColor(StyleConstants.DEFAULT_DIALOG_FONT_COLOR)
Radio({ value: item.value, group: ("" + this.ida) })
.enabled(false)
.checked(item.name === this.settingValue)
.width(StyleConstants.DEFAULT_VP_30)
.height(StyleConstants.DEFAULT_VP_30)
.onChange((isChecked) => {})
}.width(StyleConstants.PERCENTAGE_100)
.height(StyleConstants.DEFAULT_VP_80)
.onClick(() => {
mSettingsPresenter.changeSettingValue(this.ida, item.name);
mSettingsPresenter.setSettingsValue(this.ida, item.value);
this.controller.close();
this.action();
})
},(item: any) => JSON.stringify(item))
Text($r('app.string.cancel'))
.textAlign(TextAlign.Center)
.height(StyleConstants.DEFAULT_VP_80)
.width(StyleConstants.PERCENTAGE_100)
.fontSize(StyleConstants.DEFAULT_VP_30)
.fontColor(Color.Blue)
.onClick(() => {
this.controller.close();
this.action();
})
}.padding(StyleConstants.DEFAULT_VP_20)
.backgroundColor(StyleConstants.DEFAULT_SETTING_PAGE_COLOR)
.borderRadius(StyleConstants.DEFAULT_VP_30)
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2021 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.
*/
export default class StyleConstants {
public static DEFAULT_LAYOUT_FONT_COLOR: string = '#696969';
public static DEFAULT_BACKGROUND_COLOR: string = '#F0EEEE';
public static DEFAULT_DIALOG_FONT_COLOR: string = '#000000';
public static DEFAULT_SETTING_PAGE_COLOR: string = '#FFFFFF';
public static PERCENTAGE_100: string = '100%';
public static PERCENTAGE_90: string = '90%';
public static PERCENTAGE_85: string = '85%';
public static PERCENTAGE_60: string = '60%';
public static PERCENTAGE_30: string = '30%';
public static PERCENTAGE_15: string = '15%';
public static DEFAULT_APP_NAME_SIZE: number= 20;
public static DEFAULT_APP_ITEM_WIDTH: number = 70;
public static DEFAULT_APP_ITEM_HEIGHT: number = 95;
public static DEFAULT_PIXEL_10: number = 10;
public static DEFAULT_PIXEL_15: number = 15;
public static DEFAULT_PIXEL_20: number = 20;
public static DEFAULT_PIXEL_25: number = 25;
public static DEFAULT_PIXEL_30: number = 30;
public static DEFAULT_PIXEL_35: number = 35;
public static DEFAULT_PIXEL_40: number = 40;
public static DEFAULT_PIXEL_80: number = 80;
public static DEFAULT_PIXEL_60: number = 60;
public static DEFAULT_PIXEL_75: number = 75;
public static DEFAULT_PIXEL_100: number = 100;
public static DEFAULT_PIXEL_120: number = 120;
public static DEFAULT_PIXEL_200: number = 200;
public static DEFAULT_PIXEL_340: number = 340;
}

View File

@ -1,223 +0,0 @@
/*
* Copyright (c) 2021 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 featureAbility from '@ohos.ability.featureAbility';
import DefaultLayoutConfig from '../../../../../../../../common/src/main/ets/default/configs/DefaultLayoutConfig.ets'
import GridLayoutConfigs from '../../../../../../../../common/src/main/ets/default/configs/GridLayoutConfigs.ets'
import SettingsModel from '../../../../../../../../common/src/main/ets/default/model/SettingsModel.ets'
/**
* Class SettingsPresenter.
*/
export default class SettingsPresenter {
private static sSettingPresenter: SettingsPresenter = null;
private mSettingsModel: SettingsModel = null;
private callbackList = [];
/**
* Grid settingList.
*/
private gridSettingsList = [
{
ida: 0,
settingName: $r('app.string.layoutStyle'),
settingValue: '',
valueList: DefaultLayoutConfig.DefaultLayoutOptions
},
{
ida: 1,
settingName: $r('app.string.launcherLayout'),
settingValue: '',
valueList: GridLayoutConfigs.GridLayoutTable
},
{
ida: 2,
settingName: $r('app.string.recentTasksSetting'),
settingValue: '',
valueList: DefaultLayoutConfig.DefaultRecentProcessLimitArray
}
]
/**
* List settingList.
*/
private listSettingsList = [
{
ida: 0,
settingName: $r('app.string.layoutStyle'),
settingValue: '',
valueList: DefaultLayoutConfig.DefaultLayoutOptions
},
{
ida: 2,
settingName: $r('app.string.recentTasksSetting'),
settingValue: '',
valueList: DefaultLayoutConfig.DefaultRecentProcessLimitArray
}
]
/**
* Constructor.
*
* @param {object} settingsModel - model of setting.
*/
constructor() {
this.mSettingsModel = new SettingsModel();
this.gridSettingsList[1].valueList = this.mSettingsModel.getGridLayoutTable();
}
/**
* Get settingsPresenter instance.
*
* @return {settingPresenter} - settingPresenter.
*/
public static getInstance(): SettingsPresenter {
if (SettingsPresenter.sSettingPresenter == null) {
SettingsPresenter.sSettingPresenter = new SettingsPresenter();
}
return SettingsPresenter.sSettingPresenter;
}
/**
* Get setting list.
*
* @return [settingList] - setting list.
*/
public getSettingList() {
let layout = this.mSettingsModel.getAppPageStartConfig();
for (let i = 0; i < this.gridSettingsList[0].valueList.length; i++) {
if (this.gridSettingsList[0].valueList[i].name == layout) {
this.gridSettingsList[0].valueList[i].checked = true;
this.listSettingsList[0].valueList[i].checked = true;
break;
}
}
let gridLayout = this.mSettingsModel.getGridConfig().layout;
for (let i = 0; i < this.gridSettingsList[1].valueList.length; i++) {
if (this.gridSettingsList[1].valueList[i].name == gridLayout) {
this.gridSettingsList[1].valueList[i].checked = true;
break;
}
}
let Limit = this.mSettingsModel.getRecentProcessLimit().toString();
for (let i = 0; i < this.gridSettingsList[2].valueList.length; i++) {
if (this.gridSettingsList[2].valueList[i].name == Limit) {
this.gridSettingsList[2].valueList[i].checked = true;
this.listSettingsList[1].valueList[i].checked = true;
break;
}
}
if (layout == 'Grid') {
this.gridSettingsList[0].settingValue = layout;
this.gridSettingsList[1].settingValue = gridLayout;
this.gridSettingsList[2].settingValue = Limit;
return this.gridSettingsList;
} else {
this.listSettingsList[0].settingValue = layout;
this.listSettingsList[1].settingValue = Limit;
return this.listSettingsList;
}
}
/**
* Set system setting value.
*
* @param {string} settingsName - setting name.
* @param {string} settingValue - setting value.
*/
public setSettingsValue(ida, settingValue) {
if (ida == 0) {
this.setAppPageStartConfig(settingValue);
} else if (ida == 1) {
this.setGridConfig(settingValue);
} else {
this.setRecentProcessLimit(settingValue);
}
this.settingUpdate();
}
/**
* Set app start config.
*
* @param {string} type - the type of config.
*/
public setAppPageStartConfig(type) {
this.mSettingsModel.setAppPageStartConfig(type);
}
/**
* Update setting.
*/
public settingUpdate() {
console.info("Launcher settings SettingsModel settingsUpdate start");
featureAbility.terminateAbility()
.then(data => console.info("Launcher settings terminateAbility promise::then : " + data))
.catch(error => console.info("Launcher settings terminateAbility promise::catch : " + error));
console.info("Launcher settings terminateAbility end ");
}
/**
* Set grid config.
*
* @param {string} id - the id of grid config.
*/
public setGridConfig(id) {
this.mSettingsModel.setGridConfig(id);
}
/**
* Set recent process.
*
* @param {number} num - the num of recent process.
*/
public setRecentProcessLimit(num) {
this.mSettingsModel.setRecentProcessLimit(num);
}
/**
* Back to the desktop interface.
*/
public backToTheDesktop() {
this.settingUpdate();
}
/**
* Register value callback.
*
* @param {string} settingsName - setting name.
* @param {function()} settingValue - setting value.
*/
public registerValueCallback(ida, settingValue) {
this.callbackList.push({
id: ida,
fun: settingValue
});
}
/**
* Change page setting value.
*
* @param {string} settingsName - setting name.
* @param {string} settingValue - setting value.
*/
public changeSettingValue(ida, settingValue) {
for (let i = 0; i < this.callbackList.length; i++) {
if (this.callbackList[i].id == ida) {
this.callbackList[i].fun(settingValue);
break;
}
}
}
}

View File

@ -1,219 +0,0 @@
/*
* Copyright (c) 2021 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 StyleConstants from '../common/constants/StyleConstants.ets';
import SettingsPresenter from '../common/presenter/SettingsPresenter.ets';
import SettingsStage from '../common/SettingsStage.ets';
let mSettingsPresenter: SettingsPresenter;
@Entry
@Component
struct Index {
private mSettingsStage = new SettingsStage();
aboutToAppear(): void {
this.mSettingsStage.onCreate();
mSettingsPresenter = SettingsPresenter.getInstance();
}
aboutToDisappear() {
this.mSettingsStage.onDestroy();
}
build() {
Flex({ alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
Row() {
top_bar()
}
Column() {
Text($r('app.string.layout'))
.fontSize(StyleConstants.DEFAULT_PIXEL_25)
.fontColor(StyleConstants.DEFAULT_LAYOUT_FONT_COLOR)
.margin({ right: StyleConstants.DEFAULT_PIXEL_340 })
}
Column() {
SettingPage()
}
}.width(StyleConstants.PERCENTAGE_100)
.height(StyleConstants.PERCENTAGE_100)
.backgroundColor(StyleConstants.DEFAULT_BACKGROUND_COLOR)
}
}
@Component
struct top_bar {
build() {
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Image($r('app.media.ic_back'))
.margin({ right: StyleConstants.DEFAULT_PIXEL_20,
left: StyleConstants.DEFAULT_PIXEL_20 })
.width(StyleConstants.DEFAULT_PIXEL_75)
.height(StyleConstants.DEFAULT_PIXEL_75)
.objectFit(ImageFit.Contain)
.onClick(() => {
mSettingsPresenter.backToTheDesktop();
})
Text($r('app.string.intoSettings'))
.fontSize(StyleConstants.DEFAULT_PIXEL_35)
}
.margin({ top: StyleConstants.DEFAULT_PIXEL_10 })
.height(StyleConstants.DEFAULT_PIXEL_80)
.width(StyleConstants.PERCENTAGE_90)
.backgroundColor(StyleConstants.DEFAULT_BACKGROUND_COLOR)
.padding({ bottom: StyleConstants.DEFAULT_PIXEL_10 })
}
}
@Component
struct SettingPage {
@State SettingList: any = [];
private aboutToAppear(): void {
this.SettingList = mSettingsPresenter.getSettingList();
}
private onPageShow(): void {
this.SettingList = mSettingsPresenter.getSettingList();
}
build() {
Column() {
ForEach(this.SettingList, (item: any) => {
SettingItem({
ida: item.ida,
settingName: item.settingName,
settingValue: item.settingValue,
valueList: item.valueList,
})
},(item: any) => JSON.stringify(item))
}
.margin({ top: StyleConstants.DEFAULT_PIXEL_10,
bottom: StyleConstants.DEFAULT_PIXEL_10,
left: StyleConstants.DEFAULT_PIXEL_30,
right: StyleConstants.DEFAULT_PIXEL_30 })
.padding(StyleConstants.DEFAULT_PIXEL_20)
.borderRadius(StyleConstants.DEFAULT_PIXEL_30)
.backgroundColor(StyleConstants.DEFAULT_SETTING_PAGE_COLOR)
}
}
@Component
struct SettingItem {
@State ida: number = 0;
@State settingValue: string = ' ';
@State settingName: string = ' ';
private valueList: any;
dialogController: CustomDialogController = new CustomDialogController({
builder: SettingsDialog(),
cancel: this.cancelDialog,
autoCancel: true
});
cancelDialog() {
console.info('cancelDialog');
}
private aboutToAppear(): void {
mSettingsPresenter.registerValueCallback(this.ida, this.callback.bind(this));
}
callback(data) {
this.settingValue = data;
}
build() {
Column() {
Row() {
Text(this.settingName)
.lineHeight(StyleConstants.DEFAULT_PIXEL_60)
.height(StyleConstants.DEFAULT_PIXEL_60)
.fontSize(StyleConstants.DEFAULT_PIXEL_30)
.width(StyleConstants.PERCENTAGE_60)
.align(Alignment.Start)
Text(this.settingValue)
.lineHeight(StyleConstants.DEFAULT_PIXEL_60)
.height(StyleConstants.DEFAULT_PIXEL_60)
.fontSize(StyleConstants.DEFAULT_PIXEL_30)
.width(StyleConstants.DEFAULT_PIXEL_60)
.align(Alignment.Start)
Image($r('app.media.ic_settings_arrow'))
.margin({ left: StyleConstants.DEFAULT_PIXEL_80 })
.height(StyleConstants.DEFAULT_PIXEL_120)
.width(StyleConstants.DEFAULT_PIXEL_100)
.align(Alignment.End)
}.onClick(() => {
AppStorage.SetOrCreate('ida', this.ida);
AppStorage.SetOrCreate('valueList', this.valueList);
this.dialogController.open();
}).margin({ top: StyleConstants.DEFAULT_PIXEL_10,
bottom: StyleConstants.DEFAULT_PIXEL_10 })
.width(StyleConstants.PERCENTAGE_100)
.height(StyleConstants.DEFAULT_PIXEL_75)
}
}
}
@CustomDialog
@Component
struct SettingsDialog {
controller: CustomDialogController;
action: () => void;
cancel: () => void;
@StorageLink('valueList') valueList: any = [];
@StorageLink('ida') ida: number = 0;
build() {
Column() {
ForEach(this.valueList, (item: any) => {
Row() {
Text(item.name)
.margin({ left: StyleConstants.DEFAULT_PIXEL_10 })
.align(Alignment.Start)
.width(StyleConstants.PERCENTAGE_85)
.fontSize(StyleConstants.DEFAULT_PIXEL_30)
.fontColor(StyleConstants.DEFAULT_DIALOG_FONT_COLOR)
Radio({ value: item.value })
.enabled(false)
.checked(item.checked)
.width(StyleConstants.DEFAULT_PIXEL_30)
.height(StyleConstants.DEFAULT_PIXEL_30)
.onChange((isChecked) => {})
}.width(StyleConstants.PERCENTAGE_100)
.height(StyleConstants.DEFAULT_PIXEL_80)
.onClick(() => {
mSettingsPresenter.changeSettingValue(this.ida, item.name);
mSettingsPresenter.setSettingsValue(this.ida, item.value);
this.controller.close();
this.action();
})
},(item: any) => JSON.stringify(item))
Text($r('app.string.cancel'))
.textAlign(TextAlign.Center)
.height(StyleConstants.DEFAULT_PIXEL_80)
.width(StyleConstants.PERCENTAGE_100)
.fontSize(StyleConstants.DEFAULT_PIXEL_30)
.fontColor(Color.Blue)
.onClick(() => {
this.controller.close();
this.action();
})
}.padding(StyleConstants.DEFAULT_PIXEL_20)
.backgroundColor(StyleConstants.DEFAULT_SETTING_PAGE_COLOR)
.borderRadius(StyleConstants.DEFAULT_PIXEL_30)
}
}

View File

@ -0,0 +1,36 @@
{
"float": [
{
"name": "layout_title_width",
"value": "812vp"
},
{
"name": "layout_title_font_size",
"value": "14vp"
},
{
"name": "top_bar_width",
"value": "812vp"
},
{
"name": "top_bar_font_size",
"value": "20vp"
},
{
"name": "top_bar_icon_size",
"value": "20vp"
},
{
"name": "setting_item_width",
"value": "772vp"
},
{
"name": "setting_item_title_width",
"value": "462vp"
},
{
"name": "setting_item_title_font_size",
"value": "16vp"
}
]
}

View File

@ -13,24 +13,28 @@
"value": "Layout"
},
{
"name": "intoSettings",
"name": "into_settings",
"value": "Launcher settings"
},
{
"name": "layoutStyle",
"name": "layout_style",
"value": "Layout Style"
},
{
"name": "launcherLayout",
"name": "launcher_layout",
"value": "Launcher Layout"
},
{
"name": "recentTasksSetting",
"name": "recent_tasks_setting",
"value": "Recent Tasks Setting"
},
{
"name": "cancel",
"value": "Cancel"
},
{
"name": "gesture_navigation_options",
"value": "Gesture Navigation Options"
}
]
}

View File

@ -9,7 +9,7 @@
"value": "ETS_Empty Feature Ability"
},
{
"name": "intoSettings",
"name": "into_settings",
"value": "Launcher settings"
},
{
@ -17,20 +17,24 @@
"value": "Layout"
},
{
"name": "layoutStyle",
"name": "layout_style",
"value": "Layout Style"
},
{
"name": "launcherLayout",
"name": "launcher_layout",
"value": "Launcher Layout"
},
{
"name": "recentTasksSetting",
"name": "recent_tasks_setting",
"value": "Recent Tasks Setting"
},
{
"name": "cancel",
"value": "Cancel"
},
{
"name": "gesture_navigation_options",
"value": "Gesture Navigation Options"
}
]
}

View File

@ -0,0 +1,36 @@
{
"float": [
{
"name": "layout_title_width",
"value": "468vp"
},
{
"name": "top_bar_width",
"value": "468vp"
},
{
"name": "setting_item_width",
"value": "486vp"
},
{
"name": "setting_item_title_width",
"value": "200vp"
},
{
"name": "layout_title_font_size",
"value": "21vp"
},
{
"name": "top_bar_font_size",
"value": "30vp"
},
{
"name": "setting_item_title_font_size",
"value": "24vp"
},
{
"name": "top_bar_icon_size",
"value": "30vp"
}
]
}

View File

@ -9,7 +9,7 @@
"value": "ETS_Empty Feature Ability"
},
{
"name": "intoSettings",
"name": "into_settings",
"value": "桌面设置"
},
{
@ -17,20 +17,24 @@
"value": "布局"
},
{
"name": "layoutStyle",
"name": "layout_style",
"value": "布局样式"
},
{
"name": "launcherLayout",
"name": "launcher_layout",
"value": "桌面布局"
},
{
"name": "recentTasksSetting",
"name": "recent_tasks_setting",
"value": "最近任务数"
},
{
"name": "cancel",
"value": "取消"
},
{
"name": "gesture_navigation_options",
"value": "手势导航开关"
}
]
}

View File

@ -0,0 +1,18 @@
apply plugin: 'com.huawei.ohos.library'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 8
defaultConfig {
compatibleSdkVersion 8
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
}

View File

@ -0,0 +1,22 @@
{
"app": {
"bundleName": "com.ohos.launcher",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.ohos.launcher",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "smartdock",
"moduleType": "har"
}
}
}

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2021 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 BaseDragHandler from '../../../../../../../common/src/main/ets/default/base/BaseDragHandler';
import StyleConstants from '../../../../../../../common/src/main/ets/default/constants/StyleConstants';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import FeatureConstants from '../common/constants/FeatureConstants';
import SmartDockConstants from '../common/constants/SmartDockConstants';
import SmartDockModel from '../model/SmartDockModel';
import SmartDockStyleConfig from './SmartDockStyleConfig';
/**
* SmartDock DragHandler
*/
export default class SmartDockDragHandler extends BaseDragHandler {
private static sInstance: SmartDockDragHandler;
private mDockCoordinateData = [];
private readonly mSmartDockModel: SmartDockModel;
private readonly mSmartDockStyleConfig: SmartDockStyleConfig;
private mDevice = CommonConstants.DEFAULT_DEVICE_TYPE;
constructor() {
super();
this.mSmartDockModel = SmartDockModel.getInstance();
this.mSmartDockStyleConfig = LayoutConfigManager.getStyleConfig(SmartDockStyleConfig.APP_LIST_STYLE_CONFIG, FeatureConstants.FEATURE_NAME);
console.info('Launcher SmartDockDragHandler constructor!');
}
static getInstance(): SmartDockDragHandler {
if (typeof SmartDockDragHandler.sInstance === 'undefined') {
SmartDockDragHandler.sInstance = new SmartDockDragHandler();
}
console.info('Launcher SmartDockDragHandler getInstance end!');
return SmartDockDragHandler.sInstance;
}
setDragEffectArea(effectArea): void {
console.info('Launcher SmartDockDragHandler setDragEffectArea:' + JSON.stringify(effectArea));
super.setDragEffectArea(effectArea);
this.updateDockParam(effectArea);
}
private updateDockParam(effectArea) {
this.mDockCoordinateData = [];
const dockWidth = effectArea.right - effectArea.left;
const dockData: [] = this.getDragRelativeData();
const dataCount = dockData.length;
console.info('Launcher SmartDock updateDockParam dockWidth: ' + dockWidth + ', dataCount: ' + dataCount);
if (dataCount > 0) {
for (let index = 1; index <= dataCount; index++) {
this.mDockCoordinateData.push(dockWidth / dataCount * index + effectArea.left);
}
} else {
this.mDockCoordinateData.push(dockWidth);
}
console.info('Launcher SmartDock DockCoordinateData: ' + JSON.stringify(this.mDockCoordinateData));
}
protected getDragRelativeData(): any {
const dockData: [] = AppStorage.Get('residentList');
return dockData;
}
protected getItemIndex(event: any): number {
const x = event.touches[0].screenX;
const y = event.touches[0].screenY;
if (x > this.mDragEffectArea.left && x < this.mDragEffectArea.right
&& y > this.mDragEffectArea.top && y < this.mDragEffectArea.bottom) {
for (let index = 0; index < this.mDockCoordinateData.length; index++) {
if (this.mDockCoordinateData[index] > x) {
return index;
}
}
}
return CommonConstants.INVALID_VALUE;
}
protected getItemByIndex(index: number): any {
const dockData: [] = this.getDragRelativeData();
if (index >= 0 && index < dockData.length) {
return dockData[index];
}
return null;
}
protected onDragStart(event: any, itemIndex: number): void {
super.onDragStart(event, itemIndex);
const moveAppX = event.touches[0].screenX;
const moveAppY = event.touches[0].screenY;
console.info('Launcher SmartDock onDragStart itemIndex: ' + itemIndex + ', dragItemInfo: ' + JSON.stringify(this.getDragItemInfo()));
AppStorage.SetOrCreate('overlayPositionX', moveAppX);
AppStorage.SetOrCreate('overlayPositionY', moveAppY);
AppStorage.SetOrCreate('overlayData', {
iconSize: this.mSmartDockStyleConfig.mIconSize,
appInfo: this.getDragItemInfo(),
});
AppStorage.SetOrCreate('withBlur', false);
AppStorage.SetOrCreate('overlayMode', CommonConstants.OVERLAY_TYPE_APP_ICON);
}
protected onDragMove(event: any, insertIndex: number, itemIndex: number): void {
super.onDragMove(event, insertIndex, itemIndex);
console.info('Launcher SmartDock onDragMove insertIndex: ' + insertIndex);
const moveAppX = event.touches[0].screenX;
const moveAppY = event.touches[0].screenY;
AppStorage.SetOrCreate('overlayPositionX', moveAppX - (this.mSmartDockStyleConfig.mIconSize/2));
AppStorage.SetOrCreate('overlayPositionY', moveAppY - (this.mSmartDockStyleConfig.mIconSize/2));
}
protected onDragDrop(event: any, insertIndex: number, itemIndex: number): boolean {
this.mDevice = AppStorage.Get('dockDevice');
super.onDragDrop(event, insertIndex, itemIndex);
console.info('Launcher SmartDock onDragDrop insertIndex: ' + insertIndex);
AppStorage.SetOrCreate('overlayMode', CommonConstants.OVERLAY_TYPE_HIDE);
let isDragSuccess = true;
if (this.mIsInEffectArea) {
if (this.isSelfDrag()) {
this.layoutAdjustment(insertIndex, itemIndex);
isDragSuccess = true;
} else if (this.mDevice == CommonConstants.DEFAULT_DEVICE_TYPE) {
const dragItemInfo = this.getDragItemInfo();
console.info('Launcher SmartDock onDragDrop addItem: ' + JSON.stringify(dragItemInfo));
isDragSuccess = this.addItemToSmartDock(dragItemInfo, insertIndex);
}
}
return isDragSuccess;
}
protected onDragEnd(isSuccess: boolean): void {
this.mDevice = AppStorage.Get('dockDevice');
super.onDragEnd(isSuccess);
console.info('Launcher SmartDock onDragEnd isSuccess: ' + isSuccess);
if (this.mDevice == CommonConstants.DEFAULT_DEVICE_TYPE && this.isDropOutSide() && isSuccess) {
console.info('Launcher SmartDock onDragEnd remove item');
const dragItemInfo = this.getDragItemInfo();
this.mSmartDockModel.deleteDockItem(dragItemInfo, SmartDockConstants.RESIDENT_DOCK_TYPE);
}
}
private layoutAdjustment(insertIndex: number, itemIndex: number): void {
this.mSmartDockModel.inserItemToIndex(insertIndex, itemIndex);
}
private addItemToSmartDock(dragItemInfo: any, insertIndex: number): boolean {
this.mSmartDockModel.addToSmartdock(dragItemInfo, insertIndex);
return true;
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 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 BaseModulePreLoader from '../../../../../../../common/src/main/ets/default/base/BaseModulePreLoader';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import SmartDockLayoutConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/SmartDockLayoutConfig';
import SmartDockModeConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/SmartDockModeConfig';
import SmartDockStyleConfig from './SmartDockStyleConfig';
/**
* dock初始化加载器
*/
class SmartDockPreLoader extends BaseModulePreLoader {
protected loadConfig(): void {
LayoutConfigManager.addConfigToManager(SmartDockLayoutConfig.getInstance());
LayoutConfigManager.addConfigToManager(SmartDockModeConfig.getInstance());
LayoutConfigManager.addConfigToManager(SmartDockStyleConfig.getInstance());
}
protected loadData(): void {
}
releaseConfigAndData(): void {
LayoutConfigManager.removeConfigFromManager();
}
}
const smartDockPreLoader: BaseModulePreLoader = new SmartDockPreLoader();
export default smartDockPreLoader;

View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2021 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 AppListStyleConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/AppListStyleConfig';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import FeatureConstants from '../common/constants/FeatureConstants';
/**
* Dock样式配置类
*/
export default class SmartDockStyleConfig extends AppListStyleConfig {
private static sFeatureInstance: SmartDockStyleConfig;
/**
* dock列表高度
*/
mDockHeight = 78;
/**
* dock列表背景色
*/
mBackgroundColor = '#85FAFAFA';
/**
* dock列表圆角值
*/
mDockRadius = 22;
/**
* dock列表背景模糊度
*/
mBackdropBlur = 0;
/**
* dock列表padding
*/
mDockPadding = 9;
/**
* dock列表margin
*/
mDockMargin = 10;
/**
*
*/
mListItemWidth = 60;
/**
*
*/
mListItemHeight = 60;
/**
*
*/
mListItemGap = 2;
/**
*
*/
mListDirection: Axis = Axis.Horizontal;
/**
*
*/
mNameDisplaySide = true;
/**
*
*/
mWithAppName = false;
/**
*
*/
mIconSize = 54;
/**
*
*/
mItemPadding = 3;
/**
*
*/
mItemBackgroundColor = '';
/**
*
*/
mItemBorderRadius = 0;
/**
*
*/
mDockGap = 12;
/**
*
*/
mMaxDockNum = 16;
/**
*
*/
mMaxRecentNum = 3;
mMarginBottom = 24;
protected constructor() {
super();
}
/**
* dock样式实例
*/
static getInstance() {
if (typeof(SmartDockStyleConfig.sFeatureInstance) === 'undefined') {
SmartDockStyleConfig.sFeatureInstance = new SmartDockStyleConfig();
SmartDockStyleConfig.sFeatureInstance.initConfig();
console.info('Launcher SmartDockStyleConfig getInstance end!');
}
return SmartDockStyleConfig.sFeatureInstance;
}
getConfigLevel(): string {
return CommonConstants.LAYOUT_CONFIG_LEVEL_FEATURE;
}
getFeatureName() {
return FeatureConstants.FEATURE_NAME;
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2021 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.
*/
export default class FeatureConstants {
static readonly FEATURE_NAME = 'featureSmartDock';
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 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.
*/
export default class SmartDockConstants {
static readonly LIST_DIRECTION: Axis = Axis.Horizontal;
static readonly PERCENTAGE_100 = '100%';
/**
* residentList type docklist
*/
static readonly RESIDENT_DOCK_TYPE = 0;
/**
* recentdock type docklist
*/
static readonly RECENT_DOCK_TYPE = 1;
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2021 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 SmartDockContent from '../../../../../../../common/src/main/ets/default/uicomponents/SmartDockContent.ets';
import UninstallDialog from '../../../../../../../common/src/main/ets/default/uicomponents/UninstallDialog.ets';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import SmartDockConstants from '../common/constants/SmartDockConstants';
import SmartDockViewModel from '../viewmodel/SmartDockViewModel';
@Component
export default struct SmartDock {
@State device: string = 'phone';
@State popup: {
show: boolean,
showItem: string,
popup: PopupOption | CustomPopupOption
} = { show: false, showItem: '', popup: null };
showAppCenter: () => void
@StorageLink('showDock') showDock: boolean = false;
@StorageLink('residentList') residentList: any = [];
@StorageLink('recentList') recentList: any = [];
@StorageLink('missionInfoList') missionInfoList: any = [];
private mSmartDockViewModel: SmartDockViewModel;
private mSelectedItem = null;
private mSelectedDockType = 0;
private aboutToAppear(): void {
console.info("Launcher SmartDock aboutToAppear start!");
AppStorage.SetOrCreate('dockDevice', this.device);
this.mSmartDockViewModel = SmartDockViewModel.getInstance();
this.mSmartDockViewModel.setShowAppCenter(this.showAppCenter);
console.info("Launcher SmartDock aboutToAppear end!");
}
private aboutToDisappear() {
console.info("Launcher SmartDock aboutToDisappear!");
}
private mDialogController: CustomDialogController = new CustomDialogController({
builder: UninstallDialog({
cancel: () => {
this.mDialogController.close()
},
confirm: () => {
this.onConfirm()
},
dialogName: this.device === CommonConstants.PAD_DEVICE_TYPE ? $r('app.string.delete_app') : $r('app.string.uninstall'),
dialogContent: this.mSelectedItem.appName + ' ?',
}),
cancel: () => {
},
autoCancel: true,
customStyle: true
});
onConfirm() {
if (this.mSelectedItem == null || this.mSelectedDockType == null) {
console.info("Launcher click menu item null");
return;
}
if (this.device === CommonConstants.PAD_DEVICE_TYPE) {
this.mSmartDockViewModel.deleteDockItem(this.mSelectedItem, this.mSelectedDockType);
} else {
this.mSmartDockViewModel.uninstallApp(this.mSelectedItem.bundleName, this.mSelectedItem.bundleName.isUninstallAble);
}
this.mDialogController.close();
}
showDialog() {
this.mSelectedItem = this.mSmartDockViewModel.getSelectedItem();
this.mSelectedDockType = this.mSmartDockViewModel.getSelectedDockType();
this.mDialogController.open();
}
async onHoverEvent(onHover, bundleName) {
if (!onHover) {
this.popup = { show: false, showItem: '', popup: null };
return;
}
let list = this.missionInfoList.filter(it => it.bundleName == bundleName);
if (list.length <= 0) {
AppStorage.SetOrCreate("shapshotList", []);
AppStorage.SetOrCreate('snapShotWidth', 0);
this.popup = { show: false, showItem: '', popup: null };
return;
}
this.popup = {
show: true,
showItem: bundleName,
popup: {
builder: null,
placement: Placement.Top,
enableArrow: true
}
}
let dataList = await this.mSmartDockViewModel.getSnapshot(list[0].missionInfoList, list[0].appName);
}
build() {
List({ space: this.mSmartDockViewModel.getStyleConfig().mDockGap }) {
ListItem() {
SmartDockContent({
dockItemList: $residentList,
mMaxNum: this.mSmartDockViewModel.getStyleConfig().mMaxDockNum,
mSmartDockStyleConfig: this.mSmartDockViewModel.getStyleConfig(),
onItemClick: (event, item) => this.mSmartDockViewModel.residentOnClick(event, item, this.showAppCenter),
buildMenu: ((item) => this.mSmartDockViewModel.buildMenuInfoList(item, SmartDockConstants.RESIDENT_DOCK_TYPE, this.showDialog.bind(this))).bind(this.mSmartDockViewModel),
onItemTouch: (event) => this.mSmartDockViewModel.residentOnTouch(event),
onDockListChangeFunc: () => this.mSmartDockViewModel.onDockListChange(),
onTouchEventUpdateFunc: () => this.mSmartDockViewModel.onTouchEventUpdate()
})
}
ListItem() {
SmartDockContent({
dockItemList: $recentList,
mMaxNum: this.mSmartDockViewModel.getStyleConfig().mMaxRecentNum,
mSmartDockStyleConfig: this.mSmartDockViewModel.getStyleConfig(),
onItemClick: (event, item) => this.mSmartDockViewModel.recentOnClick(event, item, () => this.recentOnClickWithPopup(item)),
buildMenu: ((item) => this.mSmartDockViewModel.buildMenuInfoList(item, SmartDockConstants.RECENT_DOCK_TYPE, this.showDialog.bind(this))).bind(this.mSmartDockViewModel),
onItemTouch: (event) => {},
onDockListChangeFunc: () => this.mSmartDockViewModel.onDockListChange(),
onTouchEventUpdateFunc: () => {},
popup: this.popup,
onHoverEvent: (onHover, bundleName) => this.onHoverEvent(onHover, bundleName)
})
}
}
.height(SmartDockConstants.PERCENTAGE_100)
.listDirection(SmartDockConstants.LIST_DIRECTION)
}
recentOnClickWithPopup(item){
this.onHoverEvent(true, item.bundleName);
AppStorage.SetOrCreate('recentShowPopup', true);
}
}

View File

@ -0,0 +1,439 @@
/*
* Copyright (c) 2021 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 Prompt from '@ohos.prompt';
import missionManager from '@ohos.application.missionManager';
import launcherAbilityManager from '../../../../../../../common/src/main/ets/default/manager/LauncherAbilityManager';
import MissionInfo from '../../../../../../../common/src/main/ets/default/bean/MissionInfo';
import amsMissionManager from '../../../../../../../common/src/main/ets/default/manager/AmsMissionManager';
import SmartDockLayoutConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/SmartDockLayoutConfig';
import layoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import localEventManager from '../../../../../../../common/src/main/ets/default/manager/LocalEventManager';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import StyleConstants from '../../../../../../../common/src/main/ets/default/constants/StyleConstants';
import ResourceManager from '../../../../../../../common/src/main/ets/default/manager/ResourceManager';
import EventConstants from '../../../../../../../common/src/main/ets/default/constants/EventConstants';
import CheckEmptyUtils from '../../../../../../../common/src/main/ets/default/utils/CheckEmptyUtils';
import RecentBundleMissionInfo from '../../../../../../../common/src/main/ets/default/bean/RecentBundleMissionInfo';
import DockItemInfo from '../../../../../../../common/src/main/ets/default/bean/DockItemInfo';
import AppItemInfo from '../../../../../../../common/src/main/ets/default/bean/AppItemInfo';
import AppModel from '../../../../../../../common/src/main/ets/default/model/AppModel';
import SmartDockConstants from '../common/constants/SmartDockConstants';
import FeatureConstants from '../common/constants/FeatureConstants';
import SmartDockStyleConfig from '../common/SmartDockStyleConfig';
const KEY_NAME = 'name';
/**
* SmartDock Model
*/
export default class SmartDockModel {
private static sSmartDockModel: SmartDockModel;
private readonly mSmartDockLayoutConfig: SmartDockLayoutConfig;
private readonly mSmartDockStyleConfig: SmartDockStyleConfig;
private mResidentList: DockItemInfo[] = new Array<DockItemInfo>();
private mRecentDataList: RecentBundleMissionInfo[] = new Array<RecentBundleMissionInfo>();
private readonly mDevice = CommonConstants.DEFAULT_DEVICE_TYPE;
private readonly mResourceManager: ResourceManager;
protected mAppModel: AppModel;
private constructor() {
this.mSmartDockLayoutConfig = layoutConfigManager.getFunctionConfig(SmartDockLayoutConfig.SMART_DOCK_LAYOUT_INFO);
this.mSmartDockStyleConfig = layoutConfigManager.getStyleConfig(SmartDockStyleConfig.APP_LIST_STYLE_CONFIG, FeatureConstants.FEATURE_NAME);
this.mAppModel = AppModel.getInstance();
this.mResourceManager = ResourceManager.getInstance();
this.registerDockListener();
this.getResidentList().then(()=>{}, ()=>{});
this.mDevice = AppStorage.Get('dockDevice');
console.info('Launcher SmartDockModel dockDevice:' + this.mDevice);
if (this.mDevice === CommonConstants.PAD_DEVICE_TYPE) {
this.getRecentDataList().then(()=>{}, ()=>{});
this.registerMissionListener();
}
console.info('Launcher SmartDockModel constructor!');
}
static getInstance(): SmartDockModel{
if (typeof SmartDockModel.sSmartDockModel === 'undefined') {
SmartDockModel.sSmartDockModel = new SmartDockModel();
}
console.info('Launcher SmartDockModel getInstance!');
return SmartDockModel.sSmartDockModel;
}
/**
* get resident dock list
*/
async getResidentList(): Promise<void> {
const residentList = new Array<DockItemInfo>();
const dockDataList = this.mSmartDockLayoutConfig.getDockLayoutInfo();
console.info('Launcher SmartDockModel getResidentList from config length:' + dockDataList.length);
for (let i = 0; i < dockDataList.length; i++) {
if (dockDataList[i].itemType == CommonConstants.TYPE_APP) {
console.info('Launcher SmartDockModel getResidentList dockDataList[i].bundleName:' + dockDataList[i].bundleName);
const appData = await launcherAbilityManager.getAppInfoByBundleName(dockDataList[i].bundleName);
if (appData == undefined) {
continue;
}
const dockItemInfo = new DockItemInfo();
dockItemInfo.itemType = dockDataList[i].itemType;
dockItemInfo.editable = dockDataList[i].editable;
dockItemInfo.appName = typeof(appData) === 'undefined' ? dockDataList[i].appName : appData.appName;
dockItemInfo.bundleName = typeof(appData) === 'undefined' ? dockDataList[i].bundleName : appData.bundleName;
dockItemInfo.abilityName = typeof(appData) === 'undefined' ? dockItemInfo.abilityName : appData.abilityName;
dockItemInfo.appIconId = typeof(appData) === 'undefined' ? dockItemInfo.appIconId : appData.appIconId;
dockItemInfo.appLabelId = typeof(appData) === 'undefined' ? dockItemInfo.appLabelId : appData.appLabelId;
residentList.push(dockItemInfo);
} else if (dockDataList[i].itemType == CommonConstants.TYPE_CARD) {
} else {
const dockItemInfo = new DockItemInfo();
dockItemInfo.itemType = dockDataList[i].itemType;
dockItemInfo.editable = dockDataList[i].editable;
dockItemInfo.bundleName = dockDataList[i].bundleName;
dockItemInfo.abilityName = dockDataList[i].abilityName;
dockItemInfo.appIconId = typeof(dockDataList[i].appIconId) != 'undefined' ? dockDataList[i].appIconId : dockDataList[i].iconId.id;
dockItemInfo.appLabelId = typeof(dockDataList[i].appLabelId) != 'undefined' ? dockDataList[i].appLabelId : dockDataList[i].labelId.id;
const loadAppName = await this.mResourceManager
.getAppNameSync(dockItemInfo.appLabelId, dockItemInfo.bundleName, '');
dockItemInfo.appName = loadAppName;
residentList.push(dockItemInfo);
}
}
// update persistent data
this.mSmartDockLayoutConfig.updateDockLayoutInfo(residentList);
// trigger component update
AppStorage.SetOrCreate('residentList', residentList);
console.info('Launcher SmartDockModel getResidentList end residentList.length:' + residentList.length);
}
/**
* get recent dock list
*/
async getRecentDataList() {
console.info('Launcher SmartDockModel getRecentDataList start!');
const recentList = await amsMissionManager.getRecentBundleMissionsList();
if (CheckEmptyUtils.isEmptyArr(recentList)) {
console.info('Launcher SmartDockModel getRecentDataList empty');
AppStorage.SetOrCreate('recentList', recentList);
return;
}
let recents: RecentBundleMissionInfo[] = [];
const missionInfos: {
appName: string,
bundleName: string,
missionInfoList: MissionInfo[]
}[] = [];
recentList.forEach(item => {
missionInfos.push({
appName: item.appName,
bundleName: item.bundleName,
missionInfoList: item.missionInfoList
});
item.missionInfoList = [];
recents.push(item);
});
if (recents.length > this.mSmartDockStyleConfig.mMaxRecentNum) {
recents = recents.slice(0, this.mSmartDockStyleConfig.mMaxRecentNum);
}
AppStorage.SetOrCreate('recentList', recents);
AppStorage.SetOrCreate('missionInfoList', missionInfos);
console.info('Launcher SmartDockModel getRecentDataList end, recentList.length:' + recents.length);
}
/**
* delete app from smartdock
* @param appInfo
* @param dockType
*/
deleteDockItem(appInfo: AppItemInfo, dockType: number) {
let bundleName = appInfo.bundleName;
if (CheckEmptyUtils.checkStrIsEmpty(bundleName)) {
return;
}
if (dockType === SmartDockConstants.RESIDENT_DOCK_TYPE) {
this.mResidentList = AppStorage.Get('residentList');
const residentLength = this.mResidentList.length;
for (let i = 0; i < residentLength; i++) {
if (this.mResidentList[i].bundleName === bundleName) {
// checkt right to delete
let editable = true;
editable = this.mResidentList[i].editable;
if (!editable) {
Prompt.showToast({
message: $r('app.string.disable_add_to_delete')
});
return;
} else {
this.mResidentList.splice(i, 1);
AppStorage.SetOrCreate('residentList', this.mResidentList);
this.mSmartDockLayoutConfig.updateDockLayoutInfo(this.mResidentList);
console.info('Launcher SmartDockModel deleteDockItem:' + bundleName + ',dockType:' + dockType);
return;
}
}
}
} else if (dockType === SmartDockConstants.RECENT_DOCK_TYPE) {
this.mRecentDataList = AppStorage.Get('recentList');
const recentLength = this.mRecentDataList.length;
for (let i = 0; i < recentLength; i++) {
if (this.mRecentDataList[i].bundleName === bundleName)
this.mRecentDataList.splice(i, 1);
AppStorage.SetOrCreate('recentList', this.mRecentDataList);
console.info('Launcher SmartDockModel deleteDockItem:' + bundleName + ',dockType:' + dockType);
}
return;
}
}
/**
* add appItem to smartdock
*
* @param appInfo
* @param index
*/
addToSmartdock(appInfo: AppItemInfo, index?: number) {
this.mResidentList = AppStorage.Get('residentList');
const dockItemCount = this.mResidentList.length;
if (this.checkDockNum(dockItemCount)) {
return;
}
const flag = this.idDuplicate(this.mResidentList, appInfo);
if (flag) {
const dockItemInfo = new DockItemInfo();
dockItemInfo.itemType = CommonConstants.TYPE_APP;
dockItemInfo.editable = true;
dockItemInfo.appId = appInfo.appId;
dockItemInfo.appName = appInfo.appName;
dockItemInfo.bundleName = appInfo.bundleName;
dockItemInfo.abilityName = appInfo.abilityName;
dockItemInfo.appIconId = appInfo.appIconId;
dockItemInfo.appLabelId = appInfo.appLabelId;
if (dockItemCount == 0 || index == undefined || index >= dockItemCount || index < 0) {
this.mResidentList.push(dockItemInfo);
} else {
this.mResidentList.splice(index, 0, dockItemInfo);
}
AppStorage.SetOrCreate('residentList', this.mResidentList);
this.mSmartDockLayoutConfig.updateDockLayoutInfo(this.mResidentList);
console.info('Launcher SmartDockModel addToSmartdock appInfo:' + appInfo.bundleName);
}
}
/**
* check docklist over max num or not
* @param dockItemCount
* @return true: over max
* @return false: editable
*/
private checkDockNum(dockItemCount: number): boolean{
if (dockItemCount >= this.mSmartDockStyleConfig.mMaxDockNum) {
Prompt.showToast({
message: $r('app.string.no_space_for_add')
});
return true;
}
return false;
}
/**
* check app exist in list
* @param list
* @param appInfo
* @return true: not exit, editable
* @return false: exited
*/
private idDuplicate(list: AppItemInfo[], appInfo: AppItemInfo): boolean{
for (let i = 0; i < list.length; i++) {
if (list[i].bundleName === appInfo.bundleName) {
Prompt.showToast({
message: $r('app.string.duplicate_add')
});
return false;
}
}
return true;
}
/**
* send requset to add appItem to pageDesktop
* @param appInfo
*/
addToPageDesk(appInfo: DockItemInfo) {
if (appInfo.itemType == CommonConstants.TYPE_APP) {
localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, appInfo).then(()=>{}, ()=>{});
} else {
Prompt.showToast({
message: $r('app.string.disable_add_to_dock')
});
}
}
/**
* move appItem from itemIndex to insertIndex
* @param insertIndex
* @param itemIndex
*/
inserItemToIndex(insertIndex: number, itemIndex: number) {
if ((insertIndex == 0 || insertIndex == 1 || itemIndex == 0 || itemIndex == 1) && this.mDevice === CommonConstants.PAD_DEVICE_TYPE) {
Prompt.showToast({
message: $r('app.string.disable_to_move')
});
return;
}
this.mResidentList = AppStorage.Get('residentList');
if (itemIndex < insertIndex) {
const selectItem = this.mResidentList[itemIndex];
for (let i = itemIndex; i < insertIndex; i++) {
this.mResidentList[i] = this.mResidentList[i+1];
}
this.mResidentList[insertIndex] = selectItem;
}
if (itemIndex > insertIndex) {
const selectItem = this.mResidentList[itemIndex];
for (let i = itemIndex; i > insertIndex; i--) {
this.mResidentList[i] = this.mResidentList[i-1];
}
this.mResidentList[insertIndex] = selectItem;
}
AppStorage.SetOrCreate('residentList', this.mResidentList);
this.mSmartDockLayoutConfig.updateDockLayoutInfo(this.mResidentList);
}
/**
* register residentList dock ADD ITEM Listener
* local listener for model to model send and receive msg
*/
registerDockListener() {
localEventManager.registerEventListener(this.mAddToDockListener, [
EventConstants.EVENT_REQUEST_DOCK_ITEM_ADD,
EventConstants.EVENT_REQUEST_RESIDENT_DOCK_ITEM_DELETE,
EventConstants.EVENT_REQUEST_RECENT_DOCK_ITEM_DELETE
]);
console.info('Launcher SmartDockModel local listener on create');
}
/**
* unregister residentList dock ADD ITEM Listener
*/
unregisterDockListener() {
localEventManager.unregisterEventListener(this.mAddToDockListener);
console.info('Launcher SmartDockModel local listener on destroy');
}
/**
* resident local Listener
*/
private readonly mAddToDockListener = {
onReceiveEvent: (event: string, params: AppItemInfo) => {
console.info('Launcher SmartDock receive event: ' + event + ', params: ' + JSON.stringify(params));
if (event === EventConstants.EVENT_REQUEST_DOCK_ITEM_ADD) {
this.addToSmartdock(params);
} else if (event === EventConstants.EVENT_REQUEST_RESIDENT_DOCK_ITEM_DELETE) {
this.deleteDockItem(params, SmartDockConstants.RESIDENT_DOCK_TYPE);
} else if (event === EventConstants.EVENT_REQUEST_RECENT_DOCK_ITEM_DELETE) {
this.deleteDockItem(params, SmartDockConstants.RECENT_DOCK_TYPE);
}
}
};
private registerMissionListener() {
console.log('Launcher SmartDockModel registerMissionListener');
const listener = {
onMissionCreated: this.onMissionCreatedCallback.bind(this),
onMissionDestroyed: this.onMissionDestroyedCallback.bind(this),
onMissionSnapshotChanged: this.onMissionSnapshotChangedCallback.bind(this),
onMissionMovedToFront: this.onMissionMovedToFrontCallback.bind(this)
};
missionManager.registerMissionListener(listener);
}
onMissionCreatedCallback(missionId: number) {
console.log('Launcher SmartDockModel onMissionCreatedCallback, missionId=' + missionId);
this.getRecentDataList().then(()=>{}, ()=>{});
}
onMissionDestroyedCallback(missionId: number) {
console.log('Launcher SmartDockModel onMissionDestroyedCallback, missionId=' + missionId);
this.getRecentDataList().then(()=>{}, ()=>{});
}
onMissionSnapshotChangedCallback(missionId: number) {
console.log('Launcher SmartDockModel onMissionSnapshotChangedCallback, missionId=' + missionId);
this.getRecentDataList().then(()=>{}, ()=>{});
}
onMissionMovedToFrontCallback(missionId: number) {
console.log('Launcher SmartDockModel onMissionMovedToFrontCallback, missionId=' + missionId);
this.getRecentDataList().then(()=>{}, ()=>{});
}
/**
* bundleName获取shortcutInfo
* @param bundleName
*/
getShortcutInfo(bundleName: string) {
return this.mAppModel.getShortcutInfo(bundleName);
}
/**
* @param cacheKey
*
* @return cache
*/
getAppName(cacheKey: string) {
return this.mResourceManager.getAppResourceCache(cacheKey, KEY_NAME);
}
async getSnapshot(missionIds: MissionInfo[], name: string) {
const snapshotList: {
name: string,
image: any,
missionId: number,
boxSize: number,
bundleName: string,
left?: number,
right?: number,
}[] = [];
let snapShotWidth = 0;
for (const item of missionIds) {
let pixelMap = {
name: '',
left: StyleConstants.DEFAULT_12,
missionId: -1,
image: $r('app.media.icon'),
boxSize: StyleConstants.DEFAULT_SMART_DOCK_MISSION_IMAGE_HEIGHT,
bundleName: ''
};
const snapshotMap = await missionManager.getMissionSnapShot('', item.missionId);
pixelMap.image = snapshotMap.snapshot;
pixelMap.missionId = item.missionId;
pixelMap.bundleName = snapshotMap.ability.bundleName;
const imageInfo = await snapshotMap.snapshot.getImageInfo();
pixelMap.boxSize = Math.ceil(StyleConstants.DEFAULT_SMART_DOCK_MISSION_IMAGE_HEIGHT / imageInfo.size.height * imageInfo.size.width);
pixelMap.name = name;
pixelMap.left = StyleConstants.DEFAULT_12;
snapshotList.push(pixelMap);
snapShotWidth += pixelMap.boxSize + pixelMap.left;
}
AppStorage.SetOrCreate('shapshotList', snapshotList);
AppStorage.SetOrCreate('snapShotWidth', snapShotWidth);
return snapshotList;
}
}

View File

@ -0,0 +1,301 @@
/*
* Copyright (c) 2021 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 Prompt from '@ohos.prompt';
import CheckEmptyUtils from '../../../../../../../common/src/main/ets/default/utils/CheckEmptyUtils';
import MenuInfo from '../../../../../../../common/src/main/ets/default/bean/MenuInfo';
import MissionInfo from '../../../../../../../common/src/main/ets/default/bean/MissionInfo';
import BaseAppPresenter from '../../../../../../../common/src/main/ets/default/base/BaseAppPresenter';
import CommonConstants from '../../../../../../../common/src/main/ets/default/constants/CommonConstants';
import LayoutConfigManager from '../../../../../../../common/src/main/ets/default/layoutconfig/LayoutConfigManager';
import launcherAbilityManager from '../../../../../../../common/src/main/ets/default/manager/LauncherAbilityManager';
import amsMissionManager from '../../../../../../../common/src/main/ets/default/manager/AmsMissionManager';
import SmartDockLayoutConfig from '../../../../../../../common/src/main/ets/default/layoutconfig/SmartDockLayoutConfig';
import SmartDockStyleConfig from '../common/SmartDockStyleConfig';
import SmartDockConstants from '../common/constants/SmartDockConstants';
import FeatureConstants from '../common/constants/FeatureConstants';
import SmartDockDragHandler from '../common/SmartDockDragHandler';
import SmartDockModel from '../model/SmartDockModel';
import Trace from '../../../../../../../common/src/main/ets/default/utils/Trace';
import AppItemInfo from '../../../../../../../common/src/main/ets/default/bean/AppItemInfo';
import DockItemInfo from '../../../../../../../common/src/main/ets/default/bean/DockItemInfo';
/**
* SmartDock Viewmodel
*/
export default class SmartDockViewModel extends BaseAppPresenter {
private static sSmartDockViewModel: SmartDockViewModel;
private readonly mSmartDockLayoutConfig: SmartDockLayoutConfig;
private readonly mSmartDockStyleConfig: SmartDockStyleConfig;
private readonly mSmartDockDragHandler: SmartDockDragHandler;
private readonly mSmartDockModel: SmartDockModel;
private mShowAppCenter: Function;
private mSelectedItem: DockItemInfo;
private mSelectedDockType = 0;
private mDevice = CommonConstants.DEFAULT_DEVICE_TYPE;
constructor() {
super();
this.mSmartDockLayoutConfig = LayoutConfigManager.getFunctionConfig(SmartDockLayoutConfig.SMART_DOCK_LAYOUT_INFO);
this.mSmartDockStyleConfig = LayoutConfigManager.getStyleConfig(SmartDockStyleConfig.APP_LIST_STYLE_CONFIG, FeatureConstants.FEATURE_NAME);
this.mSmartDockDragHandler = SmartDockDragHandler.getInstance();
this.mSmartDockModel = SmartDockModel.getInstance();
console.info('Launcher SmartDockViewModel constructor!');
}
static getInstance(): SmartDockViewModel{
if (typeof(SmartDockViewModel.sSmartDockViewModel) === 'undefined') {
SmartDockViewModel.sSmartDockViewModel = new SmartDockViewModel();
}
console.info('Launcher SmartDockViewModel getInstance!');
return SmartDockViewModel.sSmartDockViewModel;
}
/**
* get SmartDockStyleConfig
*/
getStyleConfig(): SmartDockStyleConfig{
return LayoutConfigManager.getStyleConfig(SmartDockStyleConfig.APP_LIST_STYLE_CONFIG, FeatureConstants.FEATURE_NAME);
}
/**
* resident dock item onClick function
* @param event
* @param item
* @param callback
*/
residentOnClick(event, item, callback?) {
// AppCenter entry
if (item.abilityName == CommonConstants.APPCENTER_ABILITY && callback != null) {
callback();
return;
}
if (item.abilityName == CommonConstants.RECENT_ABILITY) {
globalThis.createRecentWindow();
Trace.start(Trace.CORE_METHOD_START_RECENTS);
return;
}
// app entry
launcherAbilityManager.startLauncherAbility(item.abilityName, item.bundleName);
}
/**
* recent dock item onClick function
* @param event
* @param item
*/
public recentOnClick(event, item, callback?) {
let missionInfoList = [];
missionInfoList = AppStorage.Get('missionInfoList');
console.info('Launcher SmartDockViewModel recentOnClick missionInfoList.length:' + missionInfoList.length);
if (!CheckEmptyUtils.isEmptyArr(missionInfoList)) {
for (let i = 0; i < missionInfoList.length; i++) {
if (missionInfoList[i].bundleName === item.bundleName) {
let missionList = missionInfoList[i]?.missionInfoList;
console.info('Launcher SmartDockViewModel recentOnClick missionList.length:' + missionList.length);
if (!CheckEmptyUtils.isEmptyArr(missionList) && missionList.length > 1) {
console.info('Launcher SmartDockViewModel recentOnClick callback');
callback();
} else if (!CheckEmptyUtils.isEmptyArr(missionList) && missionList.length === 1) {
let missionId = missionInfoList[i]?.missionInfoList[0]?.missionId;
amsMissionManager.moveMissionToFront(missionId).then(() => {}, () => {});
}
break;
}
}
}
}
/**
* resident dock item onTouch function
* @param event
*/
residentOnTouch(event) {
console.info('Launcher SmartDockViewModel residentOnTouch event:' + event.type);
this.mSmartDockDragHandler.notifyTouchEventUpdate(event);
}
/**
* what SmartDockContent.dockItemList onChange
*/
onDockListChange() {
console.info('Launcher SmartDockViewModel onDockListChange');
this.updateDockParams().then(()=>{}, ()=>{});
}
/**
* update drag effective area when dockList changed
*/
async updateDockParams() {
const screenWidth: number = AppStorage.Get('screenWidth');
const screenHeight: number = AppStorage.Get('screenHeight');
const systemUiHeght: number = AppStorage.Get('systemUiHeght');
const mResidentWidth: number = this.getListWidth(AppStorage.Get('residentList'));
const mRecentWidth: number = this.getListWidth(AppStorage.Get('recentList'));
if (typeof(this.mSmartDockDragHandler) != 'undefined') {
this.mSmartDockDragHandler.setDragEffectArea({
left: mResidentWidth === 0 ? 0 : (screenWidth - mResidentWidth - this.mSmartDockStyleConfig.mDockGap - mRecentWidth) / 2,
right: mResidentWidth === 0 ? screenWidth : (screenWidth - mResidentWidth - this.mSmartDockStyleConfig.mDockGap - mRecentWidth) / 2 + mResidentWidth,
top: screenHeight - systemUiHeght - this.mSmartDockStyleConfig.mDockHeight - this.mSmartDockStyleConfig.mDockMargin,
bottom: screenHeight - systemUiHeght
});
}
}
/**
* what SmartDockContent.dragLocation onChange
*/
onTouchEventUpdate() {
this.mSmartDockDragHandler.onTouchEventUpdate(AppStorage.Get('dragEvent'));
console.info('Launcher SmartDockViewModel onTouchEventUpdate');
}
/**
* build menu for @Component CustomOverlay
* @param appInfo
* @param dockType
* @param callback
*/
buildMenuInfoList(appInfo, dockType, callback?) {
// TODO 可优化成配置
const menuInfoList = new Array<MenuInfo>();
const shortcutInfo = this.mSmartDockModel.getShortcutInfo(appInfo.bundleName);
if (shortcutInfo) {
let menu = null;
shortcutInfo.forEach((value) => {
menu = new MenuInfo();
menu.menuType = CommonConstants.MENU_TYPE_DYNAMIC;
menu.menuImgSrc = value.icon;
menu.menuText = value.label;
menu.shortcutIconId = value.iconId;
menu.shortcutLabelId = value.labelId;
menu.bundleName = value.bundleName;
menu.onMenuClick = () => {
launcherAbilityManager.startLauncherAbility(value.wants[0].targetClass, value.wants[0].targetBundle);
};
menuInfoList.push(menu);
});
}
if (appInfo.itemType != CommonConstants.TYPE_FUNCTION) {
this.mDevice = AppStorage.Get('dockDevice');
if (this.mDevice === CommonConstants.PAD_DEVICE_TYPE && dockType === SmartDockConstants.RESIDENT_DOCK_TYPE) {
const addToWorkSpaceMenu = new MenuInfo();
addToWorkSpaceMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
addToWorkSpaceMenu.menuImgSrc = '/common/pics/ic_public_copy.svg';
addToWorkSpaceMenu.menuText = $r('app.string.app_center_menu_add_desktop');
addToWorkSpaceMenu.onMenuClick = () => {
console.info('Launcher click menu item add to pageDesk entry');
this.mSmartDockModel.addToPageDesk(appInfo);
};
menuInfoList.push(addToWorkSpaceMenu);
}
const removeMenu = new MenuInfo();
removeMenu.menuType = CommonConstants.MENU_TYPE_FIXED;
removeMenu.menuImgSrc = this.mDevice === CommonConstants.PAD_DEVICE_TYPE ? '/common/pics/ic_public_remove.svg' : '/common/pics/ic_public_delete.svg';
removeMenu.menuText = this.mDevice === CommonConstants.PAD_DEVICE_TYPE ? $r('app.string.delete_app') : $r('app.string.uninstall');
removeMenu.onMenuClick = () => {
console.info('Launcher click menu item remove' + JSON.stringify(appInfo) + ',dockType:' + dockType);
const cacheKey = appInfo.appLabelId + appInfo.bundleName;
const appName = this.mSmartDockModel.getAppName(cacheKey);
console.info('Launcher PageDesktopViewModel buildMenuInfoList appName' + appName);
if (appName != null) {
appInfo.appName = appName;
}
this.mSelectedItem = appInfo;
this.mSelectedDockType = dockType;
callback();
};
removeMenu.menuEnabled = appInfo.isUninstallAble;
menuInfoList.push(removeMenu);
}
return menuInfoList;
}
setShowAppCenter(showAppCenter: Function) {
this.mShowAppCenter = showAppCenter;
}
deleteDockItem(appItemInfo: DockItemInfo, dockType: number) {
this.mSmartDockModel.deleteDockItem(appItemInfo, dockType);
}
getSelectedItem(): any {
console.info('Launcher getSelectedItem' + JSON.stringify(this.mSelectedItem));
return this.mSelectedItem;
}
getSelectedDockType(): any {
console.info('Launcher getSelectedDockType' + JSON.stringify(this.mSelectedDockType));
return this.mSelectedDockType;
}
/**
* calcaulate dock list width after list change
* @param itemList
*/
private getListWidth(itemList): number {
let width = 0;
if (typeof itemList === 'undefined' || itemList == null || itemList.length === 0) {
return width;
} else {
const num = itemList.length;
width = this.mSmartDockStyleConfig.mDockPadding * 2 + num * (this.mSmartDockStyleConfig.mListItemWidth) + (num - 1) * (this.mSmartDockStyleConfig.mListItemGap);
}
return width;
}
/**
* The application uninstallation result is displayed.
*
* @param resultCode: Application uninstallation result
*/
informUninstallResult(resultCode) {
console.info('Launcher SmartDockViewModel informUninstallResult resultCode = ' + resultCode);
if (resultCode === CommonConstants.UNINSTALL_FORBID) {
Prompt.showToast({
message: $r('app.string.disable_uninstall')
});
} else if (resultCode === CommonConstants.UNINSTALL_SUCCESS) {
Prompt.showToast({
message: $r('app.string.uninstall_success')
});
} else {
Prompt.showToast({
message: $r('app.string.uninstall_failed')
});
}
}
/**
* get shapshot
*
* @param missionIds missionid list
* @return snapshot list
*/
async getSnapshot(missionIds: MissionInfo[], name: string) {
const snapshotList: {
name: string,
image: any,
missionId: number,
boxSize: number,
bundleName: string,
left?: number,
right?: number,
}[] = await this.mSmartDockModel.getSnapshot(missionIds, name);
return snapshotList;
}
}

View File

@ -0,0 +1,12 @@
{
"string": [
{
"name": "app_name",
"value": "SmartDock"
},
{
"name": "mainability_description",
"value": "JS_Phone_Empty Feature Ability"
}
]
}