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 18class ScrollNestedScrollModifier extends ModifierWithKey<ArkNestedScrollOptions> { 19 static identity: symbol = Symbol('nestedScroll'); 20 applyPeer(node: KNode, reset: boolean): void { 21 if (reset) { 22 getUINativeModule().scroll.resetNestedScroll(node); 23 } else { 24 getUINativeModule().scroll.setNestedScroll(node, this.value.scrollForward, this.value.scrollBackward); 25 } 26 } 27 28 checkObjectDiff(): boolean { 29 return !isBaseOrResourceEqual(this.stageValue.scrollForward, this.value.scrollForward) || 30 !isBaseOrResourceEqual(this.stageValue.scrollBackward, this.value.scrollBackward); 31 } 32} 33 34class ScrollEnableScrollInteractionModifier extends ModifierWithKey<boolean> { 35 static identity: symbol = Symbol('enableScrollInteraction'); 36 applyPeer(node: KNode, reset: boolean): void { 37 if (reset) { 38 getUINativeModule().scroll.resetEnableScroll(node); 39 } else { 40 getUINativeModule().scroll.setEnableScroll(node, this.value); 41 } 42 } 43 44 checkObjectDiff(): boolean { 45 return !isBaseOrResourceEqual(this.stageValue, this.value); 46 } 47} 48 49class ScrollFrictionModifier extends ModifierWithKey<number | Resource> { 50 static identity: symbol = Symbol('friction'); 51 applyPeer(node: KNode, reset: boolean): void { 52 if (reset) { 53 getUINativeModule().scroll.resetFriction(node); 54 } else { 55 getUINativeModule().scroll.setFriction(node, this.value); 56 } 57 } 58 59 checkObjectDiff(): boolean { 60 return !isBaseOrResourceEqual(this.stageValue, this.value); 61 } 62} 63 64class ScrollScrollSnapModifier extends ModifierWithKey<ArkScrollSnapOptions> { 65 static identity: symbol = Symbol('scrollSnap'); 66 applyPeer(node: KNode, reset: boolean): void { 67 if (reset) { 68 getUINativeModule().scroll.resetScrollSnap(node); 69 } else { 70 let snapPagination = []; 71 let isArray = true; 72 if (Array.isArray(this.value.snapPagination)) { 73 for (let i = 0; i <= this.value.snapPagination.length; i++) { 74 let item = this.value.snapPagination[i]; 75 snapPagination.push(item); 76 } 77 } else { 78 isArray = false; 79 } 80 81 if (isArray) { 82 getUINativeModule().scroll.setScrollSnap(node, this.value.snapAlign, snapPagination, this.value.enableSnapToStart, this.value.enableSnapToEnd); 83 } else { 84 getUINativeModule().scroll.setScrollSnap(node, this.value.snapAlign, 85 this.value.snapPagination, this.value.enableSnapToStart, this.value.enableSnapToEnd); 86 } 87 } 88 } 89 90 checkObjectDiff(): boolean { 91 return !((this.stageValue.snapAlign === this.value.snapAlign) && 92 (this.stageValue.enableSnapToStart === this.value.enableSnapToStart) && 93 (this.stageValue.enableSnapToEnd === this.value.enableSnapToEnd) && 94 (this.stageValue.snapPagination === this.value.snapPagination)); 95 } 96} 97 98class ScrollScrollBarModifier extends ModifierWithKey<number> { 99 static identity: symbol = Symbol('scrollBar'); 100 applyPeer(node: KNode, reset: boolean): void { 101 if (reset) { 102 getUINativeModule().scroll.resetScrollBar(node); 103 } else { 104 getUINativeModule().scroll.setScrollBar(node, this.value); 105 } 106 } 107 checkObjectDiff(): boolean { 108 return !isBaseOrResourceEqual(this.stageValue, this.value); 109 } 110} 111 112class ScrollScrollableModifier extends ModifierWithKey<ScrollDirection> { 113 constructor(value: ScrollDirection) { 114 super(value); 115 } 116 static identity: Symbol = Symbol('scrollable'); 117 applyPeer(node: KNode, reset: boolean): void { 118 if (reset) { 119 getUINativeModule().scroll.resetScrollable(node); 120 } else { 121 getUINativeModule().scroll.setScrollable(node, this.value); 122 } 123 } 124 125 checkObjectDiff(): boolean { 126 return this.stageValue !== this.value; 127 } 128} 129 130class ScrollEdgeEffectModifier extends ModifierWithKey<ArkScrollEdgeEffect> { 131 constructor(value: ArkScrollEdgeEffect) { 132 super(value); 133 } 134 static identity: Symbol = Symbol('edgeEffect'); 135 applyPeer(node: KNode, reset: boolean): void { 136 if (reset) { 137 getUINativeModule().scroll.resetEdgeEffect(node); 138 } else { 139 getUINativeModule().scroll.setEdgeEffect(node, this.value.value, this.value.options?.alwaysEnabled); 140 } 141 } 142 143 checkObjectDiff(): boolean { 144 return !((this.stageValue.value === this.value.value) && 145 (this.stageValue.options === this.value.options)); 146 } 147} 148 149class ScrollScrollBarWidthModifier extends ModifierWithKey<string | number> { 150 constructor(value: string | number) { 151 super(value); 152 } 153 static identity: Symbol = Symbol('scrollBarWidth'); 154 applyPeer(node: KNode, reset: boolean): void { 155 if (reset) { 156 getUINativeModule().scroll.resetScrollBarWidth(node); 157 } else { 158 getUINativeModule().scroll.setScrollBarWidth(node, this.value); 159 } 160 } 161 162 checkObjectDiff(): boolean { 163 return this.stageValue !== this.value; 164 } 165} 166 167class ScrollScrollBarColorModifier extends ModifierWithKey<ResourceColor> { 168 constructor(value: ResourceColor) { 169 super(value); 170 } 171 static identity: Symbol = Symbol('scrollBarColor'); 172 applyPeer(node: KNode, reset: boolean): void { 173 if (reset) { 174 getUINativeModule().scroll.resetScrollBarColor(node); 175 } else { 176 getUINativeModule().scroll.setScrollBarColor(node, this.value); 177 } 178 } 179 180 checkObjectDiff(): boolean { 181 return !isBaseOrResourceEqual(this.stageValue, this.value); 182 } 183} 184 185class ScrollEnablePagingModifier extends ModifierWithKey<boolean> { 186 constructor(value: boolean) { 187 super(value); 188 } 189 static identity: Symbol = Symbol('scrollEnablePaging'); 190 applyPeer(node: KNode, reset: boolean): void { 191 if (reset) { 192 getUINativeModule().scroll.resetEnablePaging(node); 193 } else { 194 getUINativeModule().scroll.setEnablePaging(node, this.value); 195 } 196 } 197} 198 199class ScrollClipModifier extends ModifierWithKey<boolean | object> { 200 constructor(value: boolean | object) { 201 super(value); 202 } 203 static identity: Symbol = Symbol('scrollClip'); 204 applyPeer(node: KNode, reset: boolean): void { 205 if (reset) { 206 getUINativeModule().common.resetClipWithEdge(node); 207 } else { 208 getUINativeModule().common.setClipWithEdge(node, this.value); 209 } 210 } 211 212 checkObjectDiff(): boolean { 213 return true; 214 } 215} 216 217 218class ArkScrollComponent extends ArkComponent implements ScrollAttribute { 219 constructor(nativePtr: KNode) { 220 super(nativePtr); 221 } 222 onGestureJudgeBegin(callback: (gestureInfo: GestureInfo, event: BaseGestureEvent) => GestureJudgeResult): this { 223 throw new Error('Method not implemented.'); 224 } 225 scrollable(value: ScrollDirection): this { 226 modifierWithKey(this._modifiersWithKeys, ScrollScrollableModifier.identity, ScrollScrollableModifier, value); 227 return this; 228 } 229 onScroll(event: (xOffset: number, yOffset: number) => void): this { 230 throw new Error('Method not implemented.'); 231 } 232 onScrollEdge(event: (side: Edge) => void): this { 233 throw new Error('Method not implemented.'); 234 } 235 onScrollStart(event: () => void): this { 236 throw new Error('Method not implemented.'); 237 } 238 onScrollEnd(event: () => void): this { 239 throw new Error('Method not implemented.'); 240 } 241 onScrollStop(event: () => void): this { 242 throw new Error('Method not implemented.'); 243 } 244 enablePaging(value: boolean): this { 245 modifierWithKey(this._modifiersWithKeys, ScrollEnablePagingModifier.identity, ScrollEnablePagingModifier, value); 246 return this; 247 } 248 scrollBar(value: BarState): this { 249 if (value in BarState) { 250 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarModifier.identity, ScrollScrollBarModifier, value); 251 } else { 252 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarModifier.identity, ScrollScrollBarModifier, undefined); 253 } 254 return this; 255 } 256 scrollBarColor(color: ResourceColor): this { 257 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarColorModifier.identity, ScrollScrollBarColorModifier, color); 258 return this; 259 } 260 scrollBarWidth(value: string | number): this { 261 modifierWithKey(this._modifiersWithKeys, ScrollScrollBarWidthModifier.identity, ScrollScrollBarWidthModifier, value); 262 return this; 263 } 264 edgeEffect(value: EdgeEffect, options?: EdgeEffectOptions): this { 265 let effect: ArkScrollEdgeEffect = new ArkScrollEdgeEffect(); 266 effect.value = value; 267 effect.options = options; 268 modifierWithKey(this._modifiersWithKeys, ScrollEdgeEffectModifier.identity, ScrollEdgeEffectModifier, effect); 269 return this; 270 } 271 onScrollFrameBegin(event: (offset: number, state: ScrollState) => { offsetRemain: number; }): this { 272 throw new Error('Method not implemented.'); 273 } 274 nestedScroll(value: NestedScrollOptions): ScrollAttribute { 275 let options = new ArkNestedScrollOptions(); 276 if (value) { 277 if (value.scrollForward) { 278 options.scrollForward = value.scrollForward; 279 } 280 if (value.scrollBackward) { 281 options.scrollBackward = value.scrollBackward; 282 } 283 modifierWithKey(this._modifiersWithKeys, ScrollNestedScrollModifier.identity, ScrollNestedScrollModifier, options); 284 } 285 return this; 286 } 287 enableScrollInteraction(value: boolean): ScrollAttribute { 288 modifierWithKey(this._modifiersWithKeys, ScrollEnableScrollInteractionModifier.identity, ScrollEnableScrollInteractionModifier, value); 289 return this; 290 } 291 friction(value: number | Resource): ScrollAttribute { 292 modifierWithKey(this._modifiersWithKeys, ScrollFrictionModifier.identity, ScrollFrictionModifier, value); 293 return this; 294 } 295 scrollSnap(value: ScrollSnapOptions): ScrollAttribute { 296 let options = new ArkScrollSnapOptions(); 297 if (value) { 298 if (value.snapAlign) { 299 options.snapAlign = value.snapAlign; 300 } 301 if (value.snapPagination) { 302 options.snapPagination = value.snapPagination; 303 } 304 if (value.enableSnapToStart) { 305 options.enableSnapToStart = value.enableSnapToStart; 306 } 307 if (value.enableSnapToEnd) { 308 options.enableSnapToEnd = value.enableSnapToEnd; 309 } 310 modifierWithKey(this._modifiersWithKeys, ScrollScrollSnapModifier.identity, ScrollScrollSnapModifier, options); 311 } 312 return this; 313 } 314 clip(value: boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute): this { 315 modifierWithKey(this._modifiersWithKeys, ScrollClipModifier.identity, ScrollClipModifier, value); 316 return this; 317 } 318} 319// @ts-ignore 320globalThis.Scroll.attributeModifier = function (modifier) { 321 const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); 322 let nativeNode = getUINativeModule().getFrameNodeById(elmtId); 323 let component = this.createOrGetNode(elmtId, () => { 324 return new ArkScrollComponent(nativeNode); 325 }); 326 applyUIAttributes(modifier, nativeNode, component); 327 component.applyModifierPatch(); 328};