diff --git a/common/index.ets b/common/index.ets index 29c43d02ad614f0bfd188f9f5e7c12b71918564c..d4dcf2ca800dcc2ba709737c9a1cecfbc5d8abb0 100644 --- a/common/index.ets +++ b/common/index.ets @@ -88,13 +88,12 @@ export { DragItemPosition } from './src/main/ets/default/base/DragItemPosition' // Window scene export { SCBRootSceneSession } from './src/main/ets/WindowScene/scene/session/SCBRootSceneSession' -export { SCBSceneInfo } from './src/main/ets/WindowScene/scene/session/SCBSceneInfo' +export { SCBSceneInfo, SCBSceneMode } from './src/main/ets/WindowScene/scene/session/SCBSceneInfo' export { SCBDividerParam } from './src/main/ets/WindowScene/scene/session/SCBDividerParam' -export { SCBSceneSession } from './src/main/ets/WindowScene/scene/session/SCBSceneSession' +export { SCBSceneSession, SCBSessionCbType, SCBSessionRect } from './src/main/ets/WindowScene/scene/session/SCBSceneSession' export { SCBSpecificSession } from './src/main/ets/WindowScene/scene/session/SCBSpecificSession' -export { SCBSceneSessionManager, SCBSpecificSceneSessionList } from './src/main/ets/WindowScene/scene/session/SCBSceneSessionManager' +export { SCBSceneSessionManager, SCBSpecificSceneSessionList, SCBEventId } from './src/main/ets/WindowScene/scene/session/SCBSceneSessionManager' export { SCBScreenSession, SCBScreenProperty } from './src/main/ets/WindowScene/screen/session/SCBScreenSession' export { SCBSceneContainerSession } from './src/main/ets/WindowScene/scene/session/SCBSceneContainerSession' export { SCBSceneContainerSessionArray } from './src/main/ets/WindowScene/scene/session/SCBSceneContainerSession' -export { SCBGestureModel, SceneState } from './src/main/ets/WindowScene/common/SCBGestureModel' export { SCBGestureActionId, SCBGestureActionOption, SCBGestureAction } from './src/main/ets/WindowScene/common/SCBGestureAction' \ No newline at end of file diff --git a/common/src/main/ets/WindowScene/common/SCBGestureAction.ts b/common/src/main/ets/WindowScene/common/SCBGestureAction.ts index b62bf6db34030e4531bba6f61c15b57cb575f6f1..17969b2658222c690f9127efe72d24c85e7d3139 100644 --- a/common/src/main/ets/WindowScene/common/SCBGestureAction.ts +++ b/common/src/main/ets/WindowScene/common/SCBGestureAction.ts @@ -19,24 +19,14 @@ import { Log } from '../../default/utils/Log' const TAG = 'SCBGestureAction' export enum SCBGestureActionId { - HOME, - FULLSCENE, - ENTER_SPLIT, - EXIT_SPILT, - ENTER_RECENT, - SLIDE_UP_BEGIN, - SLIDING_UP, - SLIDE_UP_END, + NONE, DESTROY_IN_RECENT, - EXIT_SPLIT + EXIT_SPLIT, }; export interface SCBGestureActionOption { id: number; - destroyLen?: number; screenId?: number; - gestureOffsetX?: number; - gestureOffsetY?: number; sessionId?: number; } /** @@ -44,22 +34,14 @@ export interface SCBGestureActionOption { */ @Observed export class SCBGestureAction { - readonly actionId: number = SCBGestureActionId.HOME; + readonly actionId: number = SCBGestureActionId.NONE; readonly screenId: number; - readonly gestureOffsetX: number = 0; - readonly gestureOffsetY: number = 0; readonly sessionId: number = -1; constructor(options: SCBGestureActionOption) { this.actionId = options.id; if (options.screenId) { this.screenId = options.screenId; } - if (options.gestureOffsetX) { - this.gestureOffsetX = options.gestureOffsetX; - } - if (options.gestureOffsetY) { - this.gestureOffsetY = options.gestureOffsetY; - } if (options.sessionId) { this.sessionId = options.sessionId; } diff --git a/common/src/main/ets/WindowScene/common/SCBGestureModel.ts b/common/src/main/ets/WindowScene/common/SCBGestureModel.ts deleted file mode 100644 index 5a270669e435275dc2550ba8d6e3784c2815039c..0000000000000000000000000000000000000000 --- a/common/src/main/ets/WindowScene/common/SCBGestureModel.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2023 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 screenSessionManager from '@ohos.screenSessionManager' -import { SCBSceneSession } from '../scene/session/SCBSceneSession' -import { SCBSceneContainerSession } from '../scene/session/SCBSceneContainerSession' -import { Log } from '../../default/utils/Log' -import { SCBSceneInfo } from '../scene/session/SCBSceneInfo' -import { SCBDividerParam } from '../scene/session/SCBDividerParam' - -const TAG = 'SCBGestureModel' - -export enum SceneState { - HOME, - FULLSCENE, - SPLIT, - SLIDING_UP, - RECENT -} -/** - * Manage info of gesture - */ -@Observed -export class SCBGestureModel { - - sceneState: SceneState = SceneState.HOME; - - flexWidth: number | string = '100%'; - - flexHeight: number | string = '100%'; - - flexPadding: number = 0; - - flexOffsetX: number = 0; - - flexOffsetY: number = 0; - - multiViewShow: boolean = false; - - enableScroll: boolean = true; - - /** - * Constructor. - * @param session Session of the screen - */ - constructor() { - } - - public updateSceneState(state: SceneState) { - Log.showInfo(TAG, `updateSceneState from ${this.sceneState} to ${state}`); - this.sceneState = state; - } - /** - * init properties of all container or scene - */ - public initAll() { - this.flexWidth = "100%"; - this.flexHeight = "100%"; - this.flexPadding = 0; - this.flexOffsetX = 0; - this.flexOffsetY = 0; - this.multiViewShow = false; - } -} diff --git a/common/src/main/ets/WindowScene/scene/session/SCBRootSceneSession.ts b/common/src/main/ets/WindowScene/scene/session/SCBRootSceneSession.ts index 8fd78f8b16c3634d43fa5bc23ed133f41c812e59..f57b9832ded86e05cfc62bac7fb9174ec64d61c0 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBRootSceneSession.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBRootSceneSession.ts @@ -44,6 +44,6 @@ export class SCBRootSceneSession { private onPendingSceneSessionActivation(sceneInfo: sceneSessionManager.SceneInfo): void { let info = new SCBSceneInfo(sceneInfo.bundleName, sceneInfo.abilityName); - SCBSceneSessionManager.getInstance().startScene(info); + SCBSceneSessionManager.getInstance().startSceneFromIcon(info); } } diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSceneContainerSession.ts b/common/src/main/ets/WindowScene/scene/session/SCBSceneContainerSession.ts index 65f94050a656fd79bb48b3499196766246f65da6..83f309f7a7200ac5eedf6e82438aacd531e5c1a4 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBSceneContainerSession.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBSceneContainerSession.ts @@ -13,13 +13,11 @@ * limitations under the License. */ -import screenSessionManager from '@ohos.screenSessionManager' import { SCBSceneSession } from './SCBSceneSession' import { SCBDividerParam } from './SCBDividerParam' import { SCBScreenProperty } from './../../screen/session/SCBScreenSession' - import { Log } from '../../../default/utils/Log' - +import { SCBSceneMode } from './SCBSceneInfo' const TAG = 'SCBSceneContainerSession' @Observed @@ -116,11 +114,11 @@ export class SCBSceneContainerSession { public requestActivation() { if (this.isActive) { - Log.showWarn(TAG, 'The scene is already active.'); + Log.showWarn(TAG, 'The scene is already active, containerId: ' + this.containerId); return; } - Log.showInfo(TAG, 'Request scene container session activation, id: ' + this.containerId); + Log.showInfo(TAG, 'Request scene container session activation, containerId: ' + this.containerId); this.isActive = true; this.primarySession && this.primarySession.requestSessionActivation(); if (this.isSplit) { @@ -130,7 +128,7 @@ export class SCBSceneContainerSession { public requestBackground() { if (!this.isActive) { - Log.showError(TAG, 'The scene is already background.'); + Log.showError(TAG, 'The scene is already background, containerId: ' + this.containerId); return; } @@ -162,4 +160,20 @@ export class SCBSceneContainerSession { this.borderRadius = 0; Log.showInfo(TAG, 'id: ' + this.containerId + ' initWidth: ' + this.width + ' initHeight: ' + this.height); } + + public initAll() { + this.init(); + this.dividerParam.init(); + } + + public getContainerWindowMode() : SCBSceneMode { + if (this.primarySession && this.secondarySession) { + return SCBSceneMode.FULLSCREEN; + } else if (this.primarySession) { + return this.primarySession.sceneInfo.sceneMode; + } else if (this.secondarySession) { + return this.secondarySession.sceneInfo.sceneMode; + } + return SCBSceneMode.UNDEFINED; + } } diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSceneInfo.ts b/common/src/main/ets/WindowScene/scene/session/SCBSceneInfo.ts index 476cb36c58579e29b31ff9a97164cde220728804..2275fb973049965e0e06427cc01b03fa5e0d19d9 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBSceneInfo.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBSceneInfo.ts @@ -15,6 +15,15 @@ import { SCBTransitionEffect } from '../../animation/SCBTransitionEffect' +export enum SCBSceneMode { + UNDEFINED = 1, + FULLSCREEN, + PRIMARY, + SECONDARY, + FLOATING +} + +const DEFAULT_SCENE_MODE = SCBSceneMode.FULLSCREEN; /** * Information of a scene. */ @@ -44,8 +53,14 @@ export class SCBSceneInfo { */ transitionEffect: SCBTransitionEffect = SCBTransitionEffect.DEFAULT; + /** + * SceneMode, default is undefined + */ + sceneMode: SCBSceneMode = SCBSceneMode.UNDEFINED; + constructor(bundleName: string, abilityName: string) { this.bundleName = bundleName; this.abilityName = abilityName; + this.sceneMode = DEFAULT_SCENE_MODE; } } diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts b/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts index 724386d231e7aab6de167b1d45a417481df84dd2..aa4f8837d530c3d3e05941ebb5bdec891059b6a1 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBSceneSession.ts @@ -21,6 +21,29 @@ import { SCBTransitionEffect } from '../../animation/SCBTransitionEffect' const TAG = 'SCBSceneSession' +export enum SCBSessionCbType { + RECOVER, +}; + +@Observed +export class SCBSessionRect { + left: number = 0; + + top: number = 0; + + width: number | string = '100%'; + + height: number | string = '100%'; + + copy() { + let tmpRect = new SCBSessionRect(); + tmpRect.left = this.left; + tmpRect.top = this.top; + tmpRect.width = this.width; + tmpRect.height = this.height; + return tmpRect; + } +} /** * Session of a scene. */ @@ -33,12 +56,15 @@ export class SCBSceneSession { translateY: number = 0; scaleX: number = 1; scaleY: number = 1; + lastRect: SCBSessionRect = new SCBSessionRect(); + currRect: SCBSessionRect = new SCBSessionRect(); sessionState: sceneSessionManager.SessionState; sessionRectChangeCallback: Function; createSubSessionCallback: Function; subSessionStateChangeCallback: Function; subSessionList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); + callbackMap: Map = new Map(); /** * Constructor. @@ -48,7 +74,7 @@ export class SCBSceneSession { constructor(session: sceneSessionManager.SceneSession, sceneInfo: SCBSceneInfo) { this.sceneInfo = sceneInfo; this.session = session; - this.session.on('pendingSceneSessionActivation', (info) => { + this.session.on('pendingSceneSessionActivation', (info) => { // need add mode this.onPendingSceneSessionActivation(info); }) @@ -67,13 +93,17 @@ export class SCBSceneSession { this.subSessionStateChangeCallback = callback; } + public on(cbType: SCBSessionCbType, callback: Function) { + this.callbackMap.set(cbType, callback); + } + private onPendingSceneSessionActivation(sceneInfo: sceneSessionManager.SceneInfo) { let toSceneInfo = new SCBSceneInfo(sceneInfo.bundleName, sceneInfo.abilityName); toSceneInfo.screenId = this.sceneInfo.screenId; toSceneInfo.transitionEffect = SCBTransitionEffect.APPEAR_FROM_SCENE; this.sceneInfo.transitionEffect = SCBTransitionEffect.DISAPPEAR_FROM_SCENE; - - SCBSceneSessionManager.getInstance().startScene(toSceneInfo); + // need add scene transition + SCBSceneSessionManager.getInstance().startSceneFromIcon(toSceneInfo); } public async requestSessionActivation(): Promise { @@ -109,4 +139,12 @@ export class SCBSceneSession { Log.showDebug(TAG, `onSessionStageChange, state: ${state}`); this.sessionState = state; } + + private onRecover(lastRect: SCBSessionRect) { + if (!this.callbackMap.has(SCBSessionCbType.RECOVER)) { + Log.showError(TAG, `no recover callback exists!`); + return; + } + this.callbackMap.get(SCBSessionCbType.RECOVER)(lastRect); + } } diff --git a/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts b/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts index d105d99655870773b0b26fbeb357fc744c1f36cf..0538fbe1fb90748c58139fdb5fba119f3ef68252 100644 --- a/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts +++ b/common/src/main/ets/WindowScene/scene/session/SCBSceneSessionManager.ts @@ -23,6 +23,20 @@ import { Log } from '../../../default/utils/Log' const TAG = 'SCBSceneSessionManager'; +export enum SCBEventId { + START_SCENE_FROM_ICON, + START_SCENE_FROM_RECENT, + START_SCENE_FROM_OTHER, + START_SCENE_TRANSITION, + BACK_SCENE_TRANSITION, + DESTROY_SCENE, + MINIMIZE_SCENE, + MAXIMIZE_SCENE, + CLOSE_SCENE, + ACTIVATE_SCENE, + BACKGROUND_SCENE, +}; + @Observed export class SCBSpecificSceneSessionList extends Array { } @@ -32,11 +46,8 @@ export class SCBSpecificSceneSessionList extends Array { */ export class SCBSceneSessionManager { private rootSceneSession: SCBRootSceneSession; - private startSceneFuncMap: Map = new Map(); - private backgroundSceneFuncMap: Map = new Map(); - private destroySceneFuncMap: Map = new Map(); - private activateSceneFuncMap: Map = new Map(); private createSpecificSceneCallback: Function; // callback of create system specific session + private callbackMap: Map> = new Map(); public mainScreenId: number = -1; private constructor() { @@ -81,139 +92,151 @@ export class SCBSceneSessionManager { this.rootSceneSession.loadContent(path, context); } - public registerStartSceneCallback(screenId:number, callback: Function): void { - if (this.startSceneFuncMap.has(screenId)) { - Log.showError(TAG, `StartSceneFunc alreay exists with screenId: ${screenId}`); + public on(eventId: number, screenId:number, callback: Function): void { + if (!this.callbackMap.has(eventId)) { + Log.showWarn(TAG, `callbackType: ${eventId} not exists!`); + this.callbackMap.set(eventId, new Map()); + } + let eventFuncMap = this.callbackMap.get(eventId); + if (eventFuncMap.get(screenId)) { + Log.showError(TAG, `screenId: ${screenId} with callbackType: ${eventId} alreay exists.`); return; } - Log.showInfo(TAG, `Register StartSceneFunc with screenId: ${screenId}`); - this.startSceneFuncMap.set(screenId, callback); + Log.showInfo(TAG, `Register func type:${eventId} with screenId: ${screenId} success.`); + eventFuncMap.set(screenId, callback); } - public unRegisterSceneCallback(screenId: number): void { - if (!this.startSceneFuncMap.has(screenId)) { - Log.showError(TAG, `Failed to find startSceneFunc with screenId: ${screenId}`); - return; - } - this.startSceneFuncMap.delete(screenId); - this.backgroundSceneFuncMap.delete(screenId); - this.destroySceneFuncMap.delete(screenId); - this.activateSceneFuncMap.delete(screenId); + public registerCreateSpecificSceneCallback(callback: Function) { + Log.showDebug(TAG, `registerCreateSpecificSceneCallback`); + this.createSpecificSceneCallback = callback; } - public registerActivateSceneCallback(screenId:number, callback: Function): void { - if (this.activateSceneFuncMap.has(screenId)) { - Log.showError(TAG, `ActivateSceneFunc alreay exists with screenId: ${screenId}`); - return; - } - this.activateSceneFuncMap.set(screenId, callback); + /** + * StartSceneFromIcon. + * @param sceneInfo The info of the scene which to be activated + */ + + public startSceneFromIcon(sceneInfo: SCBSceneInfo) { + Log.showInfo(TAG, 'startSceneFromIcon:' + JSON.stringify(sceneInfo)); + this.executeStartSceneCallback(SCBEventId.START_SCENE_FROM_ICON, sceneInfo.screenId, sceneInfo); } - public registerBackgroundSceneCallback(screenId:number, callback: Function): void { - if (this.backgroundSceneFuncMap.has(screenId)) { - Log.showError(TAG, `BackgroundSceneFunc alreay exists with screenId: ${screenId}`); - return; - } - this.backgroundSceneFuncMap.set(screenId, callback); + /** + * StartSceneFromRecent + * @param sceneContainerSession The session of the scene container which to be destroyed. + */ + public startSceneFromRecent(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `startSceneFromRecent, persistentId:${persistentId} containerId:${containerId}`); + this.executeCallback(SCBEventId.START_SCENE_FROM_RECENT, screenId, persistentId, containerId); } - public registerDestroySceneCallback(screenId:number, callback: Function): void { - if (this.destroySceneFuncMap.has(screenId)) { - Log.showError(TAG, `DestroySceneFunc alreay exists with screenId: ${screenId}`); - return; - } - this.destroySceneFuncMap.set(screenId, callback); + /** + * StartSceneFromOther. + * @param sceneInfo The info of the scene which to be activated + */ + + public startSceneFromOther(sceneInfo: SCBSceneInfo) { + Log.showInfo(TAG, 'startSceneFromOther:' + JSON.stringify(sceneInfo)); + this.executeStartSceneCallback(SCBEventId.START_SCENE_FROM_OTHER, sceneInfo.screenId, sceneInfo); } - public registerCreateSpecificSceneCallback(callback: Function) { - Log.showDebug(TAG, `registerCreateSpecificSceneCallback`); - this.createSpecificSceneCallback = callback; + /** + * StartSceneTransition. + * @param sceneInfo The info of the scene which to be activated + */ + + public startSceneTransition(toInfo: SCBSceneInfo, fromInfo: SCBSceneInfo) { + Log.showInfo(TAG, 'startSceneTransition:' + JSON.stringify(toInfo)); + this.executeStartSceneCallback(SCBEventId.START_SCENE_TRANSITION, toInfo.screenId, toInfo, fromInfo); } /** - * Start a scene. + * BackSceneTransition. * @param sceneInfo The info of the scene which to be activated */ - public startScene(sceneInfo: SCBSceneInfo) { - Log.showInfo(TAG, 'start scene:' + ' bundle:' + sceneInfo.bundleName + ' ability:' + sceneInfo.abilityName + - ' screenId:' + sceneInfo.screenId + ' isNewInstance:' + sceneInfo.isNewInstance); - if (this.startSceneFuncMap.size == 0) { - Log.showError(TAG, 'No start scene func from scenePanel has registered!'); - return; - } - let screenId = -1; - if (sceneInfo.screenId === -1) { - screenId = this.mainScreenId; - } else { - screenId = sceneInfo.screenId; - } - if (!this.startSceneFuncMap.has(screenId)) { - Log.showError(TAG, `No start scene func has registered screenId: ${this.mainScreenId}!`); - return; - } - Log.showInfo(TAG, `Start scene on screen with screenId: ${screenId}!`); - this.startSceneFuncMap.get(screenId)(sceneInfo); + + public backSceneTransition(toInfo: SCBSceneInfo, fromInfo: SCBSceneInfo) { + Log.showInfo(TAG, 'backSceneTransition:' + JSON.stringify(toInfo)); + this.executeStartSceneCallback(SCBEventId.BACK_SCENE_TRANSITION, toInfo.screenId, toInfo, fromInfo); } /** * Request the scene container session activation. * @param sceneContainerSession The session of the scene container which to be activated. */ - public requestSceneContainerActivation(screenId: number, containerId: number) { - if (this.activateSceneFuncMap.size == 0) { - Log.showError(TAG, 'No activate scene func from scenePanel has registered!'); - return; - }; - if (screenId === -1) { - screenId = this.mainScreenId; - } - if (!this.activateSceneFuncMap.has(screenId)) { - Log.showError(TAG, 'No activate scene func has registered screenId: ${this.mainScreenId}!`'); - return; - } - Log.showInfo(TAG, `activate scene: ${containerId} on screen with screenId: ${screenId}!`); - this.activateSceneFuncMap.get(screenId)(containerId); + public requestSceneContainerActivation(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `requestSceneContainerActivation, persistentId:${persistentId} containerId:${containerId}`); + this.executeCallback(SCBEventId.ACTIVATE_SCENE, screenId, persistentId, containerId); } /** * Request the scene container session background. * @param sceneContainerSession The session of the scene container which to be background. */ - // todo: change with emitter - public requestSceneContainerBackground(screenId: number, containerId: number) { - if (this.backgroundSceneFuncMap.size == 0) { - Log.showError(TAG, 'No background scene func from scenePanel has registered!'); - return; - }; - if (screenId === -1) { - screenId = this.mainScreenId; - } - if (!this.backgroundSceneFuncMap.has(screenId)) { - Log.showError(TAG, 'No background scene func has registered screenId: ${this.mainScreenId}!`'); - return; - } - Log.showInfo(TAG, `background scene on screen with screenId: ${screenId}!`); - this.backgroundSceneFuncMap.get(screenId)(containerId); + public requestSceneContainerBackground(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `requestSceneContainerBackground, persistentId:${persistentId} containerId:${containerId}`); + this.executeCallback(SCBEventId.BACKGROUND_SCENE, screenId, persistentId, containerId); } /** * Request the scene container session destruction. * @param sceneContainerSession The session of the scene container which to be destroyed. */ - public requestSceneContainerDestruction(screenId: number, containerId: number) { - if (this.destroySceneFuncMap.size == 0) { - Log.showError(TAG, 'No destroy scene func from scenePanel has registered!'); + public requestSceneContainerDestruction(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `requestSceneContainerDestruction, persistentId:${persistentId} containerId:${containerId}`); + this.executeCallback(SCBEventId.DESTROY_SCENE, screenId, persistentId, containerId); + } + + public minimize(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `minimize, persistentId:${persistentId} containerId:${containerId}`); + this.executeCallback(SCBEventId.MINIMIZE_SCENE, screenId, persistentId, containerId); + } + + /** + * Maximize sceneSession + * @param sceneContainerSession The session of the scene container which to be destroyed. + */ + public maximize(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `minimize, persistentId:${persistentId} containerId:${containerId}`); + this.executeCallback(SCBEventId.MAXIMIZE_SCENE, screenId, persistentId, containerId); + } + + /** + * Close sceneSession + * @param sceneContainerSession The session of the scene container which to be destroyed. + */ + public close(screenId: number, persistentId?: number, containerId?: number) { + Log.showInfo(TAG, 'Request scene container session close, persistentId: ' + persistentId); + this.executeCallback(SCBEventId.CLOSE_SCENE, screenId, persistentId, containerId) + } + + private executeCallback(eventId: SCBEventId, screenId:number, persistentId?: number, containerId?: number) { + if (!this.callbackMap.has(eventId)) { + Log.showError(TAG, `No scene func: ${eventId} has registered!`); + return; + } + let sceneFuncMap = this.callbackMap.get(eventId); + screenId = (screenId === -1) ? this.mainScreenId : screenId; + if (!sceneFuncMap.has(screenId)) { + Log.showError(TAG, `No scene func: ${eventId} has registered screenId: ${this.mainScreenId}!`); + return; + } + sceneFuncMap.get(screenId)(persistentId, containerId); + } + + private executeStartSceneCallback(eventId: SCBEventId, screenId:number, + toInfo: SCBSceneInfo, fromInfo?: SCBSceneInfo) { + if (!this.callbackMap.has(eventId)) { + Log.showError(TAG, `No start scene func eventId:${eventId} has registered!`); return; - }; - Log.showInfo(TAG, 'Request scene container session destruction, id: ' + containerId); - if (screenId === -1) { - screenId = this.mainScreenId; } - if (!this.destroySceneFuncMap.has(screenId)) { - Log.showError(TAG, 'No destroy scene func has registered screenId: ${this.mainScreenId}!`'); + let startSceneFuncMap = this.callbackMap.get(eventId); + screenId = (toInfo.screenId === -1) ? this.mainScreenId : toInfo.screenId; + if (!startSceneFuncMap.has(screenId)) { + Log.showError(TAG, `No start scene func: ${eventId} has registered screenId: ${this.mainScreenId}!`); return; } - Log.showInfo(TAG, `Destroy scene on screen with screenId: ${screenId}!`); - this.destroySceneFuncMap.get(screenId)(containerId); + Log.showInfo(TAG, `Start scene on screen with screenId: ${screenId}!`); + startSceneFuncMap.get(screenId)(toInfo, fromInfo); } } diff --git a/common/src/main/ets/default/constants/StyleConstants.ts b/common/src/main/ets/default/constants/StyleConstants.ts index a560e8269446402e11cb92e94538d761e39269ce..26c3c39f424ba4a28b725ead68a4235c8c9f4770 100644 --- a/common/src/main/ets/default/constants/StyleConstants.ts +++ b/common/src/main/ets/default/constants/StyleConstants.ts @@ -178,9 +178,11 @@ export class StyleConstants { static readonly DPI_RATIO = 1; // gesture model - static readonly GESTURE_KEY = 'gestureModel' static readonly RECENT_MARGIN = 50 // recent static readonly RECENT_SCALE = 0.7 + + // blur + static readonly BLUR_RADIUS_20 = 20 } \ No newline at end of file diff --git a/common/src/main/ets/default/manager/LauncherAbilityManager.ts b/common/src/main/ets/default/manager/LauncherAbilityManager.ts index 50fab10e52329de207acc481181a6309df6bc3c5..48d25d9951fddee6da736b673da5ab7b9db18161 100644 --- a/common/src/main/ets/default/manager/LauncherAbilityManager.ts +++ b/common/src/main/ets/default/manager/LauncherAbilityManager.ts @@ -279,7 +279,7 @@ class LauncherAbilityManager { // }); let sceneInfo = new SCBSceneInfo(paramBundleName, paramAbilityName) - SCBSceneSessionManager.getInstance().startScene(sceneInfo) + SCBSceneSessionManager.getInstance().startSceneFromIcon(sceneInfo) const sysEventInfo = { domain: 'LAUNCHER_APP', diff --git a/product/phone/package-lock.json b/product/phone/package-lock.json index b93a1b79929f7ae9f7466f59fd2404e9c91cf728..996ca121152d465924e0c47e0e50b1bb9ad0629e 100644 --- a/product/phone/package-lock.json +++ b/product/phone/package-lock.json @@ -1,5 +1,5 @@ { - "name": "launcher", + "name": "sceneboard", "version": "1.0.0", "lockfileVersion": 1, "requires": true, diff --git a/product/phone/src/main/ets/SceneBoard/SCBDivider.ets b/product/phone/src/main/ets/SceneBoard/SCBDivider.ets index b9db02deb7566d5b547232f8d209b9ef0dcdad17..068b5be6802b0846a51bcf886f168a0721dbbf6a 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBDivider.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBDivider.ets @@ -76,7 +76,7 @@ export struct SCBDivider { Log.showInfo(TAG, "exit primarySession with ratio: " + heightRatio) this.dividerParam.init() let action = new SCBGestureAction({ - id: SCBGestureActionId.EXIT_SPILT, + id: SCBGestureActionId.EXIT_SPLIT, sessionId: this.sceneContainerSession.primarySession.session.persistentId, }); this.onGestureChange && this.onGestureChange(action); @@ -84,7 +84,7 @@ export struct SCBDivider { this.dividerParam.init() Log.showInfo(TAG, "exit secondarySession with ratio: " + heightRatio) let action = new SCBGestureAction({ - id: SCBGestureActionId.EXIT_SPILT, + id: SCBGestureActionId.EXIT_SPLIT, sessionId: this.sceneContainerSession.secondarySession.session.persistentId, }); this.onGestureChange && this.onGestureChange(action); diff --git a/product/phone/src/main/ets/SceneBoard/SCBGestureNavBar.ets b/product/phone/src/main/ets/SceneBoard/SCBGestureNavBar.ets index c00908d3afa6abe6ae7e7a8778a4a55270b16606..9a8c866fea8ed37a86f88bfbf38eef683864646a 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBGestureNavBar.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBGestureNavBar.ets @@ -13,19 +13,10 @@ * limitations under the License. */ -import { SCBGestureModel ,SCBSceneContainerSessionArray} from '@ohos/common'; -import { SCBSceneSessionManager } from '@ohos/common'; -import { SCBGestureAction, SCBGestureActionId} from '@ohos/common'; -import { Log, Trace } from '@ohos/common'; -import { StyleConstants } from '@ohos/common'; - const TAG = 'SCBGestureNavBar'; @Component export struct SCBGestureNavBar { - @ObjectLink containerSessionList: SCBSceneContainerSessionArray; - @StorageLink('gestureModel') gestureModel: SCBGestureModel = new SCBGestureModel(); - onGestureChange: Function; build() { // Gesture navigation bar Stack({ alignContent: Alignment.Center }) { @@ -38,59 +29,5 @@ export struct SCBGestureNavBar { .width('100%') .height('3%') .opacity(0) - .gesture(PanGesture() - .onActionStart((event: GestureEvent) => { - let action = new SCBGestureAction({ - id: SCBGestureActionId.SLIDE_UP_BEGIN - }); - this.onGestureChange && this.onGestureChange(action); - }) - .onActionUpdate((event: GestureEvent) => { - let action = new SCBGestureAction({ - id: SCBGestureActionId.SLIDING_UP, - gestureOffsetX: event.offsetX, - gestureOffsetY: event.offsetY - }); - this.onGestureChange && this.onGestureChange(action); - }) - .onActionEnd((event: GestureEvent) => { - const index = this.containerSessionList.findIndex((item) => { - return item.isActive === true; - }); - if (index === -1) { - Log.showError(TAG, 'Failed to find active scene container session.'); - return null; - } - let activeSceneContainerSession = this.containerSessionList[index]; - var action; - if (event.offsetY < -400) { - SCBSceneSessionManager.getInstance().requestSceneContainerBackground(activeSceneContainerSession.screenProperty.screenId, activeSceneContainerSession.containerId); - action = new SCBGestureAction({ - id: SCBGestureActionId.HOME - }); - } else if (event.offsetY < -200) { - activeSceneContainerSession.dividerParam.primaryH = ((100 - StyleConstants.DIVIDER_HEIGHT / activeSceneContainerSession.screenProperty.height * 100) / 2) + '%'; - if (!activeSceneContainerSession.isSplit) { - activeSceneContainerSession.isSplit = true; - action = new SCBGestureAction({ - id: SCBGestureActionId.ENTER_SPLIT - }); - } else { - action = new SCBGestureAction({ - id: SCBGestureActionId.ENTER_RECENT - }); - } - } else if (event.offsetY < -100) { - action = new SCBGestureAction({ - id: SCBGestureActionId.ENTER_RECENT - }); - } else { - action = new SCBGestureAction({ - id: SCBGestureActionId.FULLSCENE - }); - SCBSceneSessionManager.getInstance().requestSceneContainerActivation(activeSceneContainerSession.screenProperty.screenId, activeSceneContainerSession.containerId); - } - this.onGestureChange && this.onGestureChange(action); - })) } } diff --git a/product/phone/src/main/ets/SceneBoard/SCBScene.ets b/product/phone/src/main/ets/SceneBoard/SCBScene.ets index c48bf823b417ca13963ae7c69b28e6efcf7c1481..e698fca482fbf1e671cd13c4bf4b6d1ce2802f1e 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBScene.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBScene.ets @@ -13,11 +13,10 @@ * limitations under the License. */ - -import sceneSessionManager from '@ohos.sceneSessionManager' -import { SCBSceneSession, SCBDividerParam, SceneState, SCBGestureModel } from '@ohos/common' +import { SCBSceneSession, SCBDividerParam, SCBSessionCbType, SCBSessionRect } from '@ohos/common' import { SCBGestureActionId, SCBGestureAction } from '@ohos/common' import { StyleConstants } from '@ohos/common' +import { ScenePanelState } from './SCBScenePanel'; import { Log } from '@ohos/common' const TAG = 'SCBScene' @@ -26,7 +25,7 @@ const TAG = 'SCBScene' export struct SCBScene { @ObjectLink sceneSession: SCBSceneSession @Link dividerParam: SCBDividerParam - @StorageLink('gestureModel') gestureModel: SCBGestureModel = new SCBGestureModel() + @Link scenePanelState: ScenePanelState; onGestureChange: Function; onCreateSubSession: Function; onSubSessionChange: Function; @@ -51,71 +50,70 @@ export struct SCBScene { return true; } - enableShow() { - if (this.sceneSession && this.sceneSession.isActive) { - return true; - } - if (this.sceneSession && (this.gestureModel.sceneState === SceneState.SLIDING_UP || this.gestureModel.sceneState === SceneState.RECENT)) { - return true; - } - Log.showInfo(TAG, 'enable show is false'); - return false; + onRecover(lastRect: SCBSessionRect) { + Log.showInfo(TAG, 'SCBScene onRecover'); + let tmp = this.sceneSession.currRect.copy(); + this.sceneSession.currRect = this.sceneSession.lastRect.copy(); + this.sceneSession.lastRect = tmp.copy(); } aboutToAppear() { + Log.showDebug(TAG, "aboutToAppear " + 'SCBScene: ' + this.sceneSession?.sceneInfo.bundleName + ' id: ' + this.sceneSession?.session.persistentId) // registerCreateSubSessionCallback this.sceneSession?.registerCreateSubSessionCallback(this.onCreateSubSession); // registerSubSessionActiveStatueChangeCallback this.sceneSession?.registerSubSessionActiveStatueChangeCallback(this.onSubSessionChange); + this.sceneSession.on(SCBSessionCbType.RECOVER, (lastRect: SCBSessionRect)=>{ + this.onRecover(lastRect); + }); + } + aboutToDisappear() { + Log.showDebug(TAG, "aboutToDisappear " + 'SCBScene: ' + this.sceneSession?.sceneInfo.bundleName + ' id: ' + this.sceneSession?.session.persistentId) } - build() { - if (this.enableShow()) { - Stack() { - if (this.buildLog(this.sceneSession)) { - } - HostWindowScene(this.sceneSession?.session.persistentId) - .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - if (this.gestureModel?.sceneState === SceneState.RECENT) { - Stack() { - } - .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - .priorityGesture( - GestureGroup(GestureMode.Sequence, - LongPressGesture({ repeat: true }) - .onAction((event: GestureEvent) => { - if (this.buildLog3()) { - } - }) - .onActionEnd(() => { - this.gestureModel.enableScroll = false - }), - PanGesture({ direction: PanDirection.Horizontal }) // when screen is vertical, use Vertical - .onActionStart((event: GestureEvent) => { - }) - .onActionUpdate((event: GestureEvent) => { - this.sceneSession.translateX = event.offsetX; - }) - .onActionEnd((event: GestureEvent) => { - if (this.buildLog1()) { - } - if (event.offsetX < -200 || event.offsetX > 200) { - let action = new SCBGestureAction({ - id: SCBGestureActionId.EXIT_SPILT, - sessionId: this.sceneSession.session.persistentId - }); - this.onGestureChange && this.onGestureChange(action); - } - this.dividerParam.init(); - this.sceneSession.translateX = 0; - }) - ) - ) + Stack() { + if (this.buildLog(this.sceneSession)) { + } + HostWindowScene(this.sceneSession?.session.persistentId) + .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) + if (this.scenePanelState === ScenePanelState.RECENT) { + Stack() { } + .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) + .priorityGesture( + GestureGroup(GestureMode.Sequence, + LongPressGesture({ repeat: true }) + .onAction((event: GestureEvent) => { + if (this.buildLog3()) { + } + }) + .onActionEnd(() => { + }), + PanGesture({ direction: PanDirection.Horizontal }) // when screen is vertical, use Vertical + .onActionStart((event: GestureEvent) => { + }) + .onActionUpdate((event: GestureEvent) => { + this.sceneSession.translateX = event.offsetX; + }) + .onActionEnd((event: GestureEvent) => { + if (this.buildLog1()) { + } + if (event.offsetX < -200 || event.offsetX > 200) { + let action = new SCBGestureAction({ + id: SCBGestureActionId.EXIT_SPLIT, + sessionId: this.sceneSession.session.persistentId + }); + this.onGestureChange && this.onGestureChange(action); + } + this.dividerParam.init(); + this.sceneSession.translateX = 0; + }) + ) + ) } - .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - .translate({ x: this.sceneSession?.translateX }) } + .size({ width: this.sceneSession?.currRect.width, height: this.sceneSession?.currRect.height }) + .translate({ x: this.sceneSession?.translateX }) } } diff --git a/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets b/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets index 80f844d1b749f87f0096e63db8300cbe5f785d80..fef92be64da8fea793bb6ed2cc08d4f56d8f4183 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBSceneContainer.ets @@ -15,9 +15,9 @@ import curves from '@ohos.curves' import sceneSessionManager from '@ohos.sceneSessionManager' -import { SCBSceneContainerSession, SCBDividerParam, SCBGestureModel, SCBSceneSession } from '@ohos/common' +import { SCBSceneContainerSession, SCBDividerParam, SCBSceneSession } from '@ohos/common' import { SCBSpecificSession, SCBSpecificSceneSessionList } from '@ohos/common' -import { SceneState } from '@ohos/common'; +import { ScenePanelState } from './SCBScenePanel'; import { SCBSceneSessionManager, SCBGestureAction, SCBGestureActionId, SCBScreenProperty } from '@ohos/common'; import { SCBScene } from './SCBScene' import { SCBSpecificScene } from './SCBSpecificScene' @@ -41,17 +41,16 @@ export struct SCBSceneContainer { @ObjectLink sceneContainerSession: SCBSceneContainerSession; @ObjectLink dividerParam: SCBDividerParam; @Link screenProperty: SCBScreenProperty; - @StorageLink('gestureModel') gestureModel: SCBGestureModel = new SCBGestureModel(); + @Link scenePanelState: ScenePanelState; @State priSubList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); @State secSubList: SCBSpecificSceneSessionList = new SCBSpecificSceneSessionList(); - containerIdx : number; onGestureChange: Function; buildLog2() { - Log.showInfo(TAG, " containerIdx: "+ this.containerIdx + " containerId: " + this.sceneContainerSession.containerId + - ' transX: ' + this.sceneContainerSession.translateX + ' transY: ' + this.sceneContainerSession.translateY + ' scaleX: ' - + this.sceneContainerSession.scaleX + ' scaleY: ' + this.sceneContainerSession.scaleY) + Log.showInfo(TAG, " containerId: " + this.sceneContainerSession?.containerId + + ' bundleName1: ' + this.sceneContainerSession?.primarySession?.sceneInfo.bundleName + ' bundleName2: ' + + this.sceneContainerSession?.secondarySession?.sceneInfo.bundleName) return true; } @@ -59,19 +58,6 @@ export struct SCBSceneContainer { return true } - enableShow() { - if (!this.sceneContainerSession) { - return false; - } - if (this.sceneContainerSession && this.sceneContainerSession.isActive) { - return true; - } - if (this.gestureModel.sceneState === SceneState.SLIDING_UP || this.gestureModel.sceneState === SceneState.RECENT) { - return true; - } - return false; - } - onCreateSubSession(sceneSession: SCBSceneSession, specificSession: sceneSessionManager.SceneSession) { var subList; if (this.sceneContainerSession.primarySession && @@ -130,133 +116,135 @@ export struct SCBSceneContainer { } aboutToAppear() { + Log.showDebug(TAG, "aboutToAppear containerId: " + this.sceneContainerSession?.containerId + + ' bundleName1: ' + this.sceneContainerSession?.primarySession?.sceneInfo.bundleName + ' bundleName2: ' + + this.sceneContainerSession?.secondarySession?.sceneInfo.bundleName) this.priSubList = this.sceneContainerSession.primarySession?.subSessionList; this.secSubList = this.sceneContainerSession.secondarySession?.subSessionList; this.onCreateSubSession = this.onCreateSubSession.bind(this); this.onSubSessionActiveStatueChange = this.onSubSessionActiveStatueChange.bind(this); } + aboutToDisappear() { + Log.showDebug(TAG, "aboutToDisappear containerId: " + this.sceneContainerSession?.containerId + + ' bundleName1: ' + this.sceneContainerSession?.primarySession?.sceneInfo.bundleName + ' bundleName2: ' + + this.sceneContainerSession?.secondarySession?.sceneInfo.bundleName) + } build() { - if (this.enableShow()) { - Stack() { - Column() { - if (this.buildLog2()) {} - if (this.sceneContainerSession.primarySession) { - Stack() { - // Scene Session - SCBScene({ - sceneSession: this.sceneContainerSession.primarySession, - dividerParam: $dividerParam, - onGestureChange: this.onGestureChange, - onCreateSubSession: this.onCreateSubSession, - onSubSessionChange: this.onSubSessionActiveStatueChange - }) - .width('100%') - .height(this.dividerParam.primaryH) - .scale({ y: this.dividerParam.primaryScaleY, centerY: 0 }) - .blur(this.dividerParam.blurRadius) - - // Sub SceneSession - ForEach(this.priSubList, (item: SCBSpecificSession) => { - SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty}) - }, (item: SCBSpecificSession) => item.session.persistentId.toString()) - } + Stack() { + Column() { + if (this.buildLog2()) {} + if (this.sceneContainerSession.primarySession) { + Stack() { + // Scene Session + SCBScene({ + sceneSession: this.sceneContainerSession.primarySession, + dividerParam: $dividerParam, + scenePanelState: $scenePanelState, + onGestureChange: this.onGestureChange, + onCreateSubSession: this.onCreateSubSession, + onSubSessionChange: this.onSubSessionActiveStatueChange + }) + .width('100%') + .height(this.dividerParam.primaryH) + .scale({ y: this.dividerParam.primaryScaleY, centerY: 0 }) + .blur(this.dividerParam.blurRadius) + + // Sub SceneSession + ForEach(this.priSubList, (item: SCBSpecificSession) => { + SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty}) + }, (item: SCBSpecificSession) => item.session.persistentId.toString()) } + } - // divider - if (this.sceneContainerSession.isSplit) { - SCBDivider({ dividerParam: $dividerParam, sceneContainerSession: $sceneContainerSession, - screenProperty: $screenProperty, onGestureChange: this.onGestureChange}) - } + // divider + if (this.sceneContainerSession.isSplit) { + SCBDivider({ dividerParam: $dividerParam, sceneContainerSession: $sceneContainerSession, + screenProperty: $screenProperty, onGestureChange: this.onGestureChange}) + } - // When primary Exit - if (this.sceneContainerSession.secondarySession) { - Stack() { - // Scene Session - SCBScene({ - sceneSession: this.sceneContainerSession.secondarySession, - dividerParam: $dividerParam, - onGestureChange: this.onGestureChange, - onCreateSubSession: this.onCreateSubSession, - onSubSessionChange: this.onSubSessionActiveStatueChange - }) - .scale({ y: this.dividerParam.secondaryScaleY, centerY: 0 }) - .blur(this.dividerParam.blurRadius) - .translate({ y: this.dividerParam.secTransY }) - .flexShrink(1) + // When primary Exit + if (this.sceneContainerSession.secondarySession) { + Stack() { + // Scene Session + SCBScene({ + sceneSession: this.sceneContainerSession.secondarySession, + dividerParam: $dividerParam, + scenePanelState: $scenePanelState, + onGestureChange: this.onGestureChange, + onCreateSubSession: this.onCreateSubSession, + onSubSessionChange: this.onSubSessionActiveStatueChange + }) + .scale({ y: this.dividerParam.secondaryScaleY, centerY: 0 }) + .blur(this.dividerParam.blurRadius) + .translate({ y: this.dividerParam.secTransY }) - // Sub SceneSession - ForEach(this.secSubList, (item: SCBSpecificSession) => { - SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty}) - }, (item: SCBSpecificSession) => item.session.persistentId.toString()) - } + + // Sub SceneSession + ForEach(this.secSubList, (item: SCBSpecificSession) => { + SCBSpecificScene({ specificSession: item, screenProperty: $screenProperty}) + }, (item: SCBSpecificSession) => item.session.persistentId.toString()) } + .flexShrink(1) } - .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) + } + .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - if (this.gestureModel?.sceneState === SceneState.RECENT) { - Stack() { - } - .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - .hitTestBehavior(HitTestMode.Transparent) - .onClick(() => { - SCBSceneSessionManager.getInstance().requestSceneContainerActivation(this.screenProperty.screenId, this.sceneContainerSession.containerId); - let action = new SCBGestureAction({ - id: SCBGestureActionId.FULLSCENE - }); - this.onGestureChange && this.onGestureChange(action); + if (this.scenePanelState === ScenePanelState.RECENT) { + Stack() { + } + .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) + .hitTestBehavior(HitTestMode.Transparent) + .onClick(() => { + SCBSceneSessionManager.getInstance().startSceneFromRecent(this.screenProperty.screenId, undefined, + this.sceneContainerSession.containerId); + }) + .parallelGesture( + PanGesture({ direction: PanDirection.Vertical }) + .onActionStart((event: GestureEvent) => { }) - .parallelGesture( - PanGesture({ direction: PanDirection.Vertical }) - .onActionStart((event: GestureEvent) => { - }) - .onActionUpdate((event: GestureEvent) => { - if (event.offsetY < 100) { - this.sceneContainerSession.translateY = event.offsetY; - } - }) - .onActionEnd((event: GestureEvent) => { - var action; - if (event.offsetY < -300) { - SCBSceneSessionManager.getInstance().requestSceneContainerDestruction( - this.screenProperty.screenId, this.sceneContainerSession.containerId); - action = new SCBGestureAction({ - id: SCBGestureActionId.DESTROY_IN_RECENT - }); - } else { - this.sceneContainerSession.translateY = 0; - action = new SCBGestureAction({ - id: SCBGestureActionId.FULLSCENE - }); - } + .onActionUpdate((event: GestureEvent) => { + if (event.offsetY < 100) { + this.sceneContainerSession.translateY = event.offsetY; + } + }) + .onActionEnd((event: GestureEvent) => { + var action; + if (event.offsetY < -300) { + SCBSceneSessionManager.getInstance().requestSceneContainerDestruction( + this.screenProperty.screenId, undefined, this.sceneContainerSession.containerId); + action = new SCBGestureAction({ + id: SCBGestureActionId.DESTROY_IN_RECENT + }); this.onGestureChange && this.onGestureChange(action); - })) - } + } else { + SCBSceneSessionManager.getInstance().requestSceneContainerActivation( + this.screenProperty.screenId, undefined, this.sceneContainerSession.containerId); + } + })) + } - if (this.gestureModel?.sceneState !== SceneState.RECENT - && this.gestureModel?.sceneState !== SceneState.SPLIT) { - Stack({ alignContent: Alignment.Center }) { - Button() - .backgroundColor(Color.Black) - .width('35%') - .height('25%') - } - .position({ y: '97%' }) - .width('100%') - .height('3%') - .hitTestBehavior(HitTestMode.None) + if (this.scenePanelState !== ScenePanelState.RECENT && this.scenePanelState !== ScenePanelState.SPLIT) { + Stack({ alignContent: Alignment.Center }) { + Button() + .backgroundColor(Color.Black) + .width('35%') + .height('25%') } + .position({ y: '97%' }) + .width('100%') + .height('3%') + .hitTestBehavior(HitTestMode.None) } - .id('containerSession' + this.sceneContainerSession.containerId.toString()) - .size({ width: this.sceneContainerSession.width, height: this.sceneContainerSession.height }) - .scale({ - x: this.sceneContainerSession.scaleX, - y: this.sceneContainerSession.scaleY, - centerX: this.sceneContainerSession.centerX, - centerY: this.sceneContainerSession.centerY - }) - .translate({ x: this.sceneContainerSession.translateX, y: this.sceneContainerSession.translateY }) } - + .id('containerSession' + this.sceneContainerSession.containerId.toString()) + .size({ width: this.sceneContainerSession.width, height: this.sceneContainerSession.height }) + .scale({ + x: this.sceneContainerSession.scaleX, + y: this.sceneContainerSession.scaleY, + centerX: this.sceneContainerSession.centerX, + centerY: this.sceneContainerSession.centerY + }) + .translate({ x: this.sceneContainerSession.translateX, y: this.sceneContainerSession.translateY }) } } diff --git a/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets b/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets index 7b01f49858b4e7b7ecb7f68f7ff3297f09272967..353705a39cd82125cdafc6dd5c762406baf12049 100644 --- a/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets +++ b/product/phone/src/main/ets/SceneBoard/SCBScenePanel.ets @@ -14,64 +14,68 @@ */ import { SCBScreenProperty }from '@ohos/common'; -import { SceneState, SCBGestureModel, SCBSceneContainerSessionArray} from '@ohos/common'; -import { SCBSceneContainerSession, SCBSceneInfo } from '@ohos/common'; -import { SCBSceneSessionManager, SCBSceneSession } from '@ohos/common'; +import { SCBSceneContainerSessionArray} from '@ohos/common'; +import { SCBSceneContainerSession, SCBSceneInfo, SCBSceneMode } from '@ohos/common'; +import { SCBSceneSessionManager, SCBSceneSession, SCBEventId } from '@ohos/common'; import { SCBGestureActionId, SCBGestureAction } from '@ohos/common'; import { SCBSceneContainer } from './SCBSceneContainer'; import { Log, Trace } from '@ohos/common'; import { StyleConstants } from '@ohos/common'; import { SCBGestureNavBar } from './SCBGestureNavBar' import sceneSessionManager from '@ohos.sceneSessionManager' + const TAG = 'SCBScenePanel'; +let enableSplit = false; + +export enum ScenePanelState { + HOME, + FULLSCENE, + SPLIT, + SLIDING_UP, + RECENT +} + +export class SCBViewParam { + flexWidth: number | string = '100%'; + flexHeight: number | string = '100%'; + flexPadding: number = 0; + flexOffsetX: number = 0; + flexOffsetY: number = 0; + constructor() { + } + + /** + * init properties of scenePanelView + */ + public initAll() { + this.flexWidth = "100%"; + this.flexHeight = "100%"; + this.flexPadding = 0; + this.flexOffsetX = 0; + this.flexOffsetY = 0; + } +} @Component export struct SCBScenePanel { @State containerSessionList: SCBSceneContainerSessionArray = new SCBSceneContainerSessionArray(); @Link screenProperty: SCBScreenProperty; - - @StorageLink('gestureModel') gestureModel: SCBGestureModel = new SCBGestureModel(); + @State viewParam: SCBViewParam = new SCBViewParam(); @State recentViewHitTestMode: HitTestMode = HitTestMode.None; @State scrollDirection: ScrollDirection = ScrollDirection.None; - @State mBlurRadius: number = 20; + @State blurEnabled: boolean = false; + @State scenePanelState: ScenePanelState = ScenePanelState.HOME; private scroller: Scroller = new Scroller(); - private screenWidth: number = -1 - private viewWidth: number = -1 - private currentState: number = SceneState.HOME - @State containerTranslation: number[]=[] - @State containerAlpha : number[]=[] - @State containerScale: number[]=[] buildLog(sceneContainerSession: SCBSceneContainerSession) { - Log.showInfo(TAG, `sceneContainerSession id: ${sceneContainerSession.containerId}`); - Log.showInfo(TAG, `sceneContainerSession isActive: ${sceneContainerSession.isActive}`); - Log.showInfo(TAG, 'sceneState:' + this.gestureModel?.sceneState + ' length: ' + this.containerSessionList.length); + Log.showInfo(TAG, `sceneContainerSession id: ${sceneContainerSession.containerId} isActive: ${sceneContainerSession.isActive}`); + Log.showInfo(TAG, 'sceneState:' + this.scenePanelState + ' length: ' + this.containerSessionList.length); return true; } - // sceneSessionManager Add scene of current screen - isRecent(): boolean { - Log.showInfo(TAG,"isRecent = " +(this.gestureModel.sceneState === SceneState.RECENT)) - Log.showInfo(TAG, "this.gestureModel.flexOffsetX: " + (this.gestureModel.flexOffsetX) + ' flexWidth: ' + (this.gestureModel.flexWidth)) - Log.showInfo(TAG, "this.scroller.currentOffset().xOffset: " + (this.scroller.currentOffset().xOffset)) - - if (this.gestureModel.sceneState === SceneState.RECENT) { - this.initRecentParams(); - this.currentState = this.gestureModel.sceneState; - Log.showInfo(TAG, "after scrollTo this.scroller.currentOffset().xOffset: " + (this.scroller.currentOffset().xOffset)) - return true; - } else { - this.containerTranslation = []; - this.containerAlpha = []; - this. containerScale = []; - this.currentState = this.gestureModel.sceneState; - return false; - } - } - private initView() { - this.gestureModel.initAll(); + this.viewParam.initAll(); this.containerSessionList.forEach((containerSession, index)=>{ containerSession.init(); }); @@ -81,24 +85,24 @@ export struct SCBScenePanel { Log.showInfo(TAG, 'enterRecentView') let screenW = px2vp(this.screenProperty.width); let listLen = this.containerSessionList.length; - this.gestureModel.flexWidth = (listLen * screenW * StyleConstants.RECENT_SCALE + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + - this.gestureModel.flexPadding * 2 + this.viewParam.flexWidth = (listLen * screenW * StyleConstants.RECENT_SCALE + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + + this.viewParam.flexPadding * 2 if (listLen > 2) { - let tmpX = (screenW * StyleConstants.RECENT_SCALE - (this.gestureModel.flexPadding - Number(StyleConstants.RECENT_MARGIN))); - this.gestureModel.flexOffsetX = -(this.gestureModel.flexWidth - screenW - tmpX - this.gestureModel.flexPadding) + let tmpX = (screenW * StyleConstants.RECENT_SCALE - (this.viewParam.flexPadding - Number(StyleConstants.RECENT_MARGIN))); + this.viewParam.flexOffsetX = -(this.viewParam.flexWidth - screenW - tmpX - this.viewParam.flexPadding) } else { - this.gestureModel.flexOffsetX = -(this.gestureModel.flexWidth - screenW) // decide final show pos with scroll to + this.viewParam.flexOffsetX = -(this.viewParam.flexWidth - screenW) // decide final show pos with scroll to } - this.gestureModel.multiViewShow = true; for (let i = 0; i < listLen; i++) { let containerSession = this.containerSessionList[i]; - containerSession.translateX = -this.gestureModel.flexPadding - i * (this.gestureModel.flexPadding * 2 - Number(StyleConstants.RECENT_MARGIN)) + containerSession.translateX = -this.viewParam.flexPadding - i * (this.viewParam.flexPadding * 2 - Number(StyleConstants.RECENT_MARGIN)) containerSession.translateY = 0; containerSession.scaleX = StyleConstants.RECENT_SCALE; containerSession.scaleY = StyleConstants.RECENT_SCALE; Log.showDebug(TAG, `idx: ${i} translateX: ${containerSession.translateX}.`); } - Log.showDebug(TAG, `listLen: ${listLen} flexOffsetX: ${this.gestureModel.flexOffsetX}, flexWidth:${this.gestureModel.flexWidth}.`); + this.updateScenePanelState(ScenePanelState.RECENT); + Log.showDebug(TAG, `listLen: ${listLen} flexOffsetX: ${this.viewParam.flexOffsetX}, flexWidth:${this.viewParam.flexWidth}.`); } private exitSplitView(persistentId: number) { @@ -108,7 +112,7 @@ export struct SCBScenePanel { item.secondarySession.session.persistentId === persistentId; }); if (index === -1) { - Log.showError(TAG, 'Failed to get scene containerSession with session id: ' + + Log.showWarn(TAG, 'Failed to get scene containerSession with session id: ' + persistentId); return null; } @@ -128,22 +132,30 @@ export struct SCBScenePanel { currContainerSession.init(); currContainerSession.isSplit = false; let newSceneContainerSession = new SCBSceneContainerSession(sceneSession, this.screenProperty); - newSceneContainerSession.isActive = false; - this.containerSessionList.splice(index, 0, newSceneContainerSession); - sceneSession.requestSessionBackground(); - if (this.gestureModel.sceneState !== SceneState.RECENT) { - let action = new SCBGestureAction({ - id: SCBGestureActionId.FULLSCENE - }); - this.onGestureChange(action); + newSceneContainerSession.requestBackground(); + if (!currContainerSession.primarySession && !currContainerSession.secondarySession) { + this.removeSceneContainerSession(currContainerSession); + } else { + this.containerSessionList.splice(index, 0, newSceneContainerSession); + } + if (this.scenePanelState !== ScenePanelState.RECENT) { + this.enterFullSceneOrHomeView(ScenePanelState.FULLSCENE) } else { this.enterRecentView(); } } + private enterFullSceneOrHomeView(state: ScenePanelState) { + this.initView(); + this.updateScenePanelState(state); + } + private updateRecentView(offsetX:number, offsetY:number) { Log.showDebug(TAG, 'updateRecentView') - let currContainerSession = this.getActiveSceneContainerSession(); + let currContainerSession = this.getTopActiveSceneContainerSession(); + if (!currContainerSession) { + return; + } let screenH = px2vp(this.screenProperty.height); let screenW = px2vp(this.screenProperty.width); currContainerSession.scaleX = @@ -151,26 +163,26 @@ export struct SCBScenePanel { currContainerSession.scaleX = Math.max(currContainerSession.scaleX, 0.25); currContainerSession.scaleX = Math.min(currContainerSession.scaleX, 1); currContainerSession.scaleY = currContainerSession.scaleX; - currContainerSession.translateX = offsetX - this.gestureModel.flexPadding; + currContainerSession.translateX = offsetX - this.viewParam.flexPadding; currContainerSession.translateY = offsetY + (1 - currContainerSession.scaleY) * Number(currContainerSession.height) / 2; if (offsetY > -(screenW * 0.1)) { - this.gestureModel.multiViewShow = false - let nowFinalFlexWidth = screenW * StyleConstants.RECENT_SCALE + this.gestureModel.flexPadding * 2; - if (this.gestureModel.flexWidth !== nowFinalFlexWidth) { - this.gestureModel.flexWidth = nowFinalFlexWidth; + this.updateScenePanelState(ScenePanelState.FULLSCENE); + let nowFinalFlexWidth = screenW * StyleConstants.RECENT_SCALE + this.viewParam.flexPadding * 2; + if (this.viewParam.flexWidth !== nowFinalFlexWidth) { + this.viewParam.flexWidth = nowFinalFlexWidth; } return; } - this.gestureModel.multiViewShow = true + this.updateScenePanelState(ScenePanelState.RECENT); let listLen = this.containerSessionList.length let tmpFinalFlexWith = (listLen * screenW * StyleConstants.RECENT_SCALE + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + - this.gestureModel.flexPadding * 2 - if (this.gestureModel.flexWidth !== tmpFinalFlexWith) { - this.gestureModel.flexWidth = tmpFinalFlexWith; + this.viewParam.flexPadding * 2 + if (this.viewParam.flexWidth !== tmpFinalFlexWith) { + this.viewParam.flexWidth = tmpFinalFlexWith; } - let tmpFlexWidth = (listLen * screenW * currContainerSession.scaleX + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + this.gestureModel.flexPadding * 2 - let disToEndX = (tmpFlexWidth - screenW + ((1 - currContainerSession.scaleX) * screenW) - this.gestureModel.flexPadding) // final view left space to right side is pad + (1 -scaleX) * W / 2, expect (1 -scaleX) * W / 2 + let tmpFlexWidth = (listLen * screenW * currContainerSession.scaleX + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + this.viewParam.flexPadding * 2 + let disToEndX = (tmpFlexWidth - screenW + ((1 - currContainerSession.scaleX) * screenW) - this.viewParam.flexPadding) // final view left space to right side is pad + (1 -scaleX) * W / 2, expect (1 -scaleX) * W / 2 for (let i = 0; i < listLen; i++) { let containerSession = this.containerSessionList[i]; containerSession.translateX = offsetX - i * ((1 - currContainerSession.scaleX) * screenW - Number(StyleConstants.RECENT_MARGIN)) - disToEndX @@ -183,11 +195,11 @@ export struct SCBScenePanel { private calculateCurrViewOnSlidingBegin() { let screenH = px2vp(this.screenProperty.height); let screenW = px2vp(this.screenProperty.width); - this.gestureModel.flexPadding = (1 - StyleConstants.RECENT_SCALE) * screenW / 2 - this.gestureModel.flexHeight = screenH; + this.viewParam.flexPadding = (1 - StyleConstants.RECENT_SCALE) * screenW / 2 + this.viewParam.flexHeight = screenH; let listLen = this.containerSessionList.length; - this.gestureModel.flexWidth = (listLen * screenW * StyleConstants.RECENT_SCALE + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + - this.gestureModel.flexPadding * 2 + this.viewParam.flexWidth = (listLen * screenW * StyleConstants.RECENT_SCALE + Number(StyleConstants.RECENT_MARGIN) * (listLen - 1)) + + this.viewParam.flexPadding * 2 } private addSceneContainerSession(sceneContainerSession: SCBSceneContainerSession): void { @@ -248,14 +260,14 @@ export struct SCBScenePanel { return scbSceneSession; } - private getSceneContainerSession(sceneSession: SCBSceneSession): SCBSceneContainerSession { - if (sceneSession === null) { - return null; - } + private getSceneContainerSessionWithPersistentId(persistentId: number): SCBSceneContainerSession { const index = this.containerSessionList.findIndex((item) => { - return item.primarySession === sceneSession || item.secondarySession === sceneSession; + return item.primarySession?.session.persistentId === persistentId || + item.secondarySession?.session.persistentId === persistentId; }); if (index === -1) { + Log.showWarn(TAG, 'Failed to get scene containerSession with session id: ' + + persistentId); return null; } return this.containerSessionList[index]; @@ -266,7 +278,7 @@ export struct SCBScenePanel { return item.containerId === containerId; }); if (index === -1) { - Log.showError(TAG, `Failed to find containerSession with id:${containerId}`) + Log.showWarn(TAG, `Failed to find containerSession with id:${containerId}`) return; } return this.containerSessionList[index]; @@ -283,115 +295,315 @@ export struct SCBScenePanel { return this.containerSessionList[index]; } - onStartScene(sceneInfo: SCBSceneInfo) { + private getTopActiveSceneContainerSession(): SCBSceneContainerSession { + if (this.containerSessionList.length === 0) { + Log.showError(TAG, 'Failed to find active scene container session with list length 0.'); + return null; + } + let index = this.containerSessionList.length - 1; + if (!this.containerSessionList[index].isActive) { + Log.showError(TAG, 'Failed to find active scene container session.'); + return null; + } + return this.containerSessionList[index]; + } + + onStartSceneFromIcon(sceneInfo: SCBSceneInfo) { + Log.showInfo(TAG, 'onStartSceneFromIcon with sceneInfo:' + JSON.stringify(sceneInfo)); let sceneSession = this.requestSceneSession(sceneInfo); if (sceneSession == null) { Log.showError(TAG, 'Failed to request scene session!'); return; } - Log.showInfo(TAG,"sceneState: " + this.gestureModel.sceneState ); - if (this.gestureModel.sceneState === SceneState.HOME) { - let sceneContainerSession = this.getSceneContainerSession(sceneSession); + if (this.scenePanelState === ScenePanelState.HOME) { + let sceneContainerSession = this.getSceneContainerSessionWithPersistentId(sceneSession.session.persistentId); if (sceneContainerSession === null) { sceneContainerSession = new SCBSceneContainerSession(sceneSession, this.screenProperty); this.addSceneContainerSession(sceneContainerSession); - Log.showInfo(TAG,"start scene add new container session: " + sceneContainerSession.containerId); + Log.showInfo(TAG,"start scene add new session: " + sceneContainerSession.containerId); } sceneContainerSession.requestActivation(); this.raiseSceneToTop(sceneContainerSession); - let action = new SCBGestureAction({ - id: SCBGestureActionId.FULLSCENE - }); - this.onGestureChange(action); + } else if (this.scenePanelState === ScenePanelState.SPLIT) { + this.pairSplit(sceneSession); + } else { + Log.showWarn(TAG, `do nothing with scenePanel State: ${this.scenePanelState}`); + } + this.updateScenePanelState(ScenePanelState.FULLSCENE); + } - } else if (this.gestureModel.sceneState === SceneState.SPLIT) { - let sceneContainerSession = this.getSceneContainerSession(sceneSession); - if (sceneContainerSession !== null && !sceneContainerSession.isActive) { - this.removeSceneContainerSession(sceneContainerSession); // delete old scene containerSession in background - Log.showInfo(TAG,"start scene split remove old fullscene container session: " + sceneContainerSession.containerId); - } - let activeSceneContainerSession = this.getActiveSceneContainerSession(); - activeSceneContainerSession.addSceneSession(sceneSession); - Log.showInfo(TAG,"start scene split after add active sceneSession container: " + activeSceneContainerSession.containerId); - sceneSession.requestSessionActivation(); - this.raiseSceneToTop(activeSceneContainerSession); - let action = new SCBGestureAction({ - id: SCBGestureActionId.FULLSCENE - }); - this.onGestureChange(action); + private pairSplit(sceneSession : SCBSceneSession) { + let sceneContainerSession = this.getSceneContainerSessionWithPersistentId(sceneSession.session.persistentId); + if (sceneContainerSession !== null && !sceneContainerSession.isActive) { + this.removeSceneContainerSession(sceneContainerSession); // delete old scene containerSession in background + Log.showInfo(TAG,"start scene split remove old fullscene container session: " + + sceneContainerSession.containerId); } + let activeSceneContainerSession = this.getTopActiveSceneContainerSession(); + activeSceneContainerSession.addSceneSession(sceneSession); // need to change + Log.showInfo(TAG,"start scene split after add active sceneSession container: " + + activeSceneContainerSession.containerId); + sceneSession.requestSessionActivation(); + this.raiseSceneToTop(activeSceneContainerSession); } - onActivateScene(containerId: number) { - let containerSession = this.getSceneContainerSessionWithContainerId(containerId); - let curActiveContainerSession = this.getActiveSceneContainerSession() // just for full session - if (containerSession) { - if (containerSession.containerId !== curActiveContainerSession.containerId) { - curActiveContainerSession.requestBackground(); - } + onStartSceneFromRecent(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onStartSceneFromRecent with persistentId:${persistentId} containerId:${containerId}`); + let sceneContainerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); + if (sceneContainerSession == null) { // recent must has container + Log.showError(TAG, `Failed to get sceneContainerSession with persistentId:${persistentId}!`); + return; + } + let activeSceneContainerSession = this.getTopActiveSceneContainerSession(); + sceneContainerSession.requestActivation(); + if (this.needMinimizeActiveContainer(sceneContainerSession, activeSceneContainerSession)) { + activeSceneContainerSession.requestBackground(); + } + this.raiseSceneToTop(sceneContainerSession); + this.enterFullSceneOrHomeView(ScenePanelState.FULLSCENE) + } + + private needMinimizeActiveContainer(currContainer: SCBSceneContainerSession, + activeSceneContainerSession: SCBSceneContainerSession) : boolean { + if (!activeSceneContainerSession || !currContainer) { + return false; + } + if (currContainer.containerId === activeSceneContainerSession.containerId) { + return false; + } + // need to consider split + let windowMode = currContainer.getContainerWindowMode(); + let activeContainerMode = activeSceneContainerSession.getContainerWindowMode(); + if (windowMode === SCBSceneMode.FULLSCREEN && activeContainerMode === SCBSceneMode.FULLSCREEN) { + return true; + } + return false; + } + + onStartSceneFromOther(sceneInfo: SCBSceneInfo) { // from console, full to free, free to full + Log.showInfo(TAG, 'onStartSceneFromOther with sceneInfo:' + JSON.stringify(sceneInfo)); + let sceneSession = this.requestSceneSession(sceneInfo); + if (sceneSession == null) { + Log.showError(TAG, 'Failed to request scene session!'); + return; + } + let sceneContainerSession = this.getSceneContainerSessionWithPersistentId(sceneSession.session.persistentId); + if (sceneContainerSession === null) { + sceneContainerSession = new SCBSceneContainerSession(sceneSession, this.screenProperty); + this.addSceneContainerSession(sceneContainerSession); + Log.showInfo(TAG,"start scene add new session: " + sceneContainerSession.containerId); + } + let activeSceneContainerSession = this.getTopActiveSceneContainerSession(); + sceneContainerSession.requestActivation(); + if (this.needMinimizeActiveContainer(sceneContainerSession, activeSceneContainerSession)) { + activeSceneContainerSession.requestBackground(); + } + this.raiseSceneToTop(sceneContainerSession); + this.enterFullSceneOrHomeView(ScenePanelState.FULLSCENE) + } + + onSceneStartTransition(toInfo: SCBSceneInfo, fromInfo: SCBSceneInfo) { // full to full + Log.showInfo(TAG, 'onSceneTransition with toSceneInfo:' + JSON.stringify(toInfo)); + if (!fromInfo) { + Log.showError(TAG, 'fromInfo is null'); + return; + } + let toSceneSession = this.requestSceneSession(toInfo); + let fromSceneSession = this.getSceneSession(fromInfo); + if (toSceneSession == null || fromSceneSession == null) { + Log.showError(TAG, 'Failed to get toSceneSession: ' + JSON.stringify(toInfo) + ' or fromSceneSession: ' + + JSON.stringify(fromInfo)); + return; + } + let fromContainerSession = this.getSceneContainerSessionWithPersistentId(fromSceneSession.session.persistentId); + let toContainerSession = this.getSceneContainerSessionWithPersistentId(toSceneSession.session.persistentId); + if (fromContainerSession == null) { + Log.showError(TAG, 'Failed to get fromContainerSceneSession: ' + JSON.stringify(fromInfo)); + return; + } + if (toContainerSession === null) { + toContainerSession = new SCBSceneContainerSession(toSceneSession, this.screenProperty); + this.addSceneContainerSession(toContainerSession); + Log.showInfo(TAG,"start scene add new session: " + toContainerSession.containerId); + } + toContainerSession.requestActivation(); + fromContainerSession.requestBackground(); + this.raiseSceneToTop(toContainerSession); + this.enterFullSceneOrHomeView(ScenePanelState.FULLSCENE) + } + + onSceneBackTransition(toInfo: SCBSceneInfo, fromInfo: SCBSceneInfo) { // full to full + Log.showInfo(TAG, 'onSceneTransition with toSceneInfo:' + JSON.stringify(toInfo)); + if (!fromInfo) { + Log.showError(TAG, 'fromInfo is null'); + return; + } + let toSceneSession = this.requestSceneSession(toInfo); + let fromSceneSession = this.getSceneSession(fromInfo); + if (toSceneSession == null || fromSceneSession == null) { + Log.showError(TAG, 'Failed to get toSceneSession: ' + JSON.stringify(toInfo) + ' or fromSceneSession: ' + + JSON.stringify(fromInfo)); + return; + } + let fromContainerSession = this.getSceneContainerSessionWithPersistentId(fromSceneSession.session.persistentId); + let toContainerSession = this.getSceneContainerSessionWithPersistentId(toSceneSession.session.persistentId); + if (fromContainerSession == null || toContainerSession == null) { + Log.showError(TAG, 'Failed to get fromContainerSession: ' + JSON.stringify(toInfo) + ' or toContainerSession: ' + + JSON.stringify(fromInfo)); + return; + } + toContainerSession.requestActivation(); + fromContainerSession.requestDestruction(); + this.raiseSceneToTop(toContainerSession); + this.enterFullSceneOrHomeView(ScenePanelState.FULLSCENE) + } + + onActivateScene(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onActivateScene with persistentId:${persistentId} containerId:${containerId}`); + let containerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); + let curActiveContainerSession = this.getTopActiveSceneContainerSession(); // just for full session + if (this.needMinimizeActiveContainer(containerSession, curActiveContainerSession)) { + curActiveContainerSession.requestBackground(); } containerSession.requestActivation(); this.raiseSceneToTop(containerSession); + this.enterFullSceneOrHomeView(ScenePanelState.FULLSCENE) } - onBackgroundScene(containerId: number) { - let containerSession = this.getSceneContainerSessionWithContainerId(containerId); + onMinimizeScene(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onMinimizeScene with persistentId:${persistentId} containerId:${containerId}`); + let containerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); + if (!containerSession) { + Log.showError(TAG, `cannot find containerSession with persistentId:${persistentId}`); + return; + } + if (!containerSession.isActive) { + Log.showWarn(TAG, `containerSession is already background:${persistentId}`); + return; + } + if (containerSession.isSplit) { + this.exitSplitView(persistentId); + } else { + containerSession.requestBackground(); + } + } + + minimizeAllScene() { + Log.showInfo(TAG, `onMinimizeAllScene`); + this.containerSessionList.forEach((container)=>{ + if (container.isActive) { + container.requestBackground(); + } + }) + this.enterFullSceneOrHomeView(ScenePanelState.HOME); + } + + onMaximizeScene(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onMaximizeScene with persistentId:${persistentId} containerId:${containerId}`); + let currContainerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); + if (!currContainerSession) { + Log.showError(TAG, `cannot find containerSession with persistentId:${persistentId}`); + return; + } + if (!currContainerSession.isActive) { + Log.showWarn(TAG, `containerSession is already background:${persistentId}`); + return; + } + for (let container of this.containerSessionList) { + if (container.containerId === currContainerSession.containerId) { + if (currContainerSession.isSplit) { + // maximize current split container + if (currContainerSession.primarySession && currContainerSession.secondarySession) { + let exitSceneSession = currContainerSession.primarySession.session.persistentId === persistentId ? + currContainerSession.secondarySession : currContainerSession.primarySession; + this.exitSplitView(exitSceneSession.session.persistentId); + Log.showDebug(TAG, `exitSplitView exit session:${exitSceneSession.session.persistentId}`); + } else { + currContainerSession.initAll(); + } + } + } else { + let windowMode = container.getContainerWindowMode(); + if (windowMode == SCBSceneMode.FULLSCREEN) { + container.requestBackground(); + } + } + } + currContainerSession.init(); + } + + onCloseScene(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onCloseScene with persistentId:${persistentId} containerId:${containerId}`); + let containerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); + if (!containerSession) { + Log.showError(TAG, `cannot find containerSession with persistentId:${persistentId}`); + return; + } + containerSession.requestDestruction(); + this.removeSceneContainerSession(containerSession); + } + + onBackgroundScene(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onBackgroundScene with persistentId:${persistentId} containerId:${containerId}`); + let containerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); if (containerSession) { containerSession.requestBackground(); } } - onDestroyScene(containerId: number) { - let containerSession = this.getSceneContainerSessionWithContainerId(containerId); + onDestroyScene(persistentId?: number, containerId?: number) { + Log.showInfo(TAG, `onDestroyScene with persistentId:${persistentId} containerId:${containerId}`); + let containerSession = persistentId ? this.getSceneContainerSessionWithPersistentId(persistentId) : + this.getSceneContainerSessionWithContainerId(containerId); if (containerSession) { containerSession.requestDestruction(); } this.removeSceneContainerSession(containerSession); - // test - this.containerSessionList.forEach((item, index)=> { - Log.showInfo(TAG, `onDestroyScene length: ${this.containerSessionList.length}, index: ${index}, containerId:${item.containerId}}`); - }) + } + updateScenePanelState(state: ScenePanelState) { + Log.showDebug(TAG, `updateSceneState from ${this.scenePanelState} to ${state}`); + if (this.scenePanelState === state) { + return; + } + this.scenePanelState = state; + if (this.scenePanelState === ScenePanelState.FULLSCENE || this.scenePanelState === ScenePanelState.RECENT) { + this.blurEnabled = true; + } else { + this.blurEnabled = false; + } + } + enterSplitView(containerSession: SCBSceneContainerSession) { + if (!containerSession) { + Log.showError(TAG, 'fail to enterSplitView ') + return; + } + containerSession.dividerParam.primaryH = ((100 - StyleConstants.DIVIDER_HEIGHT / containerSession.screenProperty.height * 100) / 2) + '%'; + containerSession.isSplit = true; + this.initView(); + this.updateScenePanelState(ScenePanelState.SPLIT); } onGestureChange(action: SCBGestureAction) { - Log.showInfo(TAG, `onGestureChange! action: ${action.actionId} sceneState: ${this.gestureModel.sceneState}`); + Log.showInfo(TAG, `onGestureChange! action: ${action.actionId} sceneState: ${this.scenePanelState}`); switch(action.actionId) { - case SCBGestureActionId.ENTER_SPLIT: - this.initView(); - this.gestureModel.updateSceneState(SceneState.SPLIT); - break; - case SCBGestureActionId.HOME: - this.initView(); - this.gestureModel.updateSceneState(SceneState.HOME); - break; - case SCBGestureActionId.SLIDING_UP: - this.updateRecentView(action.gestureOffsetX, action.gestureOffsetY); - break; - case SCBGestureActionId.SLIDE_UP_BEGIN: - this.calculateCurrViewOnSlidingBegin(); - this.gestureModel.updateSceneState(SceneState.SLIDING_UP); - break; - case SCBGestureActionId.ENTER_RECENT: - this.enterRecentView(); - this.gestureModel.updateSceneState(SceneState.RECENT); - break; - case SCBGestureActionId.FULLSCENE: - this.initView(); - this.gestureModel.updateSceneState(SceneState.FULLSCENE); - break; - case SCBGestureActionId.EXIT_SPILT: + case SCBGestureActionId.EXIT_SPLIT: this.exitSplitView(action.sessionId); break; case SCBGestureActionId.DESTROY_IN_RECENT: if (this.containerSessionList.length == 0) { - this.initView(); - this.gestureModel.updateSceneState(SceneState.HOME); + this.enterFullSceneOrHomeView(ScenePanelState.HOME); } else { - // todo: need modify not scorll to final view + // todo: need modify not scorll to final view when delete first/last one this.enterRecentView(); - this.gestureModel.updateSceneState(SceneState.RECENT); + this.scroller.scrollTo({ xOffset: -this.viewParam.flexOffsetX, yOffset: 0}) } break; default: @@ -399,125 +611,138 @@ export struct SCBScenePanel { } } + registerCallback() : void { + SCBSceneSessionManager.getInstance().on(SCBEventId.START_SCENE_FROM_ICON, this.screenProperty.screenId, + (toInfo: SCBSceneInfo, fromInfo?: SCBSceneInfo) => { + this.onStartSceneFromIcon(toInfo); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.START_SCENE_FROM_RECENT, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onStartSceneFromRecent(persistentId, containerId); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.START_SCENE_FROM_OTHER, this.screenProperty.screenId, + (toInfo: SCBSceneInfo, fromInfo?: SCBSceneInfo) => { + this.onStartSceneFromOther(toInfo); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.START_SCENE_TRANSITION, this.screenProperty.screenId, + (toInfo: SCBSceneInfo, fromInfo?: SCBSceneInfo) => { + this.onSceneStartTransition(toInfo, fromInfo); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.BACK_SCENE_TRANSITION, this.screenProperty.screenId, + (toInfo: SCBSceneInfo, fromInfo?: SCBSceneInfo) => { + this.onSceneBackTransition(toInfo, fromInfo); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.BACKGROUND_SCENE, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onBackgroundScene(persistentId, containerId); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.DESTROY_SCENE, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onDestroyScene(persistentId, containerId); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.ACTIVATE_SCENE, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onActivateScene(persistentId, containerId); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.MINIMIZE_SCENE, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onMinimizeScene(persistentId, containerId); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.MAXIMIZE_SCENE, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onMaximizeScene(persistentId, containerId); + }); + SCBSceneSessionManager.getInstance().on(SCBEventId.CLOSE_SCENE, this.screenProperty.screenId, + (persistentId?: number, containerId?: number) => { + this.onCloseScene(persistentId, containerId); + }); + } + aboutToAppear() { this.onGestureChange = this.onGestureChange.bind(this) - SCBSceneSessionManager.getInstance().registerStartSceneCallback(this.screenProperty.screenId, - (sceneInfo: SCBSceneInfo) => { - this.onStartScene(sceneInfo); - }) - SCBSceneSessionManager.getInstance().registerBackgroundSceneCallback(this.screenProperty.screenId, - (containerId: number) => { - this.onBackgroundScene(containerId); - }) - - SCBSceneSessionManager.getInstance().registerDestroySceneCallback(this.screenProperty.screenId, - (containerId: number) => { - this.onDestroyScene(containerId); - }) - SCBSceneSessionManager.getInstance().registerActivateSceneCallback(this.screenProperty.screenId, - (containerId: number) => { - this.onActivateScene(containerId); - }) + this.registerCallback(); } build() { Stack({ alignContent: Alignment.TopStart }) { // SLIDING_UP is needed in order to use blur when slide - if (this.gestureModel.sceneState === SceneState.FULLSCENE || this.gestureModel.sceneState === SceneState.RECENT || this.gestureModel.sceneState === SceneState.SLIDING_UP) { + if (this.blurEnabled) { Stack() { } .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - .blur(this.mBlurRadius) + .blur(StyleConstants.BLUR_RADIUS_20) } Scroll(this.scroller) { Flex({ direction: FlexDirection.Row }) { - ForEach(this.containerSessionList, (item: SCBSceneContainerSession, index) => { - if (this.buildLog(item) && this.isRecent() || (this.gestureModel.multiViewShow === true) || (this.buildLog(item) && item.isActive)) { + ForEach(this.containerSessionList, (item: SCBSceneContainerSession) => { + if (this.scenePanelState === ScenePanelState.RECENT || item.isActive) { SCBSceneContainer({ sceneContainerSession: item, dividerParam: item.dividerParam, screenProperty: $screenProperty, - containerIdx: index, + scenePanelState: $scenePanelState, onGestureChange: this.onGestureChange }) .flexShrink(0) } }, (item: SCBSceneContainerSession) => item.containerId.toString()) + } .flexShrink(0) .id('flexTest1') - .size({ width: this.gestureModel.flexWidth, height: this.gestureModel.flexHeight}) - .padding({ left: this.gestureModel.flexPadding, right: this.gestureModel.flexPadding}) + .size({ width: this.viewParam.flexWidth, height: this.viewParam.flexHeight}) + .padding({ left: this.viewParam.flexPadding, right: this.viewParam.flexPadding}) .hitTestBehavior(HitTestMode.None) } .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) .scrollBar(BarState.Off) - .scrollable(this.gestureModel.sceneState === SceneState.RECENT ? ScrollDirection.Horizontal : ScrollDirection.None) + .scrollable(this.scenePanelState === ScenePanelState.RECENT ? ScrollDirection.Horizontal : ScrollDirection.None) .edgeEffect(EdgeEffect.Spring) - .hitTestBehavior(this.gestureModel.sceneState === SceneState.RECENT ? HitTestMode.Default : HitTestMode.None) + .hitTestBehavior(this.scenePanelState === ScenePanelState.RECENT ? HitTestMode.Default : HitTestMode.None) .onClick(() => { - let activeSceneContainerSession = this.getActiveSceneContainerSession(); - activeSceneContainerSession?.requestBackground() - let action = new SCBGestureAction({ - id: SCBGestureActionId.HOME - }); - this.onGestureChange && this.onGestureChange(action); - this.containerTranslation= []; - this.containerAlpha = []; - this. containerScale = []; - }) - .onScroll((xOffset: number, yOffset: number) => { - Log.showInfo(TAG, `enableScroll: ${this.gestureModel.enableScroll}`) - if (!this.gestureModel.enableScroll) { - return - } + this.minimizeAllScene(); }) - .onScrollEnd(()=>{ - if (!this.gestureModel.enableScroll) { - return - } - }) - // Freedom scene - - if (this.gestureModel?.sceneState !== SceneState.RECENT - && this.gestureModel?.sceneState !== SceneState.SPLIT) { // todo: 放开 == recent - SCBGestureNavBar({ - containerSessionList: this.containerSessionList, - onGestureChange: this.onGestureChange - }) + + if (this.scenePanelState !== ScenePanelState.RECENT + && this.scenePanelState !== ScenePanelState.SPLIT) { // should enable in recent + SCBGestureNavBar() + .position({ y: '97%' }) + .width('100%') + .height('3%') + .gesture(PanGesture() + .onActionStart((event: GestureEvent) => { + this.calculateCurrViewOnSlidingBegin(); + this.blurEnabled = true; + }) + .onActionUpdate((event: GestureEvent) => { + this.updateRecentView(event.offsetX, event.offsetY); + this.scroller.scrollTo({ xOffset: -this.viewParam.flexOffsetX, yOffset: 0}) + }) + .onActionEnd((event: GestureEvent) => { + let activeSceneContainerSession = this.getTopActiveSceneContainerSession(); + if (!activeSceneContainerSession && event.offsetY < 0) { + this.enterRecentView(); + return; + } + if (event.offsetY < -400) { + this.minimizeAllScene(); + } else if (event.offsetY < -200) { + if (!activeSceneContainerSession.isSplit && enableSplit) { + this.enterSplitView(activeSceneContainerSession); + } else { + this.enterRecentView(); + this.scroller.scrollTo({ xOffset: -this.viewParam.flexOffsetX, yOffset: 0}) + } + } else if (event.offsetY < -100) { + this.enterRecentView(); + this.scroller.scrollTo({ xOffset: -this.viewParam.flexOffsetX, yOffset: 0}) + } else { + this.onActivateScene(undefined, activeSceneContainerSession.containerId); + } + })) } } .size({ width: StyleConstants.PERCENTAGE_100, height: StyleConstants.PERCENTAGE_100 }) - .hitTestBehavior(HitTestMode.None) - } - - updateView(progress:number,index:number) { - if(this.containerSessionList.length <= 1) { - this.containerScale = []; - this.containerTranslation = []; - this.containerAlpha = []; - return; - } - if (progress >= 0) { - this.containerAlpha[index] = 1; - } else { - this.containerAlpha[index] = 1 - Math.abs(progress) * 0.2; - } - this.containerScale[index] = 1 + (progress) * 0.05; - if (progress > 0) { - this.containerTranslation[index] = -Math.abs(progress) * this.screenWidth / 10; - } else { - this.containerTranslation[index] = Math.abs(progress) * this.screenWidth / 1.6; - } - } - - contentOffsetForIndex(index) : number { - let result = index * this.viewWidth - (this.screenWidth - this.viewWidth) / 2 - return result; - } - - initRecentParams() { - this.screenWidth = px2vp(this.screenProperty.width); - this.scroller.scrollTo({ xOffset: -this.gestureModel.flexOffsetX, yOffset: 0}) + .hitTestBehavior(this.scenePanelState === ScenePanelState.FULLSCENE ? HitTestMode.Default : HitTestMode.None) } } diff --git a/product/phone/src/main/ets/pages/EntryView.ets b/product/phone/src/main/ets/pages/EntryView.ets index 6f56b7cb1e9abdaa89438180dd8baf04b46e9b30..557cfb66716ab5eb83d87e959a3ee337c5426584 100644 --- a/product/phone/src/main/ets/pages/EntryView.ets +++ b/product/phone/src/main/ets/pages/EntryView.ets @@ -16,7 +16,7 @@ import { SCBRootSceneSession } from '@ohos/common' import { SCBSceneSessionManager } from '@ohos/common' import { SCBScreen } from '../SceneBoard/SCBScreen' -import { SCBScreenSession, SCBGestureModel } from '@ohos/common' +import { SCBScreenSession } from '@ohos/common' import { Log, Trace } from '@ohos/common'; import CommonStyleManager from '@ohos/common/src/main/ets/default/manager/CommonStyleManager'; import screenSessionManager from '@ohos.screenSessionManager'