• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-2025 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
16if (!('finalizeConstruction' in ViewPU.prototype)) {
17  Reflect.set(ViewPU.prototype, 'finalizeConstruction', () => { });
18}
19const LengthMetrics = requireNapi('arkui.node').LengthMetrics;
20const LengthUnit = requireNapi('arkui.node').LengthUnit;
21const EMPTY_STRING = '';
22const MAX_PROGRESS = 100;
23const MAX_PERCENTAGE = '100%';
24const MIN_PERCENTAGE = '0%';
25const TEXT_OPACITY = 0.4;
26const BUTTON_NORMARL_WIDTH = 44;
27const BUTTON_NORMARL_HEIGHT = 28;
28const BUTTON_BORDER_RADIUS = 14;
29const TEXT_ENABLE = 1.0;
30const PROGRESS_BUTTON_PROGRESS_KEY = 'progress_button_progress_key';
31const PROGRESS_BUTTON_PRIMARY_FONT_KEY = 'progress_button_primary_font_key';
32const PROGRESS_BUTTON_CONTAINER_BACKGROUND_COLOR_KEY = 'progress_button_container_background_color_key';
33const PROGRESS_BUTTON_EMPHASIZE_SECONDARY_BUTTON_KEY = 'progress_button_emphasize_secondary_button_key';
34export class ProgressButton extends ViewPU {
35  constructor(h1, i1, j1, k1 = -1, l1 = undefined, m1) {
36    super(h1, j1, k1, m1);
37    if (typeof l1 === 'function') {
38      this.paramsGenerator_ = l1;
39    }
40    this.__progress = new SynchedPropertySimpleOneWayPU(i1.progress, this, 'progress');
41    this.__textProgress = new ObservedPropertySimplePU(EMPTY_STRING, this, 'textProgress');
42    this.__content = new SynchedPropertyObjectOneWayPU(i1.content, this, 'content');
43    this.__isLoading = new ObservedPropertySimplePU(false, this, 'isLoading');
44    this.progressButtonWidth = BUTTON_NORMARL_WIDTH;
45    this.clickCallback = () => { };
46    this.__enable = new SynchedPropertySimpleOneWayPU(i1.enable, this, 'enable');
47    this.__colorOptions = new SynchedPropertyObjectOneWayPU(i1.colorOptions, this, 'colorOptions');
48    this.__progressButtonRadius = new SynchedPropertyObjectOneWayPU(i1.progressButtonRadius, this, 'progressButtonRadius');
49    this.__progressColor = new ObservedPropertyObjectPU('#330A59F7', this, 'progressColor');
50    this.__containerBorderColor = new ObservedPropertyObjectPU('#330A59F7', this, 'containerBorderColor');
51    this.__containerBackgroundColor = new ObservedPropertyObjectPU({ 'id': -1, 'type': 10001, params: ['sys.color.ohos_id_color_foreground_contrary'], 'bundleName': '__harDefaultBundleName__', 'moduleName': '__harDefaultModuleName__' }, this, 'containerBackgroundColor');
52    this.__textHeight = new ObservedPropertyObjectPU(BUTTON_NORMARL_HEIGHT, this, 'textHeight');
53    this.__buttonBorderRadius = new ObservedPropertySimplePU(BUTTON_BORDER_RADIUS, this, 'buttonBorderRadius');
54    this.setInitiallyProvidedValue(i1);
55    this.declareWatch('progress', this.getProgressContext);
56    this.declareWatch('isLoading', this.getLoadingProgress);
57    this.finalizeConstruction();
58  }
59  setInitiallyProvidedValue(g1) {
60    if (g1.textProgress !== undefined) {
61      this.textProgress = g1.textProgress;
62    }
63    if (g1.content === undefined) {
64      this.__content.set(EMPTY_STRING);
65    }
66    if (g1.isLoading !== undefined) {
67      this.isLoading = g1.isLoading;
68    }
69    if (g1.progressButtonWidth !== undefined) {
70      this.progressButtonWidth = g1.progressButtonWidth;
71    }
72    if (g1.clickCallback !== undefined) {
73      this.clickCallback = g1.clickCallback;
74    }
75    if (g1.enable === undefined) {
76      this.__enable.set(true);
77    }
78    if (g1.colorOptions === undefined) {
79      this.__colorOptions.set(undefined);
80    }
81    if (g1.progressButtonRadius === undefined) {
82      this.__progressButtonRadius.set(undefined);
83    }
84    if (g1.progressColor !== undefined) {
85      this.progressColor = g1.progressColor;
86    }
87    if (g1.containerBorderColor !== undefined) {
88      this.containerBorderColor = g1.containerBorderColor;
89    }
90    if (g1.containerBackgroundColor !== undefined) {
91      this.containerBackgroundColor = g1.containerBackgroundColor;
92    }
93    if (g1.textHeight !== undefined) {
94      this.textHeight = g1.textHeight;
95    }
96    if (g1.buttonBorderRadius !== undefined) {
97      this.buttonBorderRadius = g1.buttonBorderRadius;
98    }
99  }
100  updateStateVars(f1) {
101    this.__progress.reset(f1.progress);
102    this.__content.reset(f1.content);
103    this.__enable.reset(f1.enable);
104    this.__colorOptions.reset(f1.colorOptions);
105    this.__progressButtonRadius.reset(f1.progressButtonRadius);
106  }
107  purgeVariableDependenciesOnElmtId(e1) {
108    this.__progress.purgeDependencyOnElmtId(e1);
109    this.__textProgress.purgeDependencyOnElmtId(e1);
110    this.__content.purgeDependencyOnElmtId(e1);
111    this.__isLoading.purgeDependencyOnElmtId(e1);
112    this.__enable.purgeDependencyOnElmtId(e1);
113    this.__colorOptions.purgeDependencyOnElmtId(e1);
114    this.__progressButtonRadius.purgeDependencyOnElmtId(e1);
115    this.__progressColor.purgeDependencyOnElmtId(e1);
116    this.__containerBorderColor.purgeDependencyOnElmtId(e1);
117    this.__containerBackgroundColor.purgeDependencyOnElmtId(e1);
118    this.__textHeight.purgeDependencyOnElmtId(e1);
119    this.__buttonBorderRadius.purgeDependencyOnElmtId(e1);
120  }
121  aboutToBeDeleted() {
122    this.__progress.aboutToBeDeleted();
123    this.__textProgress.aboutToBeDeleted();
124    this.__content.aboutToBeDeleted();
125    this.__isLoading.aboutToBeDeleted();
126    this.__enable.aboutToBeDeleted();
127    this.__colorOptions.aboutToBeDeleted();
128    this.__progressButtonRadius.aboutToBeDeleted();
129    this.__progressColor.aboutToBeDeleted();
130    this.__containerBorderColor.aboutToBeDeleted();
131    this.__containerBackgroundColor.aboutToBeDeleted();
132    this.__textHeight.aboutToBeDeleted();
133    this.__buttonBorderRadius.aboutToBeDeleted();
134    SubscriberManager.Get().delete(this.id__());
135    this.aboutToBeDeletedInternal();
136  }
137  get progress() {
138    return this.__progress.get();
139  }
140  set progress(d1) {
141    this.__progress.set(d1);
142  }
143  get textProgress() {
144    return this.__textProgress.get();
145  }
146  set textProgress(c1) {
147    this.__textProgress.set(c1);
148  }
149  get content() {
150    return this.__content.get();
151  }
152  set content(b1) {
153    this.__content.set(b1);
154  }
155  get isLoading() {
156    return this.__isLoading.get();
157  }
158  set isLoading(a1) {
159    this.__isLoading.set(a1);
160  }
161  get enable() {
162    return this.__enable.get();
163  }
164  set enable(z) {
165    this.__enable.set(z);
166  }
167  get colorOptions() {
168    return this.__colorOptions.get();
169  }
170  set colorOptions(y) {
171    this.__colorOptions.set(y);
172  }
173  get progressButtonRadius() {
174    return this.__progressButtonRadius.get();
175  }
176  set progressButtonRadius(x) {
177    this.__progressButtonRadius.set(x);
178  }
179  get progressColor() {
180    return this.__progressColor.get();
181  }
182  set progressColor(w) {
183    this.__progressColor.set(w);
184  }
185  get containerBorderColor() {
186    return this.__containerBorderColor.get();
187  }
188  set containerBorderColor(v) {
189    this.__containerBorderColor.set(v);
190  }
191  get containerBackgroundColor() {
192    return this.__containerBackgroundColor.get();
193  }
194  set containerBackgroundColor(u) {
195    this.__containerBackgroundColor.set(u);
196  }
197  get textHeight() {
198    return this.__textHeight.get();
199  }
200  set textHeight(t) {
201    this.__textHeight.set(t);
202  }
203  get buttonBorderRadius() {
204    return this.__buttonBorderRadius.get();
205  }
206  set buttonBorderRadius(s) {
207    this.__buttonBorderRadius.set(s);
208  }
209  onWillApplyTheme(r) {
210    this.progressColor = r.colors.compEmphasizeSecondary;
211    this.containerBorderColor = r.colors.compEmphasizeSecondary;
212    this.containerBackgroundColor = r.colors.iconOnFourth;
213  }
214  getButtonProgress() {
215    if (this.progress < 0) {
216      return 0;
217    }
218    else if (this.progress > MAX_PROGRESS) {
219      return MAX_PROGRESS;
220    }
221    return this.progress;
222  }
223  getProgressContext() {
224    if (this.progress < 0) {
225      this.isLoading = false;
226      this.textProgress = MIN_PERCENTAGE;
227    }
228    else if (this.progress >= MAX_PROGRESS) {
229      this.isLoading = false;
230      this.textProgress = MAX_PERCENTAGE;
231    }
232    else {
233      this.isLoading = true;
234      this.textProgress = Math.floor(this.progress / MAX_PROGRESS * MAX_PROGRESS).toString() + '%';
235    }
236  }
237  getProgressButtonRadius() {
238    if (!this.progressButtonRadius || this.progressButtonRadius.unit === LengthUnit.PERCENT) {
239      return LengthMetrics.vp(this.buttonBorderRadius);
240    }
241    else if (this.progressButtonRadius.value < 0) {
242      return LengthMetrics.vp(0);
243    }
244    else {
245      return this.progressButtonRadius;
246    }
247  }
248  getLoadingProgress() {
249    if (this.isLoading) {
250      if (this.progress < 0) {
251        this.textProgress = MIN_PERCENTAGE;
252      }
253      else if (this.progress >= MAX_PROGRESS) {
254        this.textProgress = MAX_PERCENTAGE;
255      }
256      else {
257        this.textProgress = Math.floor(this.progress / MAX_PROGRESS * MAX_PROGRESS).toString() + '%';
258      }
259    }
260  }
261  toLengthString(o) {
262    if (o === void (0)) {
263      return '';
264    }
265    const p = o.value;
266    let q = '';
267    switch (o.unit) {
268      case LengthUnit.PX:
269        q = `${p}px`;
270        break;
271      case LengthUnit.FP:
272        q = `${p}fp`;
273        break;
274      case LengthUnit.LPX:
275        q = `${p}lpx`;
276        break;
277      case LengthUnit.PERCENT:
278        q = `${p * 100}%`;
279        break;
280      case LengthUnit.VP:
281        q = `${p}vp`;
282        break;
283      default:
284        q = `${p}vp`;
285        break;
286    }
287    return q;
288  }
289  initialRender() {
290    this.observeComponentCreation2((m, n) => {
291      Button.createWithChild();
292      Button.borderRadius(this.progressButtonRadius ? this.toLengthString(this.getProgressButtonRadius()) :
293      this.buttonBorderRadius);
294      Button.clip(false);
295      Button.hoverEffect(HoverEffect.None);
296      Button.key(PROGRESS_BUTTON_EMPHASIZE_SECONDARY_BUTTON_KEY);
297      Button.backgroundColor(this.colorOptions?.backgroundColor
298        ? this.colorOptions?.backgroundColor
299        : this.containerBackgroundColor);
300      Button.constraintSize({ minWidth: 44 });
301      Button.padding({ top: 0, bottom: 0 });
302      Button.width((!this.progressButtonWidth || this.progressButtonWidth < BUTTON_NORMARL_WIDTH) ?
303        BUTTON_NORMARL_WIDTH : this.progressButtonWidth);
304      Button.stateEffect(this.enable);
305      Button.onClick(() => {
306        if (!this.enable) {
307          return;
308        }
309        if (this.progress < MAX_PROGRESS) {
310          this.isLoading = !this.isLoading;
311        }
312        this.clickCallback && this.clickCallback();
313      });
314    }, Button);
315    this.observeComponentCreation2((k, l) => {
316      Stack.create();
317    }, Stack);
318    this.observeComponentCreation2((i, j) => {
319      Progress.create({ value: this.getButtonProgress(), total: MAX_PROGRESS,
320        style: ProgressStyle.Capsule });
321      Progress.height(ObservedObject.GetRawObject(this.textHeight));
322      Progress.constraintSize({ minHeight: BUTTON_NORMARL_HEIGHT });
323      Progress.borderRadius(this.buttonBorderRadius);
324      Progress.width('100%');
325      Progress.hoverEffect(HoverEffect.None);
326      Progress.style({
327        borderColor: this.colorOptions?.borderColor ? this.colorOptions?.borderColor : this.containerBorderColor,
328        borderRadius: this.getProgressButtonRadius()
329      });
330      Progress.clip(false);
331      Progress.key(PROGRESS_BUTTON_PROGRESS_KEY);
332      Progress.color(this.colorOptions?.progressColor ? this.colorOptions?.progressColor : this.progressColor);
333    }, Progress);
334    this.observeComponentCreation2((g, h) => {
335      Row.create();
336      Row.constraintSize({ minHeight: BUTTON_NORMARL_HEIGHT });
337    }, Row);
338    this.observeComponentCreation2((c, d) => {
339      Text.create(this.isLoading ? this.textProgress : this.content);
340      Text.fontSize({ 'id': -1, 'type': 10002, params: ['sys.float.ohos_id_text_size_button3'], 'bundleName': '__harDefaultBundleName__', 'moduleName': '__harDefaultModuleName__' });
341      Text.fontWeight(FontWeight.Medium);
342      Text.key(PROGRESS_BUTTON_PRIMARY_FONT_KEY);
343      Text.fontColor(this.colorOptions?.textColor);
344      Text.maxLines(1);
345      Text.textOverflow({ overflow: TextOverflow.Ellipsis });
346      Text.padding({ top: 4, left: 8, right: 8, bottom: 4 });
347      Text.opacity(this.enable ? TEXT_ENABLE : TEXT_OPACITY);
348      Text.onAreaChange((e, f) => {
349        if (!f.height || f.height === this.textHeight) {
350          return;
351        }
352        this.textHeight = f.height > BUTTON_NORMARL_HEIGHT ? f.height : BUTTON_NORMARL_HEIGHT;
353        this.buttonBorderRadius = Number(this.textHeight) / 2;
354      });
355    }, Text);
356    Text.pop();
357    Row.pop();
358    this.observeComponentCreation2((a, b) => {
359      Row.create();
360      Row.key(PROGRESS_BUTTON_CONTAINER_BACKGROUND_COLOR_KEY);
361      Row.backgroundColor(Color.Transparent);
362      Row.border({
363        width: 1,
364        color: this.colorOptions?.borderColor ? this.colorOptions?.borderColor : this.containerBorderColor
365      });
366      Row.height(ObservedObject.GetRawObject(this.textHeight));
367      Row.constraintSize({ minHeight: BUTTON_NORMARL_HEIGHT });
368      Row.borderRadius(this.progressButtonRadius ? this.toLengthString(this.getProgressButtonRadius()) :
369      this.buttonBorderRadius);
370      Row.width('100%');
371    }, Row);
372    Row.pop();
373    Stack.pop();
374    Button.pop();
375  }
376  rerender() {
377    this.updateDirtyElements();
378  }
379}
380
381export default { ProgressButton };