• 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;
30let MOVE_Y2 = 300;
31
32class WindowType {
33  moveToWidth: number;
34  moveToHeight: number;
35  setTouchable: boolean;
36  resetSizeWidth: number;
37  resetSizeHeight: number;
38  setPrivacyMode: boolean;
39  setBrightness: number;
40};
41
42class WindowManger {
43  private tag: string = 'WindowManger';
44  private startX: number = 0; // 窗口移动的起始坐标X
45  private startY: number = 0; // 窗口移动的起始坐标Y
46  private endX: number = MOVE_X; // 窗口移动的结束坐标X
47  private endY: number = MOVE_Y; // 窗口移动的结束坐标Y
48  private distanceX: number = 0; // 窗口在X轴上移动距离
49  private distanceY: number = 0; // 窗口在Y轴上移动距离
50  private windowWidth: number = 0; // 当前窗口宽度
51  private windowHeight: number = 0; // 当前窗口高度
52
53  initMainWindow(windowStage: window.WindowStage) {
54    windowStage.getMainWindow((err, data) => {
55      if (err.code) {
56        Logger.error(this.tag, 'Failed to obtain the main window. Cause: ' + JSON.stringify(err));
57        return;
58      }
59      ;
60      let mainWindow = data;
61      // 窗口规避区域
62      mainWindow.on('avoidAreaChange', ({type, area}) => {
63        if (type === window.AvoidAreaType.TYPE_SYSTEM) {
64          AppStorage.setOrCreate<number>('topHeight', area.topRect.height);
65          AppStorage.setOrCreate<number>('topWidth', area.topRect.width);
66        }
67      });
68      mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
69      // 设置主窗口沉浸式
70      mainWindow.setWindowLayoutFullScreen(true);
71      // 设置主窗口导航栏、状态栏、文字颜色等属性
72      const sysBarProps: window.SystemBarProperties = {
73        statusBarColor: WindowColor.statusBarColor,
74        navigationBarColor: WindowColor.navigationBarColor,
75        statusBarContentColor: WindowColor.statusBarContentColor,
76        navigationBarContentColor: WindowColor.navigationBarContentColor
77      };
78      // 加载状态变量
79      mainWindow.setWindowSystemBarProperties(sysBarProps);
80    });
81  }
82
83  updateDisplay() {
84    try {
85      const displayClass = display.getDefaultDisplaySync();
86      this.windowWidth = displayClass.width;
87      this.windowHeight = displayClass.height;
88      MOVE_Y = this.windowHeight / 2;
89      this.endY = MOVE_Y;
90    } catch (err) {
91      Logger.error('Failed to obtain the default display object. Code: ' + JSON.stringify(err));
92    }
93  }
94
95  async initSubWindow(windowStage, windowAttribute, isPortrait) {
96    // 创建应用子窗口
97    let subWindow = await windowStage.createSubWindow('mySubWindow');
98    subWindow.on('avoidAreaChange', ({type, area}) => {
99      if (type === window.AvoidAreaType.TYPE_SYSTEM) {
100        AppStorage.setOrCreate<number>('topHeight', area.topRect.height);
101        AppStorage.setOrCreate<number>('bottomHeight', area.bottomRect.height);
102      }
103    });
104    try {
105      subWindow.setWindowFocusable(true, (err) => {
106        if (err.code) {
107          console.error('Failed to set the window to be focusable. Cause:' + JSON.stringify(err));
108          return;
109        }
110        console.info('Succeeded in setting the window to be focusable.');
111      });
112      subWindow.on('windowEvent', (data) => {
113        console.info('Sub Window event happened. Event:' + JSON.stringify(data));
114        let message = null;
115        switch (JSON.stringify(data)) {
116          case '1':
117            message = $r('app.string.foreground');
118            break;
119          case '2':
120            message = $r('app.string.get_focus');
121            break;
122          case '3':
123            message = $r('app.string.lose_focus');
124            break;
125          case '4':
126            message = $r('app.string.background');
127            break;
128          default:
129            message = $r('app.string.unknown');
130            break;
131        }
132        AppStorage.SetOrCreate('focusText', message);
133      });
134    } catch (exception) {
135      console.error('Failed to register callback. Cause: ' + JSON.stringify(exception));
136    }
137    ;
138
139    try {
140      windowStage.on('windowStageEvent', (data) => {
141        console.info('Succeeded in enabling the listener for window stage event changes. Data: ' +
142        JSON.stringify(data));
143      });
144    } catch (exception) {
145      console.error('Failed to enable the listener for window stage event changes. Cause:' +
146      JSON.stringify(exception));
147    }
148    ;
149
150    Logger.info('show');
151    subWindow.resize(vp2px(WIDTH), vp2px(HEIGHT));
152    if (isPortrait) {
153      subWindow.moveWindowTo(MOVE_X, MOVE_Y);
154    } else {
155      this.updateDisplay();
156      subWindow.moveWindowTo(MOVE_X, MOVE_Y2);
157    }
158    subWindow.setUIContent('pages/SubWindowPage');
159    subWindow.setWindowTouchable(true);
160    subWindow.showWindow();
161
162    // onTouch的坐标绑定
163    let innerEvent = {
164      eventId: WindowEventId.SUB_WINDOW_INNER_EVENT_ID
165    };
166    let callback = (eventData) => {
167      Logger.info(this.tag, 'onTouchEventData' + eventData.data.x);
168      if (!this.startX || !this.startY || eventData.data.type === 0) {
169        this.startX = eventData.data.x;
170        this.startY = eventData.data.y;
171        return;
172      }
173      ;
174      this.distanceX = eventData.data.x - this.startX;
175      this.distanceY = eventData.data.y - this.startY;
176      this.endX += vp2px(this.distanceX);
177      this.endY += vp2px(this.distanceY);
178      this.startX = eventData.data.x;
179      this.startY = eventData.data.y;
180      if (this.endX > 0 && this.endX < this.windowWidth - vp2px(WIDTH) && this.endY > AppStorage.get('topHeight')
181        && this.endY < this.windowHeight - vp2px(HEIGHT)) {
182        subWindow.moveWindowTo(this.endX, this.endY);
183      }
184      ;
185    };
186    emitter.on(innerEvent, callback);
187  }
188
189  async setSubWindowAttribute(windowStage: window.WindowStage, windowAttribute: WindowType) {
190    let subWindow: window.Window = await windowStage.getMainWindow();
191    await subWindow.moveWindowTo(windowAttribute.moveToWidth, windowAttribute.moveToHeight);
192    // 设置子窗口为可触状态
193    await subWindow.setWindowTouchable(windowAttribute.setTouchable);
194    // 设置子窗口的大小
195    await subWindow.resize(windowAttribute.resetSizeWidth, windowAttribute.resetSizeHeight);
196    // 设置子窗口亮度
197    await subWindow.setWindowBrightness(windowAttribute.setBrightness);
198    // 设置子窗口为隐私模式
199    await subWindow.setWindowPrivacyMode(windowAttribute.setPrivacyMode);
200  }
201
202  changeWindowDirection(windowStage: window.WindowStage, orientation: window.Orientation) {
203    windowStage.getMainWindow((err, data) => {
204      if (err.code) {
205        Logger.error(this.tag, 'Failed to change the window: ' + JSON.stringify(err));
206        return;
207      }
208      data.setPreferredOrientation(orientation);
209    });
210  }
211
212  destorySubWindowCallback() {
213    this.startX = 0;
214    this.startY = 0;
215    this.endX = MOVE_X;
216    this.endY = MOVE_Y;
217    this.distanceX = 0;
218    this.distanceY = 0;
219  }
220}
221
222export default new WindowManger();