1/** 2 * Copyright (c) 2021-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 { EventConstants } from '../constants/EventConstants'; 17import { localEventManager } from '../manager/LocalEventManager'; 18import { Log } from '../utils/Log'; 19 20const TAG = 'PageDesktopModel'; 21 22/** 23 * PageDesktop Model 24 */ 25 26export class PageDesktopModel { 27 private isAddByDraggingFlag = false; 28 29 private constructor() { 30 } 31 32 /** 33 * Obtains the pageDesktop data model object. 34 * 35 * @return PageDesktopModel 36 */ 37 static getInstance(): PageDesktopModel { 38 if (globalThis.PageDesktopModel == null) { 39 globalThis.PageDesktopModel = new PageDesktopModel(); 40 } 41 return globalThis.PageDesktopModel; 42 } 43 44 /** 45 * Register for the PageDesktop application list add event. 46 * 47 * @param listener 48 */ 49 registerPageDesktopItemAddEvent(listener): void { 50 localEventManager.registerEventListener(listener, [ 51 EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, 52 EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_DELETE, 53 EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, 54 EventConstants.EVENT_REQUEST_PAGEDESK_FORM_ITEM_ADD, 55 EventConstants.EVENT_SMARTDOCK_INIT_FINISHED, 56 EventConstants.EVENT_REQUEST_PAGEDESK_REFRESH, 57 EventConstants.EVENT_REQUEST_FORM_ITEM_VISIBLE 58 ]); 59 } 60 61 /** 62 * register badge update event. 63 * 64 * @param listener 65 */ 66 registerPageDesktopBadgeUpdateEvent(listener): void { 67 localEventManager.registerEventListener(listener, [ 68 EventConstants.EVENT_BADGE_UPDATE 69 ]); 70 } 71 72 /** 73 * Unregister application list change listener. 74 * 75 * @param listener 76 */ 77 unregisterEventListener(listener): void { 78 localEventManager.unregisterEventListener(listener); 79 } 80 81 sendDockItemChangeEvent(appInfo): void { 82 localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_DOCK_ITEM_ADD, appInfo); 83 } 84 85 /** 86 * delete blank page from layoutInfo 87 * 88 * @param layoutInfo 89 * @param page 90 */ 91 deleteBlankPageFromLayoutInfo(layoutInfo, page): boolean { 92 for (let i = 0; i < layoutInfo.layoutInfo.length; i++) { 93 if (layoutInfo.layoutInfo[i].page == page) { 94 return false; 95 } 96 } 97 if (layoutInfo.layoutDescription.pageCount <= 1) { 98 return false; 99 } 100 layoutInfo.layoutDescription.pageCount--; 101 for (let m = 0; m < layoutInfo.layoutInfo.length; m++) { 102 if (layoutInfo.layoutInfo[m].page > page) { 103 layoutInfo.layoutInfo[m].page--; 104 } 105 } 106 return true; 107 } 108 109 /** 110 * get the addByDragging flag 111 */ 112 isAddByDragging(): boolean { 113 return this.isAddByDraggingFlag; 114 } 115 116 /** 117 * set the addByDragging flag 118 * @param {boolean} isAddByDragging 119 */ 120 setAddByDragging(isAddByDragging: boolean): void { 121 this.isAddByDraggingFlag = isAddByDragging; 122 } 123 124 updateAppItemLayoutInfo(info, item): void { 125 const pageCount = info.layoutDescription.pageCount; 126 const row = info.layoutDescription.row; 127 const column = info.layoutDescription.column; 128 const layoutInfo = info.layoutInfo; 129 // current page has space 130 let isNeedNewPage = true; 131 pageCycle: for (let i = 0; i < pageCount; i++) { 132 for (let y = 0; y < row; y++) { 133 for (let x = 0; x < column; x++) { 134 if (this.isPositionValid(info, item, i, x, y)) { 135 Log.showDebug(TAG, `updateAppItemLayoutInfo isPositionValid: x:${x} y:${y} page:${i}`); 136 isNeedNewPage = false; 137 layoutInfo.push({ 138 bundleName: item.bundleName, 139 typeId: item.typeId, 140 abilityName: item.abilityName, 141 moduleName: item.moduleName, 142 keyName: item.keyName, 143 badgeNumber:item.badgeNumber, 144 area: item.area, 145 page: i, 146 column: x, 147 row: y 148 }); 149 break pageCycle; 150 } 151 } 152 } 153 } 154 if (isNeedNewPage) { 155 layoutInfo.push({ 156 bundleName: item.bundleName, 157 typeId: item.typeId, 158 abilityName: item.abilityName, 159 moduleName: item.moduleName, 160 keyName: item.keyName, 161 badgeNumber:item.badgeNumber, 162 area: item.area, 163 page: pageCount, 164 column: 0, 165 row: 0 166 }); 167 ++info.layoutDescription.pageCount; 168 } 169 } 170 171 updatePageDesktopLayoutInfo(info, item): boolean { 172 const pageCount = info.layoutDescription.pageCount; 173 const row = info.layoutDescription.row; 174 const column = info.layoutDescription.column; 175 // current page has space 176 let isNeedNewPage = true; 177 const curPageIndex = this.getPageIndex(); 178 const max = pageCount - 1 > curPageIndex ? curPageIndex + 1 : pageCount - 1; 179 pageCycle: for (let i = curPageIndex; i <= max; i++) { 180 for (let y = 0; y < row; y++) { 181 for (let x = 0; x < column; x++) { 182 if (this.isPositionValid(info, item, i, x, y)) { 183 Log.showDebug(TAG, `updatePageDesktopLayoutInfo isPositionValid: x:${x} y:${y} page:${i}`); 184 isNeedNewPage = false; 185 item.page = i; 186 item.column = x; 187 item.row = y; 188 break pageCycle; 189 } 190 } 191 } 192 } 193 if (isNeedNewPage) { 194 item.page = curPageIndex + 1; 195 item.column = 0; 196 item.row = 0; 197 } 198 return isNeedNewPage; 199 } 200 201 private isPositionValid(info, item, page, startColumn, startRow): boolean { 202 const row = info.layoutDescription.row; 203 const column = info.layoutDescription.column; 204 if ((startColumn + item.area[0]) > column || (startRow + item.area[1]) > row) { 205 return false; 206 } 207 let isValid = true; 208 for (let x = startColumn; x < startColumn + item.area[0]; x++) { 209 for (let y = startRow; y < startRow + item.area[1]; y++) { 210 if (this.isPositionOccupied(info, page, x, y)) { 211 isValid = false; 212 break; 213 } 214 } 215 } 216 return isValid; 217 } 218 219 private isPositionOccupied(info, page, column, row): boolean { 220 const pageCount = info.layoutDescription.pageCount; 221 const layoutInfo = info.layoutInfo; 222 // current page has space 223 for (const layout of layoutInfo) { 224 if (layout.page == page) { 225 const xMatch = (column >= layout.column) && (column < layout.column + layout.area[0]); 226 const yMatch = (row >= layout.row) && (row < layout.row + layout.area[1]); 227 if (xMatch && yMatch) { 228 return true; 229 } 230 } 231 } 232 return false; 233 } 234 235 /** 236 * Changing the Desktop Page Number. 237 * 238 * @param idx: Page number 239 */ 240 setPageIndex(idx: number): void { 241 Log.showInfo(TAG, 'setPageIndex: ' + idx); 242 AppStorage.setOrCreate('pageIndex', idx); 243 } 244 245 /** 246 * Get the Desktop Page Number. 247 */ 248 getPageIndex(): number { 249 return AppStorage.get('pageIndex'); 250 } 251}