• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import window from '@ohos.window';
17import emitter from '@ohos.events.emitter';
18import display from '@ohos.display';
19import Logger from '../util/Logger';
20import { WindowColor, WindowEventId } from '../util/WindowConst';
21
22const windowPoint = {
23  x: 50, // 窗口移动的起始坐标X
24  y: 250, // 窗口移动的起始坐标Y
25};
26const WIDTH = 320;
27const HEIGHT = 240;
28const MOVE_X = 10;
29let MOVE_Y = 500;
30
31class WindowType {
32  moveToWidth: number;
33  moveToHeight: number;
34  setTouchable: boolean;
35  resetSizeWidth: number;
36  resetSizeHeight: number;
37  setPrivacyMode: boolean;
38  setBrightness: number;
39};
40
41class WindowManger {
42  private tag: string = 'WindowManger';
43  private startX: number = 0; // 窗口移动的起始坐标X
44  private startY: number = 0; // 窗口移动的起始坐标Y
45  private endX: number = MOVE_X; // 窗口移动的结束坐标X
46  private endY: number = MOVE_Y; // 窗口移动的结束坐标Y
47  private distanceX: number = 0; // 窗口在X轴上移动距离
48  private distanceY: number = 0; // 窗口在Y轴上移动距离
49  private windowWidth: number = 0; // 当前窗口宽度
50  private windowHeight: number = 0; // 当前窗口高度
51
52  initMainWindow(windowStage: window.WindowStage) {
53    windowStage.getMainWindow((err, data) => {
54      if (err.code) {
55        Logger.error(this.tag, 'Failed to obtain the main window. Cause: ' + JSON.stringify(err));
56        return;
57      };
58      let mainWindow = data;
59      // 窗口规避区域
60      mainWindow.on('avoidAreaChange', ({type, area}) => {
61        if (type === window.AvoidAreaType.TYPE_SYSTEM) {
62          AppStorage.SetOrCreate<number>('topHeight', area.topRect.height);
63          AppStorage.SetOrCreate<number>('topWidth', area.topRect.width);
64        }
65      });
66      mainWindow.getAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
67      // 设置主窗口沉浸式
68      mainWindow.setLayoutFullScreen(true);
69      // 设置主窗口导航栏、状态栏、文字颜色等属性
70      let sysBarProps = {
71        statusBarColor: WindowColor.statusBarColor,
72        navigationBarColor: WindowColor.navigationBarColor,
73        statusBarContentColor: WindowColor.statusBarContentColor,
74        navigationBarContentColor: WindowColor.navigationBarContentColor
75      };
76      // 加载状态变量
77      mainWindow.setSystemBarProperties(sysBarProps);
78    });
79
80    try {
81      const displayClass = display.getDefaultDisplaySync();
82      this.windowWidth = displayClass.width;
83      this.windowHeight = displayClass.height;
84      MOVE_Y = this.windowHeight / 2;
85      this.endY = MOVE_Y;
86    } catch (err) {
87      Logger.error('Failed to obtain the default display object. Code: ' + JSON.stringify(err));
88    };
89  }
90
91  async initSubWindow(windowStage, windowAttribute) {
92    // 创建应用子窗口
93    let subWindow = await windowStage.createSubWindow('mySubWindow');
94    subWindow.on('avoidAreaChange', ({type, area}) => {
95      if (type === window.AvoidAreaType.TYPE_SYSTEM) {
96        AppStorage.SetOrCreate<number>('topHeight', area.topRect.height);
97        AppStorage.SetOrCreate<number>('bottomHeight', area.bottomRect.height);
98      }
99    });
100    try {
101      subWindow.setWindowFocusable(true, (err) => {
102        if (err.code) {
103          console.error('Failed to set the window to be focusable. Cause:' + JSON.stringify(err));
104          return;
105        }
106        console.info('Succeeded in setting the window to be focusable.');
107      });
108      subWindow.on('windowEvent', (data) => {
109        console.info('Sub Window event happened. Event:' + JSON.stringify(data));
110        let message = null;
111        switch (JSON.stringify(data)) {
112          case '1':
113            message = $r('app.string.foreground');
114            break;
115          case '2':
116            message = $r('app.string.get_focus');
117            break;
118          case '3':
119            message = $r('app.string.lose_focus');
120            break;
121          case '4':
122            message = $r('app.string.background');
123            break;
124          default:
125            message = $r('app.string.unknown');
126            break;
127        }
128        AppStorage.SetOrCreate('focusText', message);
129      });
130    } catch (exception) {
131      console.error('Failed to register callback. Cause: ' + JSON.stringify(exception));
132    };
133
134    try {
135      windowStage.on('windowStageEvent', (data) => {
136        console.info('Succeeded in enabling the listener for window stage event changes. Data: ' +
137        JSON.stringify(data));
138      });
139    } catch (exception) {
140      console.error('Failed to enable the listener for window stage event changes. Cause:' +
141      JSON.stringify(exception));
142    };
143
144    Logger.info('show');
145    subWindow.resize(vp2px(WIDTH), vp2px(HEIGHT));
146    subWindow.moveWindowTo(MOVE_X, MOVE_Y); // 移动至坐标x为10,y为500的位置
147    subWindow.setUIContent('pages/SubWindowPage');
148    subWindow.setWindowTouchable(true);
149    subWindow.showWindow();
150
151    // onTouch的坐标绑定
152    let innerEvent = {
153      eventId: WindowEventId.SUB_WINDOW_INNER_EVENT_ID
154    };
155    let callback = (eventData) => {
156      Logger.info(this.tag, 'onTouchEventData' + eventData.data.x);
157      if (!this.startX || !this.startY || eventData.data.type === 0) {
158        this.startX = eventData.data.x;
159        this.startY = eventData.data.y;
160        return;
161      };
162      this.distanceX = eventData.data.x - this.startX;
163      this.distanceY = eventData.data.y - this.startY;
164      this.endX += vp2px(this.distanceX);
165      this.endY += vp2px(this.distanceY);
166      this.startX = eventData.data.x;
167      this.startY = eventData.data.y;
168      if (this.endX > 0 && this.endX < this.windowWidth - vp2px(WIDTH) && this.endY > AppStorage.get('topHeight')
169        && this.endY < this.windowHeight - vp2px(HEIGHT)) {
170        subWindow.moveWindowTo(this.endX, this.endY);
171      };
172    };
173    emitter.on(innerEvent, callback);
174  }
175
176  async setSubWindowAttribute(windowStage: window.WindowStage, windowAttribute: WindowType) {
177    let subWindow: window.Window = await windowStage.getMainWindow();
178    await subWindow.moveWindowTo(windowAttribute.moveToWidth, windowAttribute.moveToHeight);
179    // 设置子窗口为可触状态
180    await subWindow.setWindowTouchable(windowAttribute.setTouchable);
181    // 设置子窗口的大小
182    await subWindow.resize(windowAttribute.resetSizeWidth, windowAttribute.resetSizeHeight);
183    // 设置子窗口亮度
184    await subWindow.setWindowBrightness(windowAttribute.setBrightness);
185    // 设置子窗口为隐私模式
186    await subWindow.setWindowPrivacyMode(windowAttribute.setPrivacyMode);
187  }
188
189  changeWindowDirection(windowStage: window.WindowStage, orientation: window.Orientation) {
190    windowStage.getMainWindow((err, data) => {
191      if (err.code) {
192        Logger.error(this.tag, 'Failed to change the window: ' + JSON.stringify(err));
193        return;
194      }
195      data.setPreferredOrientation(orientation);
196    });
197  }
198
199  destorySubWindowCallback() {
200    this.startX = 0;
201    this.startY = 0;
202    this.endX = MOVE_X;
203    this.endY = MOVE_Y;
204    this.distanceX = 0;
205    this.distanceY = 0;
206  }
207}
208
209export default new WindowManger();