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' /> 17const TITLE_MODE_RANGE = 2; 18const NAV_BAR_POSITION_RANGE = 1; 19const NAVIGATION_MODE_RANGE = 2; 20const DEFAULT_NAV_BAR_WIDTH = 240; 21const MIN_NAV_BAR_WIDTH_DEFAULT = '240vp'; 22const MAX_NAV_BAR_WIDTH_DEFAULT = '40%'; 23const NAVIGATION_TITLE_MODE_DEFAULT = 0; 24const DEFAULT_UNIT = 'vp'; 25const NAV_SAFE_AREA_TYPE_LIMIT = 3; 26const NAV_SAFE_AREA_EDGE_LIMIT = 4; 27const NAV_SAFE_AREA_LOWER_LIMIT = 0; 28 29class ArkNavigationComponent extends ArkComponent implements NavigationAttribute { 30 constructor(nativePtr: KNode, classType?: ModifierType) { 31 super(nativePtr, classType); 32 } 33 navBarWidth(value: Length): NavigationAttribute { 34 modifierWithKey(this._modifiersWithKeys, NavBarWidthModifier.identity, NavBarWidthModifier, value); 35 return this; 36 } 37 navBarPosition(value: number): NavigationAttribute { 38 modifierWithKey(this._modifiersWithKeys, NavBarPositionModifier.identity, NavBarPositionModifier, value); 39 return this; 40 } 41 navBarWidthRange(value: [Dimension, Dimension]): NavigationAttribute { 42 modifierWithKey(this._modifiersWithKeys, NavBarWidthRangeModifier.identity, NavBarWidthRangeModifier, value); 43 return this; 44 } 45 minContentWidth(value: Dimension): NavigationAttribute { 46 modifierWithKey(this._modifiersWithKeys, MinContentWidthModifier.identity, MinContentWidthModifier, value); 47 48 return this; 49 } 50 mode(value: number): NavigationAttribute { 51 modifierWithKey(this._modifiersWithKeys, ModeModifier.identity, ModeModifier, value); 52 return this; 53 } 54 backButtonIcon(value: any): NavigationAttribute { 55 modifierWithKey(this._modifiersWithKeys, BackButtonIconModifier.identity, BackButtonIconModifier, value); 56 return this; 57 } 58 hideNavBar(value: boolean): NavigationAttribute { 59 modifierWithKey(this._modifiersWithKeys, HideNavBarModifier.identity, HideNavBarModifier, value); 60 return this; 61 } 62 title(value: ResourceStr | CustomBuilder | NavigationCommonTitle | NavigationCustomTitle | undefined, 63 options?: NavigationTitleOptions): NavigationAttribute { 64 if (isUndefined(value) || isNull(value)) { 65 modifierWithKey(this._modifiersWithKeys, TitleModifier.identity, 66 TitleModifier, undefined); 67 return this; 68 } 69 let arkNavigationTitle = new ArkNavigationTitle(); 70 arkNavigationTitle.value = value; 71 if (!isUndefined(options) && !isNull(options) && isObject(options)) { 72 if (Object.keys(options).length !== 0) { 73 arkNavigationTitle.navigationTitleOptions = options; 74 } 75 } 76 modifierWithKey(this._modifiersWithKeys, TitleModifier.identity, 77 TitleModifier, arkNavigationTitle); 78 return this; 79 } 80 subTitle(value: string): NavigationAttribute { 81 modifierWithKey(this._modifiersWithKeys, SubTitleModifier.identity, SubTitleModifier, value); 82 return this; 83 } 84 hideTitleBar(isHide: boolean, animated?: boolean): NavigationAttribute { 85 let arkNavigationHideTitleBar = new ArkNavHideTitleBarOrToolBar(); 86 if (!isUndefined(isHide) && !isNull(isHide)) { 87 arkNavigationHideTitleBar.isHide = isHide; 88 } 89 if (!isUndefined(animated) && !isNull(animated)) { 90 arkNavigationHideTitleBar.animated = animated; 91 } 92 if (arkNavigationHideTitleBar.isHide === undefined && arkNavigationHideTitleBar.animated === undefined) { 93 modifierWithKey(this._modifiersWithKeys, NavigationHideTitleBarModifier.identity, NavigationHideTitleBarModifier, undefined); 94 } else { 95 modifierWithKey(this._modifiersWithKeys, NavigationHideTitleBarModifier.identity, NavigationHideTitleBarModifier, arkNavigationHideTitleBar); 96 } 97 return this; 98 } 99 hideBackButton(value: boolean): NavigationAttribute { 100 modifierWithKey(this._modifiersWithKeys, HideBackButtonModifier.identity, HideBackButtonModifier, value); 101 return this; 102 } 103 titleMode(value: NavigationTitleMode): NavigationAttribute { 104 modifierWithKey(this._modifiersWithKeys, TitleModeModifier.identity, TitleModeModifier, value); 105 return this; 106 } 107 menus(value: Array<NavigationMenuItem> | undefined): NavigationAttribute { 108 if (isUndefined(value)) { 109 modifierWithKey(this._modifiersWithKeys, MenusModifier.identity, MenusModifier, undefined); 110 return this; 111 } 112 modifierWithKey(this._modifiersWithKeys, MenusModifier.identity, MenusModifier, value); 113 return this; 114 } 115 toolBar(value: any): NavigationAttribute { 116 throw new Error('Method not implemented.'); 117 } 118 toolbarConfiguration(value: any): NavigationAttribute { 119 throw new Error('Method not implemented.'); 120 } 121 hideToolBar(isHide: boolean, animated?: boolean): NavigationAttribute { 122 let arkNavigationHideToolBar = new ArkNavHideTitleBarOrToolBar(); 123 if (!isUndefined(isHide) && !isNull(isHide)) { 124 arkNavigationHideToolBar.isHide = isHide; 125 } 126 if (!isUndefined(animated) && !isNull(animated)) { 127 arkNavigationHideToolBar.animated = animated; 128 } 129 if (arkNavigationHideToolBar.isHide === undefined && arkNavigationHideToolBar.animated === undefined) { 130 modifierWithKey(this._modifiersWithKeys, HideToolBarModifier.identity, HideToolBarModifier, undefined); 131 } else { 132 modifierWithKey(this._modifiersWithKeys, HideToolBarModifier.identity, HideToolBarModifier, arkNavigationHideToolBar); 133 } 134 return this; 135 } 136 onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void): NavigationAttribute { 137 throw new Error('Method not implemented.'); 138 } 139 onNavBarStateChange(callback: (isVisible: boolean) => void): NavigationAttribute { 140 throw new Error('Method not implemented.'); 141 } 142 onNavigationModeChange(callback: (mode: NavigationMode) => void): NavigationAttribute { 143 throw new Error('Method not implemented.'); 144 } 145 navDestination(builder: (name: string, param: unknown) => void): NavigationAttribute { 146 throw new Error('Method not implemented.'); 147 } 148 ignoreLayoutSafeArea(types?: Array<SafeAreaType>, edges?: Array<SafeAreaEdge>): NavigationAttribute { 149 let opts = new ArkSafeAreaExpandOpts(); 150 if (types && types.length >= 0) { 151 let safeAreaType: string | number = ''; 152 for (let param of types) { 153 if (!isNumber(param) || param >= NAV_SAFE_AREA_TYPE_LIMIT || param < NAV_SAFE_AREA_LOWER_LIMIT) { 154 safeAreaType = undefined; 155 break; 156 } 157 if (safeAreaType) { 158 safeAreaType += '|'; 159 safeAreaType += param.toString(); 160 } else { 161 safeAreaType += param.toString(); 162 } 163 } 164 opts.type = safeAreaType; 165 } 166 if (edges && edges.length >= 0) { 167 let safeAreaEdge: string | number = ''; 168 for (let param of edges) { 169 if (!isNumber(param) || param >= NAV_SAFE_AREA_EDGE_LIMIT || param < NAV_SAFE_AREA_LOWER_LIMIT) { 170 safeAreaEdge = undefined; 171 break; 172 } 173 if (safeAreaEdge) { 174 safeAreaEdge += '|'; 175 safeAreaEdge += param.toString(); 176 } else { 177 safeAreaEdge += param.toString(); 178 } 179 } 180 opts.edges = safeAreaEdge; 181 } 182 if (opts.type === undefined && opts.edges === undefined) { 183 modifierWithKey(this._modifiersWithKeys, IgnoreNavLayoutSafeAreaModifier.identity, IgnoreNavLayoutSafeAreaModifier, undefined); 184 } else { 185 modifierWithKey(this._modifiersWithKeys, IgnoreNavLayoutSafeAreaModifier.identity, IgnoreNavLayoutSafeAreaModifier, opts); 186 } 187 return this; 188 } 189 190 enableDargBar(value: boolean | undefined): NavigationAttribute { 191 modifierWithKey(this._modifiersWithKeys, NavigationEnableDragBarModifier.identity, NavigationEnableDragBarModifier, value); 192 return this; 193 } 194 recoverable(value: boolean | undefined): NavigationAttribute { 195 modifierWithKey(this._modifiersWithKeys, NavigationRecoverableModifier.identity, NavigationRecoverableModifier, value); 196 return this; 197 } 198} 199 200class BackButtonIconModifier extends ModifierWithKey<boolean | object> { 201 static identity: Symbol = Symbol('backButtonIcon'); 202 applyPeer(node: KNode, reset: boolean): void { 203 if (reset) { 204 getUINativeModule().navigation.resetBackButtonIcon(node); 205 } else { 206 getUINativeModule().navigation.setBackButtonIcon(node, this.value); 207 } 208 } 209 210 checkObjectDiff(): boolean { 211 return !isBaseOrResourceEqual(this.stageValue, this.value); 212 } 213} 214 215class NavBarWidthRangeModifier extends ModifierWithKey<[Dimension, Dimension]> { 216 static identity: Symbol = Symbol('navBarWidthRange'); 217 applyPeer(node: KNode, reset: boolean): void { 218 if (reset) { 219 getUINativeModule().navigation.resetNavBarWidthRange(node); 220 } else { 221 getUINativeModule().navigation.setNavBarWidthRange(node, this.value); 222 } 223 } 224 225 checkObjectDiff(): boolean { 226 return !isBaseOrResourceEqual(this.stageValue, this.value); 227 } 228} 229 230class MinContentWidthModifier extends ModifierWithKey<Dimension> { 231 static identity: Symbol = Symbol('minContentWidth'); 232 233 applyPeer(node: KNode, reset: boolean): void { 234 if (reset) { 235 getUINativeModule().navigation.resetMinContentWidth(node); 236 } else { 237 getUINativeModule().navigation.setMinContentWidth(node, this.value); 238 } 239 } 240 241 checkObjectDiff(): boolean { 242 return !isBaseOrResourceEqual(this.stageValue, this.value); 243 } 244} 245 246class NavBarWidthModifier extends ModifierWithKey<Length> { 247 static identity: Symbol = Symbol('navBarWidth'); 248 249 applyPeer(node: KNode, reset: boolean): void { 250 if (reset) { 251 getUINativeModule().navigation.resetNavBarWidth(node); 252 } else { 253 getUINativeModule().navigation.setNavBarWidth(node, this.value); 254 } 255 } 256 257 checkObjectDiff(): boolean { 258 return !isBaseOrResourceEqual(this.stageValue, this.value); 259 } 260} 261 262class NavBarPositionModifier extends ModifierWithKey<number> { 263 static identity: Symbol = Symbol('navBarPosition'); 264 265 applyPeer(node: KNode, reset: boolean): void { 266 if (reset) { 267 getUINativeModule().navigation.resetNavBarPosition(node); 268 } else { 269 getUINativeModule().navigation.setNavBarPosition(node, this.value); 270 } 271 } 272} 273 274class ModeModifier extends ModifierWithKey<number> { 275 static identity: Symbol = Symbol('mode'); 276 277 applyPeer(node: KNode, reset: boolean): void { 278 if (reset) { 279 getUINativeModule().navigation.resetMode(node); 280 } else { 281 getUINativeModule().navigation.setMode(node, this.value); 282 } 283 } 284} 285 286class HideToolBarModifier extends ModifierWithKey<ArkNavHideTitleBarOrToolBar | undefined> { 287 constructor(value: ArkNavHideTitleBarOrToolBar) { 288 super(value); 289 } 290 291 static identity: Symbol = Symbol('hideToolBar'); 292 293 applyPeer(node: KNode, reset: boolean): void { 294 if (reset) { 295 getUINativeModule().navigation.resetHideToolBar(node); 296 } else { 297 getUINativeModule().navigation.setHideToolBar(node, this.value?.isHide, this.value?.animated); 298 } 299 } 300} 301 302class TitleModeModifier extends ModifierWithKey<number> { 303 static identity: Symbol = Symbol('titleMode'); 304 305 applyPeer(node: KNode, reset: boolean): void { 306 if (reset) { 307 getUINativeModule().navigation.resetTitleMode(node); 308 } else { 309 getUINativeModule().navigation.setTitleMode(node, this.value); 310 } 311 } 312} 313 314class MenusModifier extends ModifierWithKey<Array<NavigationMenuItem> | undefined> { 315 constructor(value: Array<NavigationMenuItem> | undefined) { 316 super(value); 317 } 318 static identity: Symbol = Symbol('menus'); 319 320 applyPeer(node: KNode, reset: boolean): void { 321 if (reset) { 322 getUINativeModule().navigation.resetMenus(node); 323 } else { 324 getUINativeModule().navigation.setMenus(node, this.value); 325 } 326 } 327 328 checkObjectDiff(): boolean { 329 if (!Array.isArray(this.value) || !Array.isArray(this.stageValue)) { 330 return true; 331 } 332 if (this.value.length !== this.stageValue.length) { 333 return true; 334 } 335 for (let i = 0; i < this.value.length; i++) { 336 if (!(isBaseOrResourceEqual(this.stageValue[i].value, this.value[i].value) && 337 isBaseOrResourceEqual(this.stageValue[i].icon, this.value[i].icon) && 338 isBaseOrResourceEqual(this.stageValue[i].isEnabled, this.value[i].isEnabled) && 339 isBaseOrResourceEqual(this.stageValue[i].action, this.value[i].action) && 340 isBaseOrResourceEqual(this.stageValue[i].symbolIcon, this.value[i].symbolIcon) 341 )) { 342 return true; 343 } 344 } 345 return false; 346 } 347} 348 349class HideBackButtonModifier extends ModifierWithKey<boolean> { 350 static identity: Symbol = Symbol('hideBackButton'); 351 352 applyPeer(node: KNode, reset: boolean): void { 353 if (reset) { 354 getUINativeModule().navigation.resetHideBackButton(node); 355 } else { 356 getUINativeModule().navigation.setHideBackButton(node, this.value); 357 } 358 } 359} 360 361class TitleModifier extends ModifierWithKey<ArkNavigationTitle | undefined> { 362 constructor(value: ArkNavigationTitle | undefined) { 363 super(value); 364 } 365 static identity: Symbol = Symbol('title'); 366 applyPeer(node: KNode, reset: boolean): void { 367 if (reset) { 368 getUINativeModule().navigation.resetTitle(node); 369 } else { 370 getUINativeModule().navigation.setTitle(node, this.value?.value, this.value?.navigationTitleOptions); 371 } 372 } 373 checkObjectDiff(): boolean { 374 return !this.value.isEqual(this.stageValue); 375 } 376} 377 378class SubTitleModifier extends ModifierWithKey<string> { 379 static identity: Symbol = Symbol('subTitle'); 380 381 applyPeer(node: KNode, reset: boolean): void { 382 if (reset) { 383 getUINativeModule().navigation.resetSubTitle(node); 384 } else { 385 getUINativeModule().navigation.setSubTitle(node, this.value); 386 } 387 } 388} 389 390class NavigationHideTitleBarModifier extends ModifierWithKey<ArkNavHideTitleBarOrToolBar | undefined> { 391 constructor(value: ArkNavHideTitleBarOrToolBar) { 392 super(value); 393 } 394 395 static identity: Symbol = Symbol('hideTitleBar'); 396 397 applyPeer(node: KNode, reset: boolean): void { 398 if (reset) { 399 getUINativeModule().navigation.resetHideTitleBar(node); 400 } else { 401 getUINativeModule().navigation.setHideTitleBar(node, this.value?.isHide, this.value?.animated); 402 } 403 } 404} 405 406class HideNavBarModifier extends ModifierWithKey<boolean> { 407 static identity: Symbol = Symbol('hideNavBar'); 408 409 applyPeer(node: KNode, reset: boolean): void { 410 if (reset) { 411 getUINativeModule().navigation.resetHideNavBar(node); 412 } else { 413 getUINativeModule().navigation.setHideNavBar(node, this.value); 414 } 415 } 416} 417 418class IgnoreNavLayoutSafeAreaModifier extends ModifierWithKey<ArkSafeAreaExpandOpts | undefined> { 419 constructor(value: ArkSafeAreaExpandOpts | undefined) { 420 super(value); 421 } 422 static identity: Symbol = Symbol('ignoreLayoutSafeArea'); 423 applyPeer(node: KNode, reset: boolean): void { 424 if (reset) { 425 getUINativeModule().navigation.resetIgnoreLayoutSafeArea(node); 426 } else { 427 getUINativeModule().navigation.setIgnoreLayoutSafeArea(node, this.value.type, this.value.edges); 428 } 429 } 430 checkObjectDiff(): boolean { 431 return !isBaseOrResourceEqual(this.stageValue.type, this.value.type) || 432 !isBaseOrResourceEqual(this.stageValue.edges, this.value.edges); 433 } 434} 435 436class NavigationEnableDragBarModifier extends ModifierWithKey<boolean | undefined> { 437 constructor(value: boolean | undefined) { 438 super(value); 439 } 440 static identity: Symbol = Symbol('enableDragBar'); 441 442 applyPeer(node: KNode, reset: boolean): void { 443 if (reset) { 444 getUINativeModule().navigation.resetEnableDragBar(node); 445 } else { 446 getUINativeModule().navigation.setEnableDragBar(node, this.value); 447 } 448 } 449} 450 451class NavigationRecoverableModifier extends ModifierWithKey<boolean | undefined> { 452 constructor(value: boolean | undefined) { 453 super(value); 454 } 455 static identity: Symbol = Symbol('recoverable'); 456 457 applyPeer(node: KNode, reset: boolean): void { 458 if (reset) { 459 getUINativeModule().navigation.resetRecoverable(node); 460 } else { 461 getUINativeModule().navigation.setRecoverable(node, this.value); 462 } 463 } 464} 465 466// @ts-ignore 467globalThis.Navigation.attributeModifier = function (modifier: ArkComponent): void { 468 attributeModifierFunc.call(this, modifier, (nativePtr: KNode) => { 469 return new ArkNavigationComponent(nativePtr); 470 }, (nativePtr: KNode, classType: ModifierType, modifierJS: ModifierJS) => { 471 return new modifierJS.NavigationModifier(nativePtr, classType); 472 }); 473}; 474