• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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 { Log } from '../utils/Log';
17import { SettingsModel } from '../model/SettingsModel';
18import { StyleConstants } from '../constants/StyleConstants';
19import { CommonConstants } from '../constants/CommonConstants';
20import { PresetStyleConstants } from '../constants/PresetStyleConstants';
21import { layoutConfigManager } from '../layoutconfig/LayoutConfigManager';
22import { LauncherLayoutStyleConfig } from '../layoutconfig/LauncherLayoutStyleConfig';
23
24const TAG = 'LayoutViewModel';
25
26/**
27 * layout viewmodel
28 */
29export class LayoutViewModel {
30  private mIsPad = true;
31  private mScreenHeight: number | undefined;
32  private mScreenWidth: number | undefined;
33  private mWorkSpaceHeight: number | undefined;
34  private mDockHeight: number | undefined;
35  private mSysUITopHeight: number | undefined;
36  private mSysUIBottomHeight: number | undefined;
37  private mIndicatorHeight: number | undefined;
38  private readonly mLauncherLayoutStyleConfig: LauncherLayoutStyleConfig;
39  private mNavigationBarStatus = false;
40  private mDesktopGap: number | undefined;
41  private mDesktopIconMarginLeft: number | undefined;
42  private mDesktopIconMarginTop: number | undefined;
43  private mDesktopNameHeight: number | undefined;
44  private mDesktopNameLines: number | undefined;
45  private mDesktopIconNameMargin: number | undefined;
46  private mDesktopIconSize: number | undefined;
47  private mDesktopItemSize: number | undefined;
48  private mDesktopNameSize: number | undefined;
49  private mDesktopFolderSize: number | undefined;
50  private mGridRealHeight: number | undefined;
51  private mCommonDialogWidth = '';
52
53  private constructor() {
54    this.mLauncherLayoutStyleConfig = layoutConfigManager.getStyleConfig(
55      LauncherLayoutStyleConfig.LAUNCHER_COMMON_STYLE_CONFIG, LauncherLayoutStyleConfig.LAUNCHER_PRODUCT_STYLE_CONFIG);
56  }
57
58  /**
59   * get the LayoutViewModel instance
60   *
61   * @return LayoutViewModel
62   */
63  static getInstance(): LayoutViewModel {
64    if (globalThis.LayoutViewModelInstance == null) {
65      globalThis.LayoutViewModelInstance = new LayoutViewModel();
66      globalThis.LayoutViewModelInstance.initScreen();
67    }
68    return globalThis.LayoutViewModelInstance;
69  }
70
71  /**
72   * init screen info
73   *
74   * @param navigationBarStatus
75   */
76  initScreen(navigationBarStatus?: string): void {
77    this.mScreenWidth = AppStorage.Get('screenWidth');
78    this.mScreenHeight = AppStorage.Get('screenHeight');
79    Log.showDebug(TAG, `initScreen screenWidth: ${this.mScreenWidth}, screenHeight: ${this.mScreenHeight}`);
80    this.mSysUITopHeight = this.mLauncherLayoutStyleConfig.mSysTopHeight;
81    this.mNavigationBarStatus = navigationBarStatus === '0' ? true : false;
82
83    if (!this.mNavigationBarStatus) {
84      if (this.mScreenWidth > this.mScreenHeight) {
85        this.mSysUIBottomHeight = this.mLauncherLayoutStyleConfig.mSysBottomHeight * this.mScreenWidth / 1280;
86      } else {
87        this.mSysUIBottomHeight = this.mLauncherLayoutStyleConfig.mSysBottomHeight * this.mScreenWidth / 360;
88      }
89    } else {
90      this.mSysUIBottomHeight = 0;
91    }
92    AppStorage.SetOrCreate('sysUIBottomHeight', this.mSysUIBottomHeight);
93    this.mIndicatorHeight = this.mLauncherLayoutStyleConfig.mIndicatorHeight;
94    Log.showDebug(TAG, `initScreen SysUIBottomHeight: ${this.mSysUIBottomHeight},
95      IndicatorHeight: ${this.mIndicatorHeight}, SysUITopHeight: ${this.mSysUITopHeight},
96      SysUIBottomHeight: ${this.mSysUIBottomHeight}`);
97    this.mCommonDialogWidth = this.mLauncherLayoutStyleConfig.mCommonDialogWidth;
98  }
99
100  /**
101   * set device type
102   *
103   * @param deviceType: Device type
104   */
105  setDevice(deviceType: string): void {
106    this.mIsPad = deviceType === CommonConstants.PAD_DEVICE_TYPE;
107    AppStorage.SetOrCreate('isPad', this.mIsPad);
108  }
109
110  /**
111   * get workSpaceHeight
112   */
113  getWorkSpaceHeight(): number {
114    return this.mWorkSpaceHeight;
115  }
116
117  /**
118   * get dockHeight
119   */
120  getDockHeight(): number {
121    return this.mDockHeight;
122  }
123
124  /**
125   * get UninstallDialogWidth
126   */
127  getCommonDialogWidth(): string {
128    return this.mCommonDialogWidth;
129  }
130
131  /**
132   * get indicatorHeight
133   */
134  getIndicator(): number {
135    return this.mIndicatorHeight;
136  }
137
138  /**
139   * calculate dock
140   */
141  calculateDock(): any {
142    Log.showInfo(TAG, 'calculateDock start');
143    let margin = this.mLauncherLayoutStyleConfig.mDockSaveMargin;
144    let dockGap = this.mLauncherLayoutStyleConfig.mDockGutter;
145    let iconSize = this.mLauncherLayoutStyleConfig.mDockIconSize;
146    let listItemGap = this.mLauncherLayoutStyleConfig.mDockItemGap;
147    let dockPadding = this.mLauncherLayoutStyleConfig.mDockPadding;
148    let marginBottom = this.mLauncherLayoutStyleConfig.mDockMarginBottomHideBar;
149    if (!this.mNavigationBarStatus) {
150      marginBottom = this.mLauncherLayoutStyleConfig.mDockMarginBottom;
151    }
152    let maxDockNum = 0;
153    let dockSpaceWidth = this.mScreenWidth - 2 * margin;
154    let maxRecentNum = 3;
155    if (this.mScreenWidth < PresetStyleConstants.DEFAULT_DOCK_RECENT_WIDTH || !this.mIsPad) {
156      maxRecentNum = 0;
157      maxDockNum = ~~((dockSpaceWidth - 2 * dockPadding + listItemGap) / (iconSize + listItemGap));
158    } else {
159      let maxNum = ~~((dockSpaceWidth - dockGap - 4 * dockPadding + 2 * listItemGap) / (iconSize + listItemGap));
160      maxDockNum = maxNum - maxRecentNum;
161    }
162    this.mDockHeight = iconSize + 2 * dockPadding + marginBottom;
163    this.mWorkSpaceHeight = this.mScreenHeight - this.mSysUIBottomHeight - this.mDockHeight;
164    let result = {
165      mDockGap: dockGap,
166      mIconSize: iconSize,
167      mListItemWidth: iconSize,
168      mListItemHeight: iconSize,
169      mListItemGap: listItemGap,
170      mDockPadding: dockPadding,
171      mMaxRecentNum: maxRecentNum,
172      mMaxDockNum: maxDockNum,
173      mDockHeight: iconSize + 2 * dockPadding,
174      mMarginBottom: marginBottom
175    };
176    return result;
177  }
178
179  /**
180   * calculate desktop
181   */
182  calculateDesktop(): any {
183    Log.showInfo(TAG, 'calculateDesktop start');
184    let margin = this.mLauncherLayoutStyleConfig.mMargin;
185    let realWidth = this.mScreenWidth - 2 * margin;
186    let realHeight = this.mWorkSpaceHeight - this.mIndicatorHeight - this.mSysUITopHeight;
187    if (this.mNavigationBarStatus) {
188      realHeight = realHeight - this.mLauncherLayoutStyleConfig.mSysBottomHeight;
189    }
190    let itemSize = this.mLauncherLayoutStyleConfig.mAppItemSize;
191    let minGutter = this.mLauncherLayoutStyleConfig.mGridGutter;
192    let column = ~~((realWidth + minGutter) / (itemSize + minGutter));
193    let userWidth = (realWidth + minGutter - (itemSize + minGutter) * column);
194    let gutter = (userWidth / (column - 1)) + minGutter;
195    let row = ~~((realHeight + gutter) / (itemSize + gutter));
196    let marginTop = ((realHeight + gutter - (itemSize + gutter) * row) / 2);
197    if (!this.mIsPad) {
198        if (row > 6) {
199            row = 6;
200        }
201
202        if (this.mNavigationBarStatus) {
203            realHeight = realHeight + this.mLauncherLayoutStyleConfig.mSysBottomHeight;
204        }
205        let remainHeight = (realHeight + gutter - (itemSize + gutter) * row)
206        realHeight -= remainHeight
207        marginTop = remainHeight / 2 + this.mSysUITopHeight
208    }
209    //set desktop icon
210    let ratio = this.mLauncherLayoutStyleConfig.mIconRatio;
211    let lines = this.mLauncherLayoutStyleConfig.mNameLines;
212    let appTextSize = this.mLauncherLayoutStyleConfig.mNameSize;
213    let nameHeight = this.mLauncherLayoutStyleConfig.mNameHeight;
214    let iconNameMargin = this.mLauncherLayoutStyleConfig.mIconNameGap;
215    let iconMarginVertical = ratio * itemSize;
216    let iconHeight = itemSize - 2 * iconMarginVertical - nameHeight - iconNameMargin;
217    let iconMarginHorizontal = (itemSize - iconHeight) / 2;
218    if (AppStorage.Get('isPortrait') ) {
219      row = 11;
220      column = 5;
221    }
222    this.updateGrid(row, column);
223
224    this.mDesktopGap = gutter;
225    this.mDesktopIconMarginLeft = iconMarginHorizontal;
226    this.mDesktopIconMarginTop = iconMarginVertical;
227    this.mDesktopNameLines = lines;
228    this.mDesktopNameHeight = nameHeight;
229    this.mDesktopIconNameMargin = iconNameMargin;
230    this.mDesktopIconSize = iconHeight;
231    this.mDesktopItemSize = itemSize;
232    this.mDesktopNameSize = appTextSize;
233    this.mGridRealHeight = realHeight;
234    //set desktop config
235    let result = {
236      mMargin: margin,
237      mColumnsGap: gutter,
238      mRowsGap: gutter,
239      mColumns: column,
240      mRows: row,
241      mDesktopMarginTop: marginTop,
242      mGridWidth: realWidth,
243      mGridHeight: realHeight,
244      mAppItemSize: itemSize,
245      mNameSize: appTextSize,
246      mNameHeight: nameHeight,
247      mIconNameMargin: iconNameMargin,
248      mIconSize: iconHeight,
249      mNameLines: lines,
250      mIconMarginHorizontal: iconMarginHorizontal,
251      mIconMarginVertical: iconMarginVertical
252    };
253    return result;
254  }
255
256  /**
257   * calculate desktop folder
258   *
259   * @param layoutInfo folder layoutInfo
260   */
261  calculateFolder(layoutInfo: any): any {
262    Log.showInfo(TAG, 'calculateFolder start');
263    let itemSize = this.mLauncherLayoutStyleConfig.mAppItemSize;
264    let gap = this.mDesktopGap;
265    let iconMargin = this.mDesktopIconMarginLeft;
266    let gridColumn = SettingsModel.getInstance().getGridConfig().row;
267    let folderSize = this.mGridRealHeight / gridColumn + itemSize - iconMargin * 2;
268    let folderGutter = this.mLauncherLayoutStyleConfig.mFolderGutterRatio * folderSize;
269    let folderMargin = this.mLauncherLayoutStyleConfig.mFolderMarginRatio * folderSize;
270
271    let column = layoutInfo.column;
272    let iconSize = (folderSize - folderGutter * 2 - folderMargin * 2) / column;
273    let nameHeight = this.mDesktopNameHeight;
274    let nameLines = this.mDesktopNameLines;
275    let iconNameMargin = this.mDesktopIconNameMargin;
276
277    this.mDesktopFolderSize = folderSize;
278    let result = {
279      mGridSize: folderSize,
280      mFolderAppSize: iconSize,
281      mFolderGridGap: folderGutter,
282      mGridMargin: folderMargin,
283      mNameHeight: nameHeight,
284      mNameLines: nameLines,
285      mIconNameMargin: iconNameMargin
286    };
287    return result;
288  }
289
290  /**
291   * calculate open folder
292   *
293   * @param openFolderConfig layoutInfo
294   */
295  calculateOpenFolder(openFolderConfig: any): any {
296    Log.showInfo(TAG, 'calculateOpenFolder start');
297    let row = openFolderConfig.row;
298    let column = openFolderConfig.column;
299    let gutter = this.mLauncherLayoutStyleConfig.mFolderOpenGutter;
300    let padding = this.mLauncherLayoutStyleConfig.mFolderOpenPADDING;
301    let margin = this.mLauncherLayoutStyleConfig.mFolderOpenMargin;
302    let title = this.mLauncherLayoutStyleConfig.mFolderOpenTitle;
303    let itemSize = this.mDesktopItemSize;
304    let layoutWidth = column * itemSize + (column - 1) * gutter + 2 * padding;
305    let layoutHeight = row * itemSize + (row - 1) * gutter + 2 * padding;
306    let layoutSwiperHeight = row * itemSize + (row - 1) * gutter + 2 * padding + itemSize;
307    let result = {
308      mOpenFolderGridWidth: layoutWidth,
309      mOpenFolderGridHeight: layoutHeight,
310      mOpenFolderSwiperHeight: layoutSwiperHeight,
311      mOpenFolderAddIconSize: this.mDesktopIconSize,
312      mOpenFolderIconSize: this.mDesktopIconSize,
313      mOpenFolderAppSize: this.mDesktopItemSize,
314      mOpenFolderAppNameSize: this.mDesktopNameSize,
315      mOpenFolderAppNameHeight: this.mDesktopNameHeight,
316      mOpenFolderGridRow: row,
317      mOpenFolderGridColumn: column,
318      mOpenFolderGridGap: gutter,
319      mOpenFolderGridPadding: padding,
320      mFolderOpenMargin: margin,
321      mFolderOpenTitle: title,
322      mOpenFolderGridIconTopPadding: this.mDesktopIconMarginTop
323    };
324    return result;
325  }
326
327  /**
328   * calculate add app
329   *
330   * @param addFolderConfig
331   */
332  calculateFolderAddList(addFolderConfig: any): any {
333    Log.showInfo(TAG, 'calculateFolderAddList start');
334    let column: number = addFolderConfig.column;
335    let margin: number = this.mLauncherLayoutStyleConfig.mFolderAddGridMargin;
336    let saveMargin: number = PresetStyleConstants.DEFAULT_SCREEN_GRID_GAP_AND_MARGIN;
337    let screenGap: number = PresetStyleConstants.DEFAULT_SCREEN_GRID_GAP_AND_MARGIN;
338    let gap: number = this.mLauncherLayoutStyleConfig.mFolderAddGridGap;
339    let maxHeight: number = this.mLauncherLayoutStyleConfig.mFolderAddMaxHeight *
340    (this.mScreenHeight - this.mSysUITopHeight);
341    let toggleSize: number = this.mLauncherLayoutStyleConfig.mFolderToggleSize;
342    let screenColumns: number = PresetStyleConstants.DEFAULT_PHONE_GRID_APP_COLUMNS;
343    let textSize: number = this.mLauncherLayoutStyleConfig.mFolderAddTextSize;
344    let textLines: number = this.mLauncherLayoutStyleConfig.mFolderAddTextLines;
345    let titleSize: number = this.mLauncherLayoutStyleConfig.mFolderAddTitleSize;
346    let linesHeight = textSize * textLines;
347    let buttonSize: number = this.mLauncherLayoutStyleConfig.mFolderAddButtonSize;
348    let ratio: number = this.mLauncherLayoutStyleConfig.mFolderAddIconRatio;
349    if (this.mIsPad) {
350      screenColumns = PresetStyleConstants.DEFAULT_PAD_GRID_APP_COLUMNS;
351    }
352    let columnsWidth = this.mScreenWidth - 2 * saveMargin - (screenColumns - 1) * screenGap;
353    let columnWidth = columnsWidth / screenColumns;
354    let layoutWidth = columnWidth * column + (column - 1) * screenGap;
355    let gridSize = layoutWidth - 2 * margin;
356    let itemSize = (gridSize - (column - 1) * gap) / column;
357    let layoutHeight = layoutWidth + StyleConstants.DEFAULT_APP_ADD_TITLE_SIZE +
358    StyleConstants.DEFAULT_BUTTON_HEIGHT_NUMBER +
359    StyleConstants.DEFAULT_DIALOG_BOTTOM_MARGIN_NUMBER;
360    let iconSize = (1 - 2 * ratio) * itemSize - linesHeight - this.mDesktopIconNameMargin;
361
362    let result = {
363      mAddFolderGridWidth: gridSize,
364      mAddFolderDialogWidth: layoutWidth,
365      mAddFolderDialogHeight: layoutHeight,
366      mAddFolderGridGap: gap,
367      mAddFolderGridMargin: margin,
368      mAddFolderMaxHeight: maxHeight,
369      mFolderToggleSize: toggleSize,
370      mAddFolderTextSize: textSize,
371      mAddFolderTextLines: textLines,
372      mAddFolderLinesHeight: linesHeight,
373      mAddFolderItemSize: itemSize,
374      mAddFolderIconPaddingTop: itemSize * ratio,
375      mAddFolderIconMarginHorizontal: (itemSize - iconSize) / 2,
376      mAddFolderIconSize: iconSize,
377      mAddFolderTitleSize: titleSize,
378      mAddFolderButtonSize: buttonSize
379    };
380    return result;
381  }
382
383  /**
384   * calculate card form
385   */
386  calculateForm(): any {
387    Log.showInfo(TAG, 'calculateForm start');
388    let iconSize = this.mDesktopIconSize;
389    let folderSize = this.mDesktopFolderSize;
390    let itemSize = this.mDesktopItemSize;
391    let gap = this.mDesktopGap;
392    let iconMarginHorizontal = this.mDesktopIconMarginLeft;
393    let iconMarginVertical = this.mDesktopIconMarginTop;
394    let nameHeight = this.mDesktopNameHeight;
395    let widthDimension1: number = folderSize;
396    let heightDimension1: number = iconSize;
397    let widthDimension2 = folderSize;
398    let heightDimension2 = folderSize;
399    let widthDimension3 = (itemSize + gap) * 4 - gap - iconMarginHorizontal * 2;
400    let heightDimension3 = folderSize;
401    let widthDimension4 = widthDimension3;
402    let heightDimension4 = (itemSize + gap) * 4 - gap - 2 * iconMarginVertical -
403    nameHeight - this.mDesktopIconNameMargin;
404    let result = {
405      widthDimension1: widthDimension1,
406      heightDimension1: heightDimension1,
407      widthDimension2: widthDimension2,
408      heightDimension2: heightDimension2,
409      widthDimension3: widthDimension3,
410      heightDimension3: heightDimension3,
411      widthDimension4: widthDimension4,
412      heightDimension4: heightDimension4,
413      mIconNameMargin: this.mDesktopIconNameMargin
414    };
415    return result;
416  }
417
418  /**
419   * calculate app center
420   */
421  calculateAppCenter(): any {
422    Log.showInfo(TAG, 'calculateAppCenter start');
423    let appCenterMarginLeft: number = this.mLauncherLayoutStyleConfig.mAppCenterMarginLeft;
424    let saveMargin: number = this.mLauncherLayoutStyleConfig.mAppCenterMargin;
425    let gutter: number = this.mLauncherLayoutStyleConfig.mAppCenterGutter;
426    let appItemSize = this.mLauncherLayoutStyleConfig.mAppCenterSize;
427    let width = this.mScreenWidth - 2 * appCenterMarginLeft;
428    let height = this.mWorkSpaceHeight;
429    let column = ~~((width + gutter) / (appItemSize + gutter));
430    let row = ~~((height + gutter) / (appItemSize + gutter));
431    let padding = (height - row * (appItemSize + gutter) + gutter) / 2;
432    let ratio = this.mLauncherLayoutStyleConfig.mAppCenterRatio;
433    let lines = this.mLauncherLayoutStyleConfig.mAppCenterNameLines;
434    let appTextSize = this.mLauncherLayoutStyleConfig.mAppCenterNameSize;
435    let nameHeight = lines * appTextSize;
436    let iconMarginVertical = ratio * appItemSize;
437    let iconHeight = appItemSize - 2 * iconMarginVertical - nameHeight - this.mDesktopIconNameMargin;
438    let result = {
439      mColumnsGap: gutter,
440      mRowsGap: gutter,
441      mColumns: column,
442      mRows: row,
443      mGridWidth: width,
444      mGridHeight: height - 2 * padding,
445      mPadding: padding,
446      mNameSize: appTextSize,
447      mNameHeight: nameHeight,
448      mIconSize: iconHeight,
449      mNameLines: lines,
450      mIconMarginVertical: iconMarginVertical,
451      mAppItemSize: appItemSize,
452      mAppCenterMarginLeft:appCenterMarginLeft
453    };
454    return result;
455  }
456
457  /**
458   * update gridConfig info
459   *
460   * @param {number} row row of grid
461   * @param {number} column column of grid
462   */
463  private updateGrid(row: number, column: number): void {
464    Log.showInfo(TAG, `updateGrid row ${row} column ${column}`);
465    let settingsModel = SettingsModel.getInstance();
466    let gridConfig = settingsModel.getGridConfig();
467    gridConfig.row = row;
468    gridConfig.column = column;
469    const layoutDimension = `${row}X${column}`;
470    gridConfig.layout = layoutDimension;
471    gridConfig.name = layoutDimension;
472  }
473}