1// @ts-nocheck 2/** 3 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import { 18 AppMenu, 19 AppIcon, 20 DockItemInfo, 21 LauncherDragItemInfo, 22 CommonConstants, 23 StyleConstants, 24 ResourceManager, 25 Log 26} from '@ohos/common'; 27import { SmartDockStyleConfig } from '../config/SmartDockStyleConfig'; 28 29let mSmartDockStyleConfig: SmartDockStyleConfig = null; 30const TAG = 'ResidentLayout'; 31 32@Component 33export default struct ResidentLayout { 34 @StorageLink('dockPadding') dockPadding: { 35 right: number, 36 left: number, 37 top: number, 38 bottom: number 39 } = { right: 0, left: 0, top: 0, bottom: 0 }; 40 @StorageLink('residentList') @Watch('onDockListChange') appList: Array<DockItemInfo> = []; 41 mSmartDockStyleConfig: SmartDockStyleConfig; 42 onItemClick: Function = null; 43 buildMenu: Function = null; 44 onDockListChangeFunc: Function = null; 45 46 aboutToAppear(): void { 47 mSmartDockStyleConfig = this.mSmartDockStyleConfig; 48 this.onDockListChange(); 49 } 50 51 aboutToDisappear(): void { 52 this.onItemClick = null; 53 this.buildMenu = null; 54 this.onDockListChangeFunc = null; 55 } 56 57 getListWidth(): number { 58 let residentMaxNum = this.mSmartDockStyleConfig.mMaxDockNum; 59 let width = 0.0; 60 if (AppStorage.get("deviceType") == CommonConstants.DEFAULT_DEVICE_TYPE) { 61 Log.showDebug(TAG, `getListWidth mDockPadding: ${this.mSmartDockStyleConfig.mDockPadding}, mMaxNum: ${residentMaxNum}`); 62 width = this.mSmartDockStyleConfig.mDockPadding * 2 + residentMaxNum * (this.mSmartDockStyleConfig.mListItemWidth) + (residentMaxNum - 1) * (this.mSmartDockStyleConfig.mListItemGap); 63 Log.showDebug(TAG, `getListWidth width: ${width}`); 64 } else { 65 if (this.appList == null || this.appList.length === 0) { 66 } else { 67 let num = this.appList.length; 68 if (num > residentMaxNum) { 69 num = residentMaxNum; 70 } 71 width = this.mSmartDockStyleConfig.mDockPadding * 2 + num * (this.mSmartDockStyleConfig.mListItemWidth) + (num - 1) * (this.mSmartDockStyleConfig.mListItemGap); 72 } 73 } 74 return width; 75 } 76 77 private onDockListChange() { 78 this.onDockListChangeFunc(); 79 } 80 81 build() { 82 if (this.getListWidth && this.getListWidth() !== 0) { 83 Row() { 84 List({ space: this.appList.length == 0 ? 0 : this.mSmartDockStyleConfig.mListItemGap }) { 85 ForEach(this.appList, (item) => { 86 ListItem() { 87 AppItem({ 88 appInfo: item, 89 buildMenu: this.buildMenu, 90 onItemClick: this.onItemClick 91 }) 92 } 93 }, (item) => JSON.stringify(item)) 94 } 95 .height('100%') 96 .animation({ 97 curve: Curve.Friction 98 }) 99 .listDirection(Axis[this.mSmartDockStyleConfig.mListDirection]) 100 .editMode(false) 101 } 102 .backgroundColor(this.mSmartDockStyleConfig.mBackgroundColor) 103 .borderRadius(this.mSmartDockStyleConfig.mDockRadius) 104 .backdropBlur(this.mSmartDockStyleConfig.mBackdropBlur) 105 .padding(this.appList.length == 0 ? this.mSmartDockStyleConfig.mDockPadding : this.dockPadding) 106 .width(this.getListWidth()) 107 .height(this.mSmartDockStyleConfig.mDockHeight) 108 .justifyContent(FlexAlign.Center) 109 .onDragEnter((event: DragEvent, extraParams: string) => { 110 Log.showDebug(TAG, `onDragEnter extraParams: ${extraParams}, event: [${event.getWindowX()}, ${event.getWindowY()}]`); 111 }) 112 .onDragMove((event: DragEvent, extraParams: string) => { 113 Log.showDebug(TAG, `onDragMove event: [${event.getWindowX()}, ${event.getWindowY()}]`); 114 }) 115 .onDragLeave((event: DragEvent, extraParams: string) => { 116 Log.showDebug(TAG, `onDragLeave event: [${event.getWindowX()}, ${event.getWindowY()}]`); 117 }) 118 .onDrop((event: DragEvent, extraParams: string) => { 119 Log.showInfo(TAG, `onDrop event: [${event.getWindowX()}, ${event.getWindowY()}]`); 120 const dragResult = globalThis.SmartDockDragHandler.onDragDrop(event.getWindowX(), event.getWindowY()); 121 AppStorage.setOrCreate('selectAppIndex', null); 122 if (!dragResult) { 123 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 124 } else { 125 // Wait for the UI rendering to end. 126 setTimeout(() => { 127 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 128 }, 50); 129 } 130 }) 131 } 132 } 133} 134 135@Component 136struct AppItem { 137 @StorageLink('dragItemInfo') smartDragItemInfo: LauncherDragItemInfo = new LauncherDragItemInfo(); 138 @StorageLink('dragItemType') dragItemType: number = CommonConstants.DRAG_FROM_DOCK; 139 @State isShow: boolean = false; 140 onItemClick: Function = null; 141 appInfo: DockItemInfo = null; 142 buildMenu: Function = null; 143 private menuInfo; 144 145 aboutToAppear(): void { 146 this.menuInfo = this.buildMenu(this.appInfo); 147 } 148 149 aboutToDisappear(): void { 150 this.buildMenu = null; 151 this.onItemClick = null; 152 this.isShow = false; 153 this.appInfo = null; 154 this.menuInfo = null; 155 } 156 157 private getLongPress(): boolean { 158 return AppStorage.get('isLongPress'); 159 } 160 161 @Builder MenuBuilder() { 162 Column() { 163 AppMenu({ 164 menuInfoList: this.menuInfo, 165 closeMenu: () => { 166 this.isShow = false; 167 } 168 }) 169 } 170 .alignItems(HorizontalAlign.Center) 171 .justifyContent(FlexAlign.Center) 172 .width(StyleConstants.CONTEXT_MENU_WIDTH) 173 .height(StyleConstants.DEFAULT_40 * this.menuInfo.length + StyleConstants.DEFAULT_8) 174 } 175 176 build() { 177 Column() { 178 AppIcon({ 179 iconSize: mSmartDockStyleConfig.mIconSize, 180 iconId: this.appInfo.appIconId, 181 bundleName: this.appInfo.bundleName, 182 moduleName: this.appInfo.moduleName, 183 icon: ResourceManager.getInstance().getCachedAppIcon(this.appInfo.appIconId, 184 this.appInfo.bundleName, this.appInfo.moduleName), 185 badgeNumber: this.appInfo.badgeNumber 186 }) 187 } 188 .visibility(this.dragItemType === CommonConstants.DRAG_FROM_DOCK && this.smartDragItemInfo.keyName === this.appInfo.keyName ? 189 Visibility.Hidden : Visibility.Visible) 190 .width(mSmartDockStyleConfig.mListItemWidth) 191 .height(mSmartDockStyleConfig.mListItemHeight) 192 .backgroundColor(mSmartDockStyleConfig.mItemBackgroundColor) 193 .borderRadius(mSmartDockStyleConfig.mItemBorderRadius) 194 .parallelGesture( 195 LongPressGesture({ repeat: false }) 196 .onAction((event: GestureEvent) => { 197 Log.showInfo(TAG, 'onAction start'); 198 this.isShow = true; 199 AppStorage.setOrCreate('isLongPress', true); 200 }) 201 ) 202 .bindPopup(this.isShow, { 203 builder: this.MenuBuilder, 204 placement: Placement.Top, 205 popupColor: Color.White, 206 arrowOffset: AppStorage.get('deviceType') == CommonConstants.DEFAULT_DEVICE_TYPE ? null : 3 * (mSmartDockStyleConfig.mIconSize / 2) + mSmartDockStyleConfig.mListItemGap, // Avoid the popup offset problem in phone form 207 onStateChange: (e) => { 208 if (!e.isVisible) { 209 this.isShow = false; 210 } 211 AppStorage.setOrCreate('smartDockShowMenu', e.isVisible) 212 }, 213 autoCancel: true 214 }) 215 .onTouch((event: TouchEvent) => { 216 Log.showInfo(TAG, `onTouch event type: ${event.type}`); 217 if (event.type === CommonConstants.TOUCH_TYPE_UP && this.smartDragItemInfo.isDragging) { 218 let mIsDragEffectArea = globalThis.SmartDockDragHandler.isDragEffectArea(event.touches[0].windowX, event.touches[0].windowY); 219 if (!mIsDragEffectArea) { 220 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 221 AppStorage.setOrCreate('selectAppIndex', null); 222 } 223 AppStorage.setOrCreate('isLongPress', false); 224 } 225 if (this.smartDragItemInfo.isDragging) { 226 this.isShow = false; 227 } 228 }) 229 .onClick((event) => { 230 this.onItemClick(event, this.appInfo); 231 }) 232 .onMouse((event: MouseEvent) => { 233 Log.showInfo(TAG, `onMouse MouseType: ${event.button}`); 234 if (event.button == MouseButton.Right) { 235 event.stopPropagation(); 236 AppStorage.setOrCreate('selectDesktopAppItem', ''); 237 this.isShow = true; 238 } 239 }) 240 .onDragStart((event: DragEvent, extraParams: string) => { 241 Log.showInfo(TAG, `DragStart`); 242 this.dragItemType = CommonConstants.DRAG_FROM_DOCK; 243 this.smartDragItemInfo = Object.assign(new LauncherDragItemInfo(true), this.appInfo); 244 Log.showInfo(TAG, `smartDragItemInfo: ${JSON.stringify(this.smartDragItemInfo)}`); 245 const selectAppIndex = globalThis.SmartDockDragHandler.getDragItemIndexByCoordinates(event.getWindowX(), event.getWindowY()); 246 AppStorage.setOrCreate('selectAppIndex', selectAppIndex); 247 }) 248 .onDragEnd((event: DragEvent, extraParams: string) => { 249 Log.showInfo(TAG, `onDragEnd event: [${event.getWindowX()}, ${event.getWindowY()}]` + event.getResult()); 250 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 251 }) 252 } 253}