1/* 2 * Copyright (c) 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 16/// <reference path='./import.ts' /> 17 18import { ArkScrollable } from "./ArkScrollable"; 19 20class ScrollNestedScrollModifier extends ModifierWithKey<ArkNestedScrollOptions> { 21 static identity: symbol = Symbol('nestedScroll'); 22 applyPeer(node: KNode, reset: boolean): void { 23 if (reset) { 24 getUINativeModule().scroll.resetNestedScroll(node); 25 } else { 26 getUINativeModule().scroll.setNestedScroll(node, this.value.scrollForward, this.value.scrollBackward); 27 } 28 } 29 30 checkObjectDiff(): boolean { 31 return !isBaseOrResourceEqual(this.stageValue.scrollForward, this.value.scrollForward) || 32 !isBaseOrResourceEqual(this.stageValue.scrollBackward, this.value.scrollBackward); 33 } 34} 35 36class ScrollEnableScrollInteractionModifier extends ModifierWithKey<boolean> { 37 static identity: symbol = Symbol('enableScrollInteraction'); 38 applyPeer(node: KNode, reset: boolean): void { 39 if (reset) { 40 getUINativeModule().scroll.resetEnableScroll(node); 41 } else { 42 getUINativeModule().scroll.setEnableScroll(node, this.value); 43 } 44 } 45 46 checkObjectDiff(): boolean { 47 return !isBaseOrResourceEqual(this.stageValue, this.value); 48 } 49} 50 51class ScrollFrictionModifier extends ModifierWithKey<number | Resource> { 52 static identity: symbol = Symbol('friction'); 53 applyPeer(node: KNode, reset: boolean): void { 54 if (reset) { 55 getUINativeModule().scroll.resetFriction(node); 56 } else { 57 getUINativeModule().scroll.setFriction(node, this.value); 58 } 59 } 60 61 checkObjectDiff(): boolean { 62 return !isBaseOrResourceEqual(this.stageValue, this.value); 63 } 64} 65 66class ScrollScrollSnapModifier extends ModifierWithKey<ArkScrollSnapOptions> { 67 static identity: symbol = Symbol('scrollSnap'); 68 applyPeer(node: KNode, reset: boolean): void { 69 if (reset) { 70 getUINativeModule().scroll.resetScrollSnap(node); 71 } else { 72 let snapPagination = []; 73 let isArray = true; 74 if (Array.isArray(this.value.snapPagination)) { 75 for (let i = 0; i < this.value.snapPagination.length; i++) { 76 let item = this.value.snapPagination[i]; 77 snapPagination.push(item); 78 } 79 } else { 80 isArray = false; 81 } 82 83 if (isArray) { 84 getUINativeModule().scroll.setScrollSnap(node, this.value.snapAlign, snapPagination, this.value.enableSnapToStart, this.value.enableSnapToEnd); 85 } else { 86 getUINativeModule().scroll.setScrollSnap(node, this.value.snapAlign, 87 this.value.snapPagination, this.value.enableSnapToStart, this.value.enableSnapToEnd); 88 } 89 } 90 } 91 92 checkObjectDiff(): boolean { 93 return !((this.stageValue.snapAlign === this.value.snapAlign) && 94 (this.stageValue.enableSnapToStart === this.value.enableSnapToStart) && 95 (this.stageValue.enableSnapToEnd === this.value.enableSnapToEnd) && 96 (this.stageValue.snapPagination === this.value.snapPagination)); 97 } 98} 99 100class ScrollScrollBarModifier extends ModifierWithKey<number> { 101 static identity: symbol = Symbol('scrollBar'); 102 applyPeer(node: KNode, reset: boolean): void { 103 if (reset) { 104 getUINativeModule().scroll.resetScrollBar(node); 105 } else { 106 getUINativeModule().scroll.setScrollBar(node, this.value); 107 } 108 } 109 checkObjectDiff(): boolean { 110 return !isBaseOrResourceEqual(this.stageValue, this.value); 111 } 112} 113 114class ScrollScrollableModifier extends ModifierWithKey<ScrollDirection> { 115 constructor(value: ScrollDirection) { 116 super(value); 117 } 118 static identity: Symbol = Symbol('scrollable'); 119 applyPeer(node: KNode, reset: boolean): void { 120 if (reset) { 121 getUINativeModule().scroll.resetScrollable(node); 122 } else { 123 getUINativeModule().scroll.setScrollable(node, this.value); 124 } 125 } 126 127 checkObjectDiff(): boolean { 128 return this.stageValue !== this.value; 129 } 130} 131 132class ScrollScrollBarWidthModifier extends ModifierWithKey<string | number> { 133 constructor(value: string | number) { 134 super(value); 135 } 136 static identity: Symbol = Symbol('scrollBarWidth'); 137 applyPeer(node: KNode, reset: boolean): void { 138 if (reset) { 139 getUINativeModule().scroll.resetScrollBarWidth(node); 140 } else { 141 getUINativeModule().scroll.setScrollBarWidth(node, this.value); 142 } 143 } 144 145 checkObjectDiff(): boolean { 146 return this.stageValue !== this.value; 147 } 148} 149 150class ScrollScrollBarColorModifier extends ModifierWithKey<ResourceColor> { 151 constructor(value: ResourceColor) { 152 super(value); 153 } 154 static identity: Symbol = Symbol('scrollBarColor'); 155 applyPeer(node: KNode, reset: boolean): void { 156 if (reset) { 157 getUINativeModule().scroll.resetScrollBarColor(node); 158 } else { 159 getUINativeModule().scroll.setScrollBarColor(node, this.value); 160 } 161 } 162 163 checkObjectDiff(): boolean { 164 return !isBaseOrResourceEqual(this.stageValue, this.value); 165 } 166} 167 168class ScrollEnablePagingModifier extends ModifierWithKey<boolean> { 169 constructor(value: boolean) { 170 super(value); 171 } 172 static identity: Symbol = Symbol('scrollEnablePaging'); 173 applyPeer(node: KNode, reset: boolean): void { 174 if (reset) { 175 getUINativeModule().scroll.resetEnablePaging(node); 176 } else { 177 getUINativeModule().scroll.setEnablePaging(node, this.value); 178 } 179 } 180} 181 182class ScrollClipModifier extends ModifierWithKey<boolean | object> { 183 constructor(value: boolean | object) { 184 super(value); 185 } 186 static identity: Symbol = Symbol('scrollClip'); 187 applyPeer(node: KNode, reset: boolean): void { 188 if (reset) { 189 getUINativeModule().common.resetClipWithEdge(node); 190 } else { 191 getUINativeModule().common.setClipWithEdge(node, this.value); 192 } 193 } 194 195 checkObjectDiff(): boolean { 196 return true; 197 } 198} 199 200class ScrollInitialOffsetModifier extends ModifierWithKey<ArkScrollOffsetOptions> { 201 static identity: Symbol = Symbol('initialOffset'); 202 applyPeer(node: KNode, reset: boolean): void { 203 if (reset) { 204 getUINativeModule().scroll.resetInitialOffset(node); 205 } else { 206 getUINativeModule().scroll.setInitialOffset(node, this.value.xOffset, this.value.yOffset); 207 } 208 } 209 210 checkObjectDiff(): boolean { 211 return !((this.stageValue.xOffset === this.value.xOffset) && 212 (this.stageValue.yOffset === this.value.yOffset)); 213 } 214} 215 216class ScrollFlingSpeedLimitModifier extends ModifierWithKey<number> { 217 static identity: symbol = Symbol('flingSpeedLimit'); 218 applyPeer(node: KNode, reset: boolean): void { 219 if (reset) { 220 getUINativeModule().scroll.resetFlingSpeedLimit(node); 221 } else { 222 getUINativeModule().scroll.setFlingSpeedLimit(node, this.value); 223 } 224 } 225 checkObjectDiff(): boolean { 226 return !isBaseOrResourceEqual(this.stageValue, this.value); 227 } 228} 229 230class ScrollInitializeModifier extends ModifierWithKey<Scroller> { 231 constructor(value: Scroller) { 232 super(value); 233 } 234 static identity: Symbol = Symbol('scrollInitialize'); 235 applyPeer(node: KNode, reset: boolean): void { 236 if (reset) { 237 getUINativeModule().scroll.resetScrollInitialize(node); 238 } else { 239 getUINativeModule().scroll.setScrollInitialize(node, this.value); 240 } 241 } 242} 243class ScrollOnScrollStartModifier extends ModifierWithKey<() => void> { 244 constructor(value: () => void) { 245 super(value); 246 } 247 static identity: Symbol = Symbol('scrollOnScrollStart'); 248 applyPeer(node: KNode, reset: boolean): void { 249 if (reset) { 250 getUINativeModule().scroll.resetScrollOnScrollStart(node); 251 } else { 252 getUINativeModule().scroll.setScrollOnScrollStart(node, this.value); 253 } 254 } 255} 256 257class ScrollOnScrollEndModifier extends ModifierWithKey<() => void> { 258 constructor(value: () => void) { 259 super(value); 260 } 261 static identity: Symbol = Symbol('scrollOnScrollEnd'); 262 applyPeer(node: KNode, reset: boolean): void { 263 if (reset) { 264 getUINativeModule().scroll.resetScrollOnScrollEnd(node); 265 } else { 266 getUINativeModule().scroll.setScrollOnScrollEnd(node, this.value); 267 } 268 } 269} 270 271class ScrollOnScrollStopModifier extends ModifierWithKey<() => void> { 272 constructor(value: () => void) { 273 super(value); 274 } 275 static identity: Symbol = Symbol('scrollOnScrollStop'); 276 applyPeer(node: KNode, reset: boolean): void { 277 if (reset) { 278 getUINativeModule().scroll.resetScrollOnScrollStop(node); 279 } else { 280 getUINativeModule().scroll.setScrollOnScrollStop(node, this.value); 281 } 282 } 283} 284 285class ScrollOnScrollModifier extends ModifierWithKey<(xOffset: number, yOffset: number) => void> { 286 constructor(value: (xOffset: number, yOffset: number) => void) { 287 super(value); 288 } 289 static identity: Symbol = Symbol('scrollOnScroll'); 290 applyPeer(node: KNode, reset: boolean): void { 291 if (reset) { 292 getUINativeModule().scroll.resetScrollOnScrollModifier(node); 293 } else { 294 getUINativeModule().scroll.setScrollOnScrollModifier(node, this.value); 295 } 296 } 297} 298 299class ScrollOnScrollEdgeModifier extends ModifierWithKey<(side: Edge) => void> { 300 constructor(value: (side: Edge) => void) { 301 super(value); 302 } 303 static identity: Symbol = Symbol('scrollOnScrollEdge'); 304 applyPeer(node: KNode, reset: boolean): void { 305 if (reset) { 306 getUINativeModule().scroll.resetScrollOnScrollEdge(node); 307 } else { 308 getUINativeModule().scroll.setScrollOnScrollEdge(node, this.value); 309 } 310 } 311} 312 313class ScrollOnDidScrollModifier extends ModifierWithKey<(xOffset: number, 314 yOffset: number, scrollState: ScrollState) => void> { 315 constructor(value: (xOffset: number, yOffset: number, scrollState: ScrollState) => void) { 316 super(value); 317 } 318 static identity: Symbol = Symbol('scrollOnDidScroll'); 319 applyPeer(node: KNode, reset: boolean): void { 320 if (reset) { 321 getUINativeModule().scroll.resetScrollOnDidScroll(node); 322 } else { 323 getUINativeModule().scroll.setScrollOnDidScroll(node, this.value); 324 } 325 } 326} 327 328class ScrollOnWillScrollModifier extends ModifierWithKey<(xOffset: number, yOffset: number, 329 scrollState: ScrollState, scrollSource: ScrollSource) => void | OffsetResult> { 330 constructor(value: (xOffset: number, yOffset: number, 331 scrollState: ScrollState, scrollSource: ScrollSource) => void | OffsetResult) { 332 super(value); 333 } 334 static identity: Symbol = Symbol('scrollOnWillScroll'); 335 applyPeer(node: KNode, reset: boolean): void { 336 if (reset) { 337 getUINativeModule().scroll.resetScrollOnWillScroll(node); 338 } else { 339 getUINativeModule().scroll.setScrollOnWillScroll(node, this.value); 340 } 341 } 342} 343 344class ScrollOnScrollFrameBeginModifier extends ModifierWithKey<(offset: number, state: ScrollState) => 345 { offsetRemain: number }> { 346 constructor(value: (offset: number, state: ScrollState) => 347 { offsetRemain: number }) { 348 super(value); 349 } 350 static identity: Symbol = Symbol('scrollOnScrollFrameBegin'); 351 applyPeer(node: KNode, reset: boolean): void { 352 if (reset) { 353 getUINativeModule().scroll.resetScrollOnScrollFrameBegin(node); 354 } else { 355 getUINativeModule().scroll.setScrollOnScrollFrameBegin(node, this.value); 356 } 357 } 358} 359 360class ArkScrollComponent extends ArkScrollable<ScrollAttribute> implements ScrollAttribute { 361 constructor(nativePtr: KNode, classType?: ModifierType) { 362 super(nativePtr, classType); 363 } 364 initialize(value: Object[]): ScrollAttribute { 365 if (value[0] !== undefined) { 366 modifierWithKey(this._modifiersWithKeys, ScrollInitializeModifier.identity, ScrollInitializeModifier, value[0]); 367 } 368 return this; 369 } 370 allowChildCount(): number { 371 return 1; 372 } 373 scrollable(value: ScrollDirection): this { 374 modifierWithKey(this._modifiersWithKeys, ScrollScrollableModifier.identity, ScrollScrollableModifier, value); 375 return this; 376 } 377 onScroll(event: (xOffset: number, yOffset: number) => void): this { 378 modifierWithKey(this._modifiersWithKeys, ScrollOnScrollModifier.identity, ScrollOnScrollModifier, event); 379 return this; 380 } 381 onScrollEdge(event: (side: Edge) => void): this { 382 modifierWithKey(this._modifiersWithKeys, ScrollOnScrollEdgeModifier.identity, ScrollOnScrollEdgeModifier, event); 383 return this; 384 } 385 onScrollStart(event: () => void): this { 386 modifierWithKey(this._modifiersWithKeys, ScrollOnScrollStartModifier.identity, ScrollOnScrollStartModifier, event); 387 return this; 388 } 389 onScrollEnd(event: () => void): this { 390 modifierWithKey(this._modifiersWithKeys, ScrollOnScrollEndModifier.identity, ScrollOnScrollEndModifier, event); 391 return this; 392 } 393 onScrollStop(event: () => void): this { 394 modifierWithKey(this._modifiersWithKeys, ScrollOnScrollStopModifier.identity, ScrollOnScrollStopModifier, event); 395 return this; 396 } 397 enablePaging(value: boolean): this { 398 modifierWithKey(this._modifiersWithKeys, ScrollEnablePagingModifier.identity, ScrollEnablePagingModifier, value); 399 return this; 400 } 401 scrollBar(value: BarState): this { 402 if (value in BarState) { 403 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarModifier.identity, ScrollScrollBarModifier, value); 404 } else { 405 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarModifier.identity, ScrollScrollBarModifier, undefined); 406 } 407 return this; 408 } 409 scrollBarColor(color: ResourceColor): this { 410 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarColorModifier.identity, ScrollScrollBarColorModifier, color); 411 return this; 412 } 413 scrollBarWidth(value: string | number): this { 414 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarWidthModifier.identity, ScrollScrollBarWidthModifier, value); 415 return this; 416 } 417 onScrollFrameBegin(callback: (offset: number, state: ScrollState) => { offsetRemain: number }): this { 418 modifierWithKey(this._modifiersWithKeys, ScrollOnScrollFrameBeginModifier.identity, ScrollOnScrollFrameBeginModifier, callback); 419 return this; 420 } 421 onWillScroll(callback: (xOffset: number, yOffset: number, 422 scrollState: ScrollState, scrollSource: ScrollSource) => void | OffsetResult): this { 423 modifierWithKey(this._modifiersWithKeys, ScrollOnWillScrollModifier.identity, ScrollOnWillScrollModifier, callback); 424 return this; 425 } 426 427 onDidScroll(callback: (xOffset: number, yOffset: number, scrollState: ScrollState) => void): this { 428 modifierWithKey(this._modifiersWithKeys, ScrollOnDidScrollModifier.identity, ScrollOnDidScrollModifier, callback); 429 return this; 430 } 431 432 nestedScroll(value: NestedScrollOptions): ScrollAttribute { 433 let options = new ArkNestedScrollOptions(); 434 if (value) { 435 if (value.scrollForward) { 436 options.scrollForward = value.scrollForward; 437 } 438 if (value.scrollBackward) { 439 options.scrollBackward = value.scrollBackward; 440 } 441 modifierWithKey(this._modifiersWithKeys, ScrollNestedScrollModifier.identity, ScrollNestedScrollModifier, options); 442 } 443 return this; 444 } 445 enableScrollInteraction(value: boolean): ScrollAttribute { 446 modifierWithKey(this._modifiersWithKeys, ScrollEnableScrollInteractionModifier.identity, ScrollEnableScrollInteractionModifier, value); 447 return this; 448 } 449 friction(value: number | Resource): ScrollAttribute { 450 modifierWithKey(this._modifiersWithKeys, ScrollFrictionModifier.identity, ScrollFrictionModifier, value); 451 return this; 452 } 453 scrollSnap(value: ScrollSnapOptions): ScrollAttribute { 454 let options = new ArkScrollSnapOptions(); 455 if (value) { 456 if (value.snapAlign) { 457 options.snapAlign = value.snapAlign; 458 } 459 if (value.snapPagination) { 460 options.snapPagination = value.snapPagination; 461 } 462 if (value.enableSnapToStart) { 463 options.enableSnapToStart = value.enableSnapToStart; 464 } 465 if (value.enableSnapToEnd) { 466 options.enableSnapToEnd = value.enableSnapToEnd; 467 } 468 modifierWithKey(this._modifiersWithKeys, ScrollScrollSnapModifier.identity, ScrollScrollSnapModifier, options); 469 } 470 return this; 471 } 472 clip(value: boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute): this { 473 modifierWithKey(this._modifiersWithKeys, ScrollClipModifier.identity, ScrollClipModifier, value); 474 return this; 475 } 476 initialOffset(value: OffsetOptions): ScrollAttribute { 477 let options = new ArkScrollOffsetOptions(); 478 if (value) { 479 if (value.xOffset) { 480 options.xOffset = value.xOffset; 481 } 482 if (value.yOffset) { 483 options.yOffset = value.yOffset; 484 } 485 modifierWithKey(this._modifiersWithKeys, ScrollInitialOffsetModifier.identity, ScrollInitialOffsetModifier, options); 486 } 487 return this; 488 } 489 flingSpeedLimit(value: number): this { 490 modifierWithKey(this._modifiersWithKeys, ScrollFlingSpeedLimitModifier.identity, ScrollFlingSpeedLimitModifier, value); 491 return this; 492 } 493} 494// @ts-ignore 495globalThis.Scroll.attributeModifier = function (modifier: ArkComponent): void { 496 attributeModifierFunc.call(this, modifier, (nativePtr: KNode) => { 497 return new ArkScrollComponent(nativePtr); 498 }, (nativePtr: KNode, classType: ModifierType, modifierJS: ModifierJS) => { 499 return new modifierJS.ScrollModifier(nativePtr, classType); 500 }); 501}; 502