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 Log from '../../../../../../../../common/src/main/ets/default/Log'; 17import Constants from '../common/Constants'; 18import StyleConfiguration, { SimpleToggleLayoutEditComponentStyle, SimpleToggleLayoutEditUpTitleStyle, 19 SimpleToggleLayoutEditOptMsgStyle } from '../common/StyleConfiguration'; 20import SimpleToggleLayoutEditGrid from './SimpleToggleLayoutEditGrid'; 21import SimpleToggleLayoutEditDialogComponent from './SimpleToggleLayoutEditDialogComponent'; 22 23const TAG = 'Control-SimpleToggleLayoutEditComponent'; 24const TAG_SimpleToggleLayoutEditUpTitle = 'Control-SimpleToggleLayoutEditUpTitle'; 25const TAG_SimpleToggleLayoutEditOptMsg = 'Control-SimpleToggleLayoutEditOptMsg'; 26 27@Component 28export default struct SimpleToggleLayoutEditComponent { 29 private mDisplayingToggles: string[] = []; 30 private mHidingToggles: string[] = []; 31 private mDefaultDisplayToggles: string[] = []; 32 @Prop mColumnCount: number; 33 private simpleToggleLayoutEditEndCallback: () => void; 34 private onSaveDisplayingToggles: (toggles: string[]) => void; 35 @State mNewDisplayingToggles: string[] = []; 36 @State mNewHidingToggles: string[] = []; 37 @State style: SimpleToggleLayoutEditComponentStyle = StyleConfiguration.getSimpleToggleLayoutEditComponentStyle(); 38 @State mOptMsg: Resource = $r('app.string.control_center_simple_toggle_layout_edit_opt_desc'); 39 private mDisplayingTogglesMaxCount: number = Constants.SIMPLE_TOGGLE_LAYOUT_MAX_TOGGLE_COUNT; 40 private mDisplayingTogglesMinCount: number = Constants.SIMPLE_TOGGLE_LAYOUT_MIN_TOGGLE_COUNT; 41 private mHidingTogglesMaxCount: number = 0; 42 private mHidingTogglesMinCount: number = 0; 43 @State mCurrentDragToggleName: string = ''; 44 private titleDisplayInside: boolean = false; 45 private backDialogController: CustomDialogController = new CustomDialogController({ 46 builder: SimpleToggleLayoutEditDialogComponent({ 47 title: $r("app.string.control_center_simple_toggle_layout_edit_back_confirm"), 48 leftButton: $r("app.string.control_center_simple_toggle_layout_edit_back_confirm_primary"), 49 rightButton: $r("app.string.control_center_simple_toggle_layout_edit_back_confirm_secondary"), 50 leftAction: () => this.callSimpleToggleLayoutEditEnd(), 51 rightAction: () => this.onFinishBtnClick(null), 52 }), 53 autoCancel: false, 54 offset: { dx: 0, dy: 0 }, 55 customStyle: true, 56 alignment: DialogAlignment.Center 57 }); 58 private resetDialogController: CustomDialogController = new CustomDialogController({ 59 builder: SimpleToggleLayoutEditDialogComponent({ 60 title: $r("app.string.control_center_simple_toggle_layout_edit_reset_confirm"), 61 leftButton: $r("app.string.control_center_simple_toggle_layout_edit_reset_confirm_primary"), 62 rightButton: $r("app.string.control_center_simple_toggle_layout_edit_reset_confirm_secondary"), 63 leftAction: () => { 64 }, 65 rightAction: () => this.editResetConfirm(), 66 }), 67 autoCancel: false, 68 offset: { dx: 0, dy: 0 }, 69 customStyle: true, 70 alignment: DialogAlignment.Center 71 }); 72 73 aboutToAppear() { 74 Log.showInfo(TAG, 'aboutToAppear'); 75 this.mNewDisplayingToggles = [...this.mDisplayingToggles]; 76 this.mNewHidingToggles = [...this.mHidingToggles]; 77 let allTogglesCount = this.mNewDisplayingToggles.length + this.mNewHidingToggles.length; 78 this.mHidingTogglesMaxCount = allTogglesCount - this.mDisplayingTogglesMinCount; 79 if (this.mHidingTogglesMaxCount < 0) { 80 this.mHidingTogglesMaxCount = 0; 81 }; 82 this.mHidingTogglesMinCount = allTogglesCount - this.mDisplayingTogglesMaxCount; 83 if (this.mHidingTogglesMinCount < 0) { 84 this.mHidingTogglesMinCount = 0; 85 }; 86 } 87 88 aboutToDisappear() { 89 delete this.backDialogController 90 this.backDialogController = undefined 91 92 delete this.resetDialogController 93 this.resetDialogController = undefined 94 95 Log.showInfo(TAG, 'aboutToDisappear '); 96 } 97 98 build() { 99 Column() { 100 if (!this.titleDisplayInside) { 101 Column() { 102 SimpleToggleLayoutEditUpTitle({ 103 simpleToggleLayoutEditEndCallback: () => this.onSimpleToggleLayoutEditEnd() 104 }) 105 } 106 .width('100%') 107 .height(this.style.titleHeight) 108 .margin({bottom: this.style.titleMarginBottom}) 109 } 110 111 Column() { 112 if (this.titleDisplayInside) { 113 Column() { 114 SimpleToggleLayoutEditUpTitle({ 115 simpleToggleLayoutEditEndCallback: () => this.onSimpleToggleLayoutEditEnd() 116 }) 117 } 118 .width('100%') 119 .height(this.style.titleHeight) 120 } 121 Column() { 122 SimpleToggleLayoutEditGrid({ 123 mToggles: $mNewDisplayingToggles, 124 mMaxCount: this.mDisplayingTogglesMaxCount, 125 mMinCount: this.mDisplayingTogglesMinCount, 126 mColumnCount: this.mColumnCount, 127 mGlobalDragToggleName: this.mCurrentDragToggleName, 128 gridTag: 'displaying', 129 onItemDragStart: (toggleName) => this.onDisplayingGridItemDragStart(toggleName), 130 onItemDrop: (status) => this.onDisplayingGridItemDrop(status) 131 }) 132 } 133 .margin({top: this.style.upGridMarginTop, bottom: this.style.upGridMarginBottom, left: this.style.gridMarginLeft, right: this.style.gridMarginRight}) 134 135 Column() { 136 Column() { 137 SimpleToggleLayoutEditOptMsg({ 138 mOptMsg: $mOptMsg 139 }) 140 }.margin({top: this.style.msgMarginTop}) 141 142 Column() { 143 SimpleToggleLayoutEditGrid({ 144 mToggles: $mNewHidingToggles, 145 mMaxCount: this.mHidingTogglesMaxCount, 146 mMinCount: this.mHidingTogglesMinCount, 147 mColumnCount: this.mColumnCount, 148 mGlobalDragToggleName: this.mCurrentDragToggleName, 149 gridTag: 'hiding', 150 onItemDragStart: (toggleName) => this.onHidingGridItemDragStart(toggleName), 151 onItemDrop: (status) => this.onHidingGridItemDrop(status) 152 }) 153 }.margin({top: this.style.msgMarginBottom, bottom: this.style.btnMarginTop, left: this.style.gridMarginLeft, right: this.style.gridMarginRight}) 154 155 Grid() { 156 GridItem() { 157 Button({ type: ButtonType.Capsule, stateEffect: true }) { 158 Text($r("app.string.control_center_simple_toggle_layout_edit_reset")) 159 .fontColor(this.style.editBtnFontColor) 160 .fontSize(this.style.editBtnFontSize) 161 .fontWeight(FontWeight.Medium) 162 } 163 .backgroundColor(this.style.editBtnBgColor) 164 .width('100%') 165 .height('100%') 166 .onClick(this.onResetBtnClick.bind(this)) 167 } 168 169 GridItem() { 170 Button({ type: ButtonType.Capsule, stateEffect: true }) { 171 Text($r("app.string.control_center_simple_toggle_layout_edit_finish")) 172 .fontColor(this.style.editBtnFontColor) 173 .fontSize(this.style.editBtnFontSize) 174 .fontWeight(FontWeight.Medium) 175 } 176 .backgroundColor(this.style.editBtnBgColor) 177 .width('100%') 178 .height('100%') 179 .onClick(this.onFinishBtnClick.bind(this)) 180 } 181 } 182 .height(this.style.editBtnHeight) 183 .margin({bottom: this.style.btnMarginBottom}) 184 .padding({left: this.style.editBtnMarginLeft, right: this.style.editBtnMarginRight}) 185 .columnsTemplate('1fr 1fr') 186 .rowsTemplate('1fr') 187 .columnsGap(this.style.editBtnSpace) 188 } 189 .width('100%') 190 .backgroundColor(this.style.downAreaBgColor) 191 192 } 193 .margin({left: this.style.marginLeft, right: this.style.marginRight}) 194 .borderRadius(this.style.borderRadius) 195 .backgroundColor(this.style.upAreaBgColor) 196 .clip(true) 197 198 } 199 .width('100%') 200 .margin({top: this.style.marginTop}) 201 .onTouch(this.onComponentTouch.bind(this)) 202 } 203 204 onSimpleToggleLayoutEditEnd() { 205 Log.showDebug(TAG, `onSimpleToggleLayoutEditEnd`); 206 let changed = JSON.stringify(this.mDisplayingToggles) != JSON.stringify(this.mNewDisplayingToggles); 207 Log.showDebug(TAG, `onSimpleToggleLayoutEditEnd, changed: ${changed}`); 208 if (changed) { 209 this.backDialogController.open(); 210 } else { 211 this.callSimpleToggleLayoutEditEnd(); 212 }; 213 } 214 215 callSimpleToggleLayoutEditEnd() { 216 Log.showDebug(TAG, `callSimpleToggleLayoutEditEnd`); 217 if (this.simpleToggleLayoutEditEndCallback) { 218 this.simpleToggleLayoutEditEndCallback(); 219 }; 220 } 221 222 onResetBtnClick(event: ClickEvent) { 223 Log.showDebug(TAG, `onResetBtnClick`); 224 let equalDefault = JSON.stringify(this.mDefaultDisplayToggles) == JSON.stringify(this.mNewDisplayingToggles); 225 Log.showDebug(TAG, `onResetBtnClick, equalDefault: ${equalDefault}`); 226 if (!equalDefault) { 227 this.resetDialogController.open(); 228 }; 229 } 230 231 editResetConfirm() { 232 Log.showDebug(TAG, `editResetConfirm`); 233 this.resetData(); 234 this.callSaveDisplayingToggles(); 235 } 236 237 resetData(): void{ 238 Log.showDebug(TAG, `resetData`); 239 let tempDisplayingToggles: string[] = [...this.mDefaultDisplayToggles]; 240 let tempHidingToggles: string[] = []; 241 this.mDisplayingToggles.forEach((toggleName) => { 242 if (tempDisplayingToggles.indexOf(toggleName) < 0) { 243 tempHidingToggles.push(toggleName); 244 }; 245 }) 246 this.mHidingToggles.forEach((toggleName) => { 247 if (tempDisplayingToggles.indexOf(toggleName) < 0) { 248 tempHidingToggles.push(toggleName); 249 }; 250 }) 251 this.mNewDisplayingToggles = tempDisplayingToggles; 252 this.mNewHidingToggles = tempHidingToggles; 253 this.mDisplayingToggles = [...tempDisplayingToggles]; 254 this.mHidingToggles = [...tempHidingToggles]; 255 Log.showDebug(TAG, `resetData, mNewDisplayingToggles: ${JSON.stringify(this.mNewDisplayingToggles)}`); 256 Log.showDebug(TAG, `resetData, mNewHidingToggles: ${JSON.stringify(this.mNewHidingToggles)}`); 257 } 258 259 onFinishBtnClick(event: ClickEvent) { 260 Log.showDebug(TAG, `onFinishBtnClick`); 261 let changed = JSON.stringify(this.mDisplayingToggles) != JSON.stringify(this.mNewDisplayingToggles); 262 Log.showDebug(TAG, `onFinishBtnClick, changed: ${changed}`); 263 if (changed) { 264 this.callSaveDisplayingToggles(); 265 } 266 this.callSimpleToggleLayoutEditEnd(); 267 } 268 269 callSaveDisplayingToggles(): void{ 270 Log.showDebug(TAG, `callSaveDisplayingToggles`); 271 if (this.onSaveDisplayingToggles) { 272 this.onSaveDisplayingToggles(this.mNewDisplayingToggles); 273 }; 274 } 275 276 async onDisplayingGridItemDragStart(toggleName: string): Promise<void> { 277 Log.showDebug(TAG, `onDisplayingGridItemDragStart, toggleName: ${toggleName}`); 278 this.mCurrentDragToggleName = toggleName; 279 this.setOptMsg(toggleName); 280 } 281 282 async onDisplayingGridItemDrop(status: string): Promise<void> { 283 Log.showDebug(TAG, `onDisplayingGridItemDrop, status: ${status}`); 284 this.setOptMsg(null); 285 } 286 287 async onHidingGridItemDragStart(toggleName: string): Promise<void> { 288 Log.showDebug(TAG, `onHidingGridItemDragStart, toggleName: ${toggleName}`); 289 this.mCurrentDragToggleName = toggleName; 290 this.setOptMsg(toggleName); 291 } 292 293 async onHidingGridItemDrop(status: string): Promise<void> { 294 Log.showDebug(TAG, `onHidingGridItemDrop, status: ${status}`); 295 this.setOptMsg(null); 296 } 297 298 setOptMsg(toggleName: string): void { 299 Log.showInfo(TAG, `setOptMsg, toggleName: ${toggleName}, toggleName.length: ${toggleName.length}`); 300 if (!toggleName || toggleName.length == 0) { 301 this.mOptMsg = $r('app.string.control_center_simple_toggle_layout_edit_opt_desc'); 302 return; 303 } 304 if (this.mNewDisplayingToggles.indexOf(toggleName) >= 0) { 305 if (this.mNewDisplayingToggles.length <= this.mDisplayingTogglesMinCount) { 306 this.mOptMsg = $r('app.string.control_center_simple_toggle_layout_edit_opt_min', this.mDisplayingTogglesMinCount.toString()); 307 } else { 308 this.mOptMsg = $r('app.string.control_center_simple_toggle_layout_edit_opt_drag'); 309 } 310 } else if (this.mNewHidingToggles.indexOf(toggleName) >= 0) { 311 if (this.mNewDisplayingToggles.length >= this.mDisplayingTogglesMaxCount) { 312 this.mOptMsg = $r('app.string.control_center_simple_toggle_layout_edit_opt_max', this.mDisplayingTogglesMaxCount.toString()); 313 } else { 314 this.mOptMsg = $r('app.string.control_center_simple_toggle_layout_edit_opt_drag'); 315 } 316 }; 317 } 318 319 onComponentTouch(event: TouchEvent) { 320 Log.showDebug(TAG, `onComponentTouch`); 321 event.stopPropagation(); 322 } 323} 324 325@Component 326struct SimpleToggleLayoutEditUpTitle { 327 private simpleToggleLayoutEditEndCallback: Function; 328 @State style: SimpleToggleLayoutEditUpTitleStyle = StyleConfiguration.getSimpleToggleLayoutEditUpTitleStyle(); 329 330 aboutToAppear() { 331 Log.showInfo(TAG_SimpleToggleLayoutEditUpTitle, 'aboutToAppear'); 332 } 333 334 aboutToDisappear() { 335 Log.showInfo(TAG_SimpleToggleLayoutEditUpTitle, 'aboutToDisappear '); 336 } 337 338 build() { 339 Row() { 340 Image($r('app.media.ic_public_back')) 341 .margin({left: this.style.marginLeft, right: this.style.editTitleSpace}) 342 .objectFit(ImageFit.Contain) 343 .size({ width: this.style.imageWidth, 344 height: this.style.imageHeight }) 345 .fillColor(this.style.fontColor) 346 .onClick(this.backClick.bind(this)) 347 Text($r('app.string.control_center_simple_toggle_layout_edit')) 348 .fontColor(this.style.fontColor) 349 .fontSize(this.style.titleFontSize) 350 .fontWeight(FontWeight.Medium) 351 }.width('100%') 352 .height('100%') 353 } 354 355 backClick(event: ClickEvent) { 356 Log.showDebug(TAG_SimpleToggleLayoutEditUpTitle, `backClick, event: ${JSON.stringify(event)}`); 357 this.simpleToggleLayoutEditEndCallback(); 358 } 359} 360 361@Component 362struct SimpleToggleLayoutEditOptMsg { 363 @Link mOptMsg: Resource; 364 @State style: SimpleToggleLayoutEditOptMsgStyle = StyleConfiguration.getSimpleToggleLayoutEditOptMsgStyle(); 365 366 aboutToAppear() { 367 Log.showInfo(TAG_SimpleToggleLayoutEditOptMsg, 'aboutToAppear'); 368 } 369 370 aboutToDisappear() { 371 Log.showInfo(TAG_SimpleToggleLayoutEditOptMsg, 'aboutToDisappear '); 372 } 373 374 build() { 375 Column() { 376 Text(this.mOptMsg) 377 .fontSize(this.style.fontSize) 378 .fontColor(this.style.fontColor) 379 } 380 .height(this.style.height) 381 .margin({left: this.style.marginLeftRight, right: this.style.marginLeftRight}) 382 .justifyContent(FlexAlign.Center) 383 } 384}