jsbox-cview 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/components/alert/input-alert.ts +73 -0
  4. package/components/alert/login-alert.ts +75 -0
  5. package/components/alert/plain-alert.ts +49 -0
  6. package/components/alert/uialert.ts +110 -0
  7. package/components/artificial-flowlayout.ts +321 -0
  8. package/components/base.ts +47 -0
  9. package/components/custom-navigation-bar.ts +570 -0
  10. package/components/dialogs/dialog-sheet.ts +87 -0
  11. package/components/dialogs/form-dialog.ts +23 -0
  12. package/components/dialogs/list-dialog.ts +87 -0
  13. package/components/dialogs/text-dialog.ts +34 -0
  14. package/components/dynamic-itemsize-matrix.ts +190 -0
  15. package/components/dynamic-preference-listview.ts +691 -0
  16. package/components/dynamic-rowheight-list.ts +62 -0
  17. package/components/enhanced-imageview.ts +128 -0
  18. package/components/image-pager.ts +177 -0
  19. package/components/page-control.ts +91 -0
  20. package/components/pageviewer-titlebar.ts +170 -0
  21. package/components/pageviewer.ts +124 -0
  22. package/components/rotating-view.ts +126 -0
  23. package/components/searchbar.ts +373 -0
  24. package/components/sheet.ts +113 -0
  25. package/components/single-views.ts +828 -0
  26. package/components/spinners/loading-double-rings.ts +121 -0
  27. package/components/spinners/loading-dual-ring.ts +90 -0
  28. package/components/spinners/loading-wedges.ts +112 -0
  29. package/components/spinners/spinner-androidstyle.ts +264 -0
  30. package/components/static-preference-listview.ts +991 -0
  31. package/components/symbol-button.ts +105 -0
  32. package/components/tabbar.ts +451 -0
  33. package/controller/base-controller.ts +216 -0
  34. package/controller/controller-router.ts +74 -0
  35. package/controller/pageviewer-controller.ts +86 -0
  36. package/controller/presented-page-controller.ts +57 -0
  37. package/controller/splitview-controller.ts +323 -0
  38. package/controller/tabbar-controller.ts +99 -0
  39. package/package.json +23 -0
  40. package/test.ts +0 -0
  41. package/tsconfig.json +121 -0
  42. package/utils/colors.ts +13 -0
  43. package/utils/cvid.ts +34 -0
  44. package/utils/l10n.ts +42 -0
  45. package/utils/path.ts +100 -0
  46. package/utils/rect.ts +67 -0
  47. package/utils/uitools.ts +117 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * # Base<T extends AllUIView, R extends UiTypes.AllViewOptions>
3
+ * 组件 Base 基类,用于创建自定义组件。CView 的所有子类都应该继承自 Base。
4
+ *
5
+ * ## 属性
6
+ * - id: string 组件的唯一 id
7
+ * - view: T 通过自动创建的唯一 id 进行查找,获得对应的 UIView 对象
8
+ * - definition: R 获得对应的 view 的定义
9
+ *
10
+ * ## 方法
11
+ * - add(view: UiTypes.AllViewOptions | Base<any, any>): void 添加子 view。其中 `view` 参数可以是 CView,或 view 的定义
12
+ *
13
+ * ## 说明
14
+ * 视图是 CView 框架的重点,其名称的含义为“组件化视图”。设计目的是:
15
+ * - 通过组件化的方式,将JSBox view的定义和实例绑定,使用起来更加方便
16
+ * - 可以便利地创建自定义组件
17
+ */
18
+
19
+ import { cvid } from '../utils/cvid';
20
+
21
+ export abstract class Base<T extends AllUIView, R extends UiTypes.AllViewOptions> {
22
+ readonly id: string;
23
+ private _view?: T;
24
+ abstract _defineView: () => R;
25
+ _layout?: (make: MASConstraintMaker, view: T) => void;
26
+
27
+ constructor() {
28
+ this.id = cvid.newId;
29
+ }
30
+
31
+ get definition() {
32
+ return this._defineView();
33
+ }
34
+
35
+ get view() {
36
+ if (!this._view) this._view = $(this.id) as T;
37
+ return this._view;
38
+ }
39
+
40
+ add(view: UiTypes.AllViewOptions | Base<any, any>) {
41
+ if (view instanceof Base) {
42
+ this.view.add(view.definition);
43
+ } else {
44
+ this.view.add(view);
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,570 @@
1
+ /**
2
+ * # CView Custom NavigationBar
3
+ *
4
+ * 仿制 navBar
5
+ *
6
+ * ## features:
7
+ *
8
+ * - 拥有隐藏、最小化、普通、扩展四种布局方式
9
+ * - 隐藏: 什么都不显示
10
+ * - 最小化: safeAreaHeight 为 25, 只显示 titleView, 若用 title, font 为\$font(14)
11
+ * - 普通: safeAreaHeight 为 50, 显示 titleView, leftBarButtonItems 或 popButton, rightBarButtonItems, 若用 title, font 为\$font("bold", 17)
12
+ * - 扩展: safeAreaHeight 为 100, 除上面的之外, 再显示一个 toolView
13
+ * - 自动适应全面屏和非全面屏
14
+ *
15
+ * ## Arguments
16
+ *
17
+ * props:
18
+ *
19
+ * - 读写 style: number 0, 1, 2, 3,指定布局
20
+ * - 读写 title: string 但必须使用此种方案才可以在生成后写入,自动创建 Label 作为 titleView
21
+ * - titleView: cview 自定义的 titleView
22
+ * - popButtonEnabled: boolean 返回上一级的按钮,若为 true,则 leftBarButtonItems 忽略
23
+ * - popButtonTitle: string 返回上一级的按钮标题
24
+ * - popToRootEnabled: boolean popButton 是否可以长按返回到顶级
25
+ * - leftBarButtonItems: cview[]
26
+ * | {symbol: string, handler: () => void, tintColor?: UIColor}[]
27
+ * | {title: string, handler: () => void, tintColor?: UIColor}[]
28
+ * | {image: UIImage, handler: () => void, tintColor?: UIColor}[]
29
+ * 如果用的是 cview,其布局将被重新指定,即不需要(也不能)指定布局。可以通过 cview.width 来指定应有的宽度,如果没有此属性,则宽度为 50
30
+ * 建议最多放两个
31
+ * - rightBarButtonItems 定义同上,建议最多放两个
32
+ * - toolView: cview 在 expanded 模式下才会显现的
33
+ * - tintColor: UIColor 这将作用于 title, popButton, 自动创建的 barButton
34
+ * - bgcolor: UIColor 如不设置,则自动使用 blur(style 10),如果设置则没有 blur 效果
35
+ *
36
+ * events:
37
+ *
38
+ * - hidden: cview => void hide()时执行
39
+ * - minimized: cview => void minimize()时执行
40
+ * - restored: cview => void restore()时执行
41
+ * - expanded: cview => void expand()时执行
42
+ * - popHandler: cview => void 返回上一级时执行,需要popButtonEnabled
43
+ * - popToRootHandler: cview => void 返回顶级时执行,需要popButtonEnabled和popToRootEnabled
44
+ * - titleTapped: cview => void 点击标题时执行,需要使用title
45
+ *
46
+ * methods:
47
+ *
48
+ * - hide() 隐藏布局
49
+ * - minimize() 最小化布局
50
+ * - restore() 普通布局
51
+ * - expand() 扩展布局
52
+ */
53
+
54
+ import { Base } from "./base";
55
+ import { ContentView, Label, Button } from "./single-views";
56
+ import { SymbolButton } from "./symbol-button";
57
+ import { getTextWidth } from "../utils/uitools";
58
+
59
+ const navBarStyles = {
60
+ hidden: 0,
61
+ minimized: 1,
62
+ normal: 2,
63
+ expanded: 3
64
+ };
65
+
66
+ const navBarLayouts = [
67
+ (make: MASConstraintMaker, view: AllUIView) => {
68
+ make.left.right.top.inset(0);
69
+ make.height.equalTo(0);
70
+ },
71
+ (make: MASConstraintMaker, view: AllUIView) => {
72
+ make.left.right.top.inset(0);
73
+ make.bottom.equalTo(view.super.safeAreaTop).inset(-25);
74
+ },
75
+ (make: MASConstraintMaker, view: AllUIView) => {
76
+ make.left.right.top.inset(0);
77
+ make.bottom.equalTo(view.super.safeAreaTop).inset(-50);
78
+ },
79
+ (make: MASConstraintMaker, view: AllUIView) => {
80
+ make.left.right.top.inset(0);
81
+ make.bottom.equalTo(view.super.safeAreaTop).inset(-100);
82
+ }
83
+ ]
84
+
85
+ export interface NavigationBarProps {
86
+ style: number;
87
+ title?: string;
88
+ titleView?: Base<any, any>;
89
+ popButtonEnabled?: boolean;
90
+ popButtonTitle?: string;
91
+ popToRootEnabled?: boolean;
92
+ leftBarButtonItems: BarButtonItem[];
93
+ rightBarButtonItems: BarButtonItem[];
94
+ toolView?: Base<any, any>;
95
+ tintColor: UIColor;
96
+ bgcolor?: UIColor;
97
+ }
98
+
99
+ interface BarButtonItem {
100
+ cview?: Base<AllUIView, UiTypes.AllViewOptions>;
101
+ width?: number;
102
+ title?: string;
103
+ symbol?: string;
104
+ image?: UIImage;
105
+ tintColor?: UIColor;
106
+ handler?: () => void;
107
+ }
108
+
109
+ interface NavigationBarEvents {
110
+ hidden?: (cview: CustomNavigationBar) => void;
111
+ minimized?: (cview: CustomNavigationBar) => void;
112
+ restored?: (cview: CustomNavigationBar) => void;
113
+ expanded?: (cview: CustomNavigationBar) => void;
114
+ popHandler?: (cview: CustomNavigationBar) => void;
115
+ popToRootHandler?: (cview: CustomNavigationBar) => void;
116
+ titleTapped?: (cview: CustomNavigationBar) => void;
117
+ }
118
+
119
+ interface NavigationBarCViews {
120
+ leftItemView?: ContentView | Button;
121
+ rightItemView?: ContentView;
122
+ titleViewWrapper?: ContentView | Label;
123
+ contentView?: ContentView;
124
+ toolViewWrapper?: ContentView;
125
+ }
126
+
127
+ export class CustomNavigationBar extends Base<UIView | UIBlurView, UiTypes.ViewOptions | UiTypes.BlurOptions> {
128
+ _props: NavigationBarProps;
129
+ _events: NavigationBarEvents;
130
+ cviews: Required<NavigationBarCViews>;
131
+ _defineView: () => UiTypes.ViewOptions | UiTypes.BlurOptions;
132
+ constructor({ props = {}, events = {} }: {
133
+ props?: Partial<NavigationBarProps>;
134
+ events?: NavigationBarEvents;
135
+ } = {}) {
136
+ super();
137
+ this._props = {
138
+ leftBarButtonItems: [],
139
+ rightBarButtonItems: [],
140
+ style: navBarStyles.normal,
141
+ tintColor: $color("primaryText"),
142
+ ...props
143
+ };
144
+ this._events = events;
145
+ this.cviews = {} as Required<NavigationBarCViews>
146
+ this._defineView = () => {
147
+ /*
148
+ 设计思路
149
+ 一共5个子视图:
150
+ - contentView 下有3个子视图
151
+ - leftItemView popButton或者leftButtonItems
152
+ - rightItemView rightButtonItems
153
+ - titleView
154
+ - toolView
155
+ */
156
+ // leftItemView
157
+ let leftInset = 0;
158
+ if (this._props.popButtonEnabled) {
159
+ const titleWidth = this._props.popButtonTitle
160
+ ? getTextWidth(this._props.popButtonTitle)
161
+ : 0;
162
+ leftInset = titleWidth + 35;
163
+ const views = [];
164
+ const chevronOptions: UiTypes.ViewOptions = {
165
+ type: "view",
166
+ props: {},
167
+ layout: (make: MASConstraintMaker) => {
168
+ make.left.top.bottom.inset(0);
169
+ make.width.equalTo(35);
170
+ },
171
+ views: [
172
+ {
173
+ type: "image",
174
+ props: {
175
+ symbol: "chevron.left",
176
+ contentMode: 1,
177
+ tintColor: this._props.tintColor
178
+ },
179
+ layout: (make: MASConstraintMaker) => make.edges.insets($insets(12.5, 10, 12.5, 0))
180
+ }
181
+ ]
182
+ }
183
+ views.push(chevronOptions);
184
+ if (this._props.popButtonTitle) {
185
+ const popButtonTitleOptions: UiTypes.LabelOptions = {
186
+ type: "label",
187
+ props: {
188
+ align: $align.left,
189
+ text: this._props.popButtonTitle,
190
+ font: $font(17),
191
+ textColor: this._props.tintColor
192
+ },
193
+ layout: (make: MASConstraintMaker, view: UILabelView) => {
194
+ make.top.bottom.right.inset(0);
195
+ make.left.equalTo(view.prev.right);
196
+ }
197
+ }
198
+ views.push(popButtonTitleOptions);
199
+ }
200
+ this.cviews.leftItemView = new Button({
201
+ props: {
202
+ bgcolor: $color("clear"),
203
+ cornerRadius: 0
204
+ },
205
+ views,
206
+ layout: (make, view) => {
207
+ make.width.equalTo(leftInset);
208
+ make.left.top.bottom.inset(0);
209
+ },
210
+ events: {
211
+ tapped: sender => {
212
+ if (this._events.popHandler) this._events.popHandler(this);
213
+ $ui.pop();
214
+ },
215
+ longPressed: this._props.popToRootEnabled
216
+ ? sender => {
217
+ if (this._events.popToRootHandler)
218
+ this._events.popToRootHandler(this);
219
+ $ui.popToRoot();
220
+ }
221
+ : undefined
222
+ }
223
+ });
224
+ } else {
225
+ leftInset = this._calculateItemViewWidth(this._props.leftBarButtonItems);
226
+ this.cviews.leftItemView = new ContentView({
227
+ props: {
228
+ bgcolor: undefined
229
+ },
230
+ layout: (make, view) => {
231
+ make.width.equalTo(leftInset);
232
+ make.left.top.bottom.inset(0);
233
+ },
234
+ views: this._createCviewsOnItemView(this._props.leftBarButtonItems).map(
235
+ n => n.definition
236
+ )
237
+ });
238
+ }
239
+
240
+ // rightItemView
241
+ const rightInset = this._calculateItemViewWidth(
242
+ this._props.rightBarButtonItems
243
+ );
244
+ this.cviews.rightItemView = new ContentView({
245
+ props: {
246
+ bgcolor: undefined
247
+ },
248
+ layout: (make, view) => {
249
+ make.width.equalTo(rightInset);
250
+ make.right.top.bottom.inset(0);
251
+ },
252
+ views: this._createCviewsOnItemView(this._props.rightBarButtonItems).map(
253
+ n => n.definition
254
+ )
255
+ });
256
+
257
+ // titleView
258
+ const titleViewInset = Math.max(leftInset, rightInset);
259
+ if (this._props.title) {
260
+ this.cviews.titleViewWrapper = new Label({
261
+ props: {
262
+ text: this._props.title,
263
+ font: $font("bold", 17),
264
+ align: $align.center,
265
+ textColor: this._props.tintColor,
266
+ userInteractionEnabled: true
267
+ },
268
+ layout: (make, view) => {
269
+ make.left.right.inset(titleViewInset);
270
+ make.top.bottom.inset(0);
271
+ },
272
+ events: {
273
+ tapped: sender => {
274
+ if (this._events.titleTapped) this._events.titleTapped(this);
275
+ }
276
+ }
277
+ });
278
+ } else {
279
+ this.cviews.titleViewWrapper = new ContentView({
280
+ props: {
281
+ bgcolor: undefined
282
+ },
283
+ layout: (make, view) => {
284
+ make.left.right.inset(titleViewInset);
285
+ make.top.bottom.inset(0);
286
+ },
287
+ views: this._props.titleView && [this._props.titleView.definition]
288
+ });
289
+ }
290
+
291
+ // contentView
292
+ this.cviews.contentView = new ContentView({
293
+ props: {
294
+ bgcolor: undefined
295
+ },
296
+ layout: (make, view) => {
297
+ make.top.inset(0);
298
+ make.left.right.inset(5);
299
+ make.height.equalTo(50);
300
+ },
301
+ views: [
302
+ this.cviews.titleViewWrapper.definition,
303
+ this.cviews.leftItemView.definition,
304
+ this.cviews.rightItemView.definition
305
+ ]
306
+ });
307
+
308
+ // toolView
309
+ this.cviews.toolViewWrapper = new ContentView({
310
+ props: {
311
+ bgcolor: undefined
312
+ },
313
+ layout: (make, view) => {
314
+ make.left.right.bottom.equalTo(view.super);
315
+ make.top.equalTo(view.super).inset(50);
316
+ },
317
+ views: this._props.toolView && [this._props.toolView.definition]
318
+ });
319
+
320
+ return {
321
+ type: this._props.bgcolor ? "view" : "blur",
322
+ props: {
323
+ id: this.id,
324
+ style: this._props.bgcolor ? undefined : 10,
325
+ bgcolor: this._props.bgcolor
326
+ },
327
+ layout: navBarLayouts[this._props.style],
328
+ events: {
329
+ ready: () => (this.style = this.style)
330
+ },
331
+ views: [
332
+ {
333
+ type: "view",
334
+ props: {},
335
+ layout: $layout.fillSafeArea,
336
+ views: [
337
+ this.cviews.contentView.definition,
338
+ this.cviews.toolViewWrapper.definition
339
+ ]
340
+ },
341
+ {
342
+ type: "view",
343
+ props: {
344
+ bgcolor: $color("separatorColor")
345
+ },
346
+ layout: (make, view) => {
347
+ make.bottom.left.right.inset(0);
348
+ make.height.equalTo(0.5);
349
+ }
350
+ }
351
+ ]
352
+ };
353
+ }
354
+ }
355
+
356
+ private _calculateItemViewWidth(items: BarButtonItem[]) {
357
+ if (!items || items.length === 0) return 0;
358
+ let width = 0;
359
+ items.forEach(n => {
360
+ if (n.cview) width += n.width || 50;
361
+ else if (n.title) width += getTextWidth(n.title, { inset: 20 });
362
+ else width += 50;
363
+ });
364
+ return width;
365
+ }
366
+
367
+ private _createCviewsOnItemView(items: BarButtonItem[]) {
368
+ return items.map(n => {
369
+ if (n.cview) {
370
+ const width = n.width || 50;
371
+ n.cview._layout = (make: MASConstraintMaker, view: AllUIView) => {
372
+ make.top.bottom.inset(0);
373
+ make.width.equalTo(width);
374
+ make.left.equalTo((view.prev && view.prev.right) || 0);
375
+ };
376
+ return n.cview;
377
+ } else if (n.title) {
378
+ const width = getTextWidth(n.title, { inset: 20 });
379
+ return new Button({
380
+ props: {
381
+ title: n.title,
382
+ bgcolor: $color("clear"),
383
+ titleColor: n.tintColor || this._props.tintColor,
384
+ cornerRadius: 0
385
+ },
386
+ layout: (make, view) => {
387
+ make.top.bottom.inset(0);
388
+ make.width.equalTo(width);
389
+ make.left.equalTo((view.prev && view.prev.right) || 0);
390
+ },
391
+ events: {
392
+ tapped: n.handler
393
+ }
394
+ });
395
+ } else if (n.symbol || n.image) {
396
+ return new SymbolButton({
397
+ props: {
398
+ symbol: n.symbol,
399
+ image: n.image,
400
+ tintColor: n.tintColor || this._props.tintColor
401
+ },
402
+ layout: (make, view) => {
403
+ make.top.bottom.inset(0);
404
+ make.width.equalTo(50);
405
+ make.left.equalTo((view.prev && view.prev.right) || 0);
406
+ },
407
+ events: {
408
+ tapped: n.handler
409
+ }
410
+ });
411
+ } else {
412
+ throw Error("Invalid BarButtonItem");
413
+ }
414
+ });
415
+ }
416
+
417
+ get title() {
418
+ return this._props.title || "";
419
+ }
420
+
421
+ set title(title: string) {
422
+ if (this._props.title === undefined) return;
423
+ this._props.title = title;
424
+ if ("text" in this.cviews.titleViewWrapper.view) this.cviews.titleViewWrapper.view.text = title;
425
+ }
426
+
427
+ hide(animated = true) {
428
+ this.view.hidden = false;
429
+ this.cviews.leftItemView.view.hidden = true;
430
+ this.cviews.rightItemView.view.hidden = true;
431
+ this.cviews.toolViewWrapper.view.hidden = true;
432
+ this.cviews.titleViewWrapper.view.hidden = true;
433
+ this.view.remakeLayout(navBarLayouts[navBarStyles.hidden]);
434
+ this.cviews.contentView.view.updateLayout(make => make.height.equalTo(0));
435
+ if (animated) {
436
+ $ui.animate({
437
+ duration: 0.3,
438
+ animation: () => {
439
+ this.view.relayout();
440
+ this.cviews.contentView.view.relayout();
441
+ },
442
+ completion: () => {
443
+ this.view.hidden = true;
444
+ if (this._events.hidden) this._events.hidden(this);
445
+ }
446
+ });
447
+ } else {
448
+ this.view.hidden = true;
449
+ if (this._events.hidden) this._events.hidden(this);
450
+ }
451
+ }
452
+
453
+ minimize(animated = true) {
454
+ this.view.hidden = false;
455
+ this.cviews.leftItemView.view.hidden = true;
456
+ this.cviews.rightItemView.view.hidden = true;
457
+ this.cviews.toolViewWrapper.view.hidden = true;
458
+ this.cviews.titleViewWrapper.view.hidden = false;
459
+ this.view.remakeLayout(navBarLayouts[navBarStyles.minimized]);
460
+ this.cviews.contentView.view.updateLayout(make => make.height.equalTo(25));
461
+ if (animated) {
462
+ $ui.animate({
463
+ duration: 0.3,
464
+ animation: () => {
465
+ this.view.relayout();
466
+ this.cviews.contentView.view.relayout();
467
+ if (this._props.title && "font" in this.cviews.titleViewWrapper.view)
468
+ this.cviews.titleViewWrapper.view.font = $font("bold", 14);
469
+ },
470
+ completion: () => {
471
+ if (this._events.minimized) this._events.minimized(this);
472
+ }
473
+ });
474
+ } else {
475
+ if (this._props.title && "font" in this.cviews.titleViewWrapper.view)
476
+ this.cviews.titleViewWrapper.view.font = $font("bold", 14);
477
+ if (this._events.minimized) this._events.minimized(this);
478
+ }
479
+ }
480
+
481
+ restore(animated = true) {
482
+ this.view.hidden = false;
483
+ this.cviews.titleViewWrapper.view.hidden = false;
484
+ //this.cviews.toolViewWrapper.view.hidden = true;
485
+ this.view.remakeLayout(navBarLayouts[navBarStyles.normal]);
486
+ this.cviews.contentView.view.updateLayout(make => make.height.equalTo(50));
487
+ if (animated) {
488
+ $ui.animate({
489
+ duration: 0.3,
490
+ animation: () => {
491
+ this.view.relayout();
492
+ this.cviews.contentView.view.relayout();
493
+ if (this._props.title && "font" in this.cviews.titleViewWrapper.view)
494
+ this.cviews.titleViewWrapper.view.font = $font("bold", 17);
495
+ },
496
+ completion: () => {
497
+ this.cviews.leftItemView.view.hidden = false;
498
+ this.cviews.rightItemView.view.hidden = false;
499
+ if (this._events.restored) this._events.restored(this);
500
+ }
501
+ });
502
+ } else {
503
+ this.cviews.leftItemView.view.hidden = false;
504
+ this.cviews.rightItemView.view.hidden = false;
505
+ if (this._props.title && "font" in this.cviews.titleViewWrapper.view)
506
+ this.cviews.titleViewWrapper.view.font = $font("bold", 17);
507
+ if (this._events.restored) this._events.restored(this);
508
+ }
509
+ }
510
+
511
+ expand(animated = true) {
512
+ this.view.hidden = false;
513
+ this.cviews.toolViewWrapper.view.hidden = false;
514
+ this.cviews.titleViewWrapper.view.hidden = false;
515
+ this.view.remakeLayout(navBarLayouts[navBarStyles.expanded]);
516
+ this.cviews.contentView.view.updateLayout(make => make.height.equalTo(50));
517
+ if (animated) {
518
+ $ui.animate({
519
+ duration: 0.3,
520
+ animation: () => {
521
+ this.view.relayout();
522
+ this.cviews.contentView.view.relayout();
523
+ if (this._props.title && "font" in this.cviews.titleViewWrapper.view)
524
+ this.cviews.titleViewWrapper.view.font = $font("bold", 17);
525
+ },
526
+ completion: () => {
527
+ this.cviews.leftItemView.view.hidden = false;
528
+ this.cviews.rightItemView.view.hidden = false;
529
+ //this.cviews.toolViewWrapper.view.hidden = false;
530
+ if (this._events.expanded) this._events.expanded(this);
531
+ }
532
+ });
533
+ } else {
534
+ this.cviews.leftItemView.view.hidden = false;
535
+ this.cviews.rightItemView.view.hidden = false;
536
+ //this.cviews.toolViewWrapper.view.hidden = false;
537
+ if (this._props.title && "font" in this.cviews.titleViewWrapper.view)
538
+ this.cviews.titleViewWrapper.view.font = $font("bold", 17);
539
+ if (this._events.expanded) this._events.expanded(this);
540
+ }
541
+ }
542
+
543
+ get style() {
544
+ return this._props.style;
545
+ }
546
+
547
+ set style(num) {
548
+ this._props.style = num;
549
+ switch (num) {
550
+ case 0: {
551
+ this.hide();
552
+ break;
553
+ }
554
+ case 1: {
555
+ this.minimize();
556
+ break;
557
+ }
558
+ case 2: {
559
+ this.restore();
560
+ break;
561
+ }
562
+ case 3: {
563
+ this.expand();
564
+ break;
565
+ }
566
+ default:
567
+ break;
568
+ }
569
+ }
570
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * # cview DialogSheet
3
+ *
4
+ * dialog所需要的sheet
5
+ *
6
+ * ## 参数
7
+ * - `title` 标题
8
+ * - `cview` CView
9
+ * - `doneHandler` 完成时的回调
10
+ * - `presentMode` presentMode
11
+ * - `bgcolor` 背景颜色
12
+ */
13
+
14
+ import { Sheet } from "../sheet";
15
+
16
+ import { CustomNavigationBar } from "../custom-navigation-bar";
17
+ import { l10n } from "../../utils/l10n";
18
+ import { ContentView } from "../single-views";
19
+ import { Base } from "../base";
20
+
21
+
22
+ export class DialogSheet extends Sheet<ContentView, UIView, UiTypes.ViewOptions>{
23
+ _props: {
24
+ title: string;
25
+ cview: Base<any, any>;
26
+ doneHandler?: () => void;
27
+ presentMode?: number;
28
+ bgcolor?: UIColor;
29
+ }
30
+ _done: boolean;
31
+ resolve?: (value: any) => void;
32
+ reject?: (reason: any) => void;
33
+
34
+ constructor(props: {
35
+ title: string;
36
+ cview: Base<any, any>;
37
+ doneHandler?: () => void;
38
+ presentMode?: number;
39
+ bgcolor?: UIColor;
40
+ }) {
41
+ super({
42
+ presentMode: props.presentMode || ($device.isIpad ? 2 : 1),
43
+ bgcolor: props.bgcolor
44
+ });
45
+ this._props = props;
46
+ this._done = false;
47
+ }
48
+
49
+ promisify(resolve: (value: any) => void, reject: (reason: any) => void) {
50
+ this.resolve = resolve;
51
+ this.reject = reject;
52
+ }
53
+
54
+ present() {
55
+ this._dismissalHandler = () => {
56
+ if (!this._done && this.reject) this.reject("cancel");
57
+ };
58
+ const _navbar = new CustomNavigationBar({
59
+ props: {
60
+ title: this._props.title,
61
+ leftBarButtonItems: [
62
+ { symbol: "xmark", handler: () => this.dismiss() }
63
+ ],
64
+ rightBarButtonItems: [
65
+ { title: l10n("DONE"), handler: () => this.done() }
66
+ ]
67
+ }
68
+ });
69
+ this._props.cview._layout = (make, view) => {
70
+ make.bottom.equalTo(view.super);
71
+ make.left.right.equalTo(view.super.safeArea);
72
+ make.top.equalTo(view.prev.bottom);
73
+ };
74
+ this._cview = new ContentView({
75
+ props: { bgcolor: $color("clear") },
76
+ views: [_navbar.definition, this._props.cview.definition]
77
+ });
78
+ super.present();
79
+ }
80
+
81
+ done() {
82
+ this._done = true;
83
+ if (this.resolve && this._props.doneHandler)
84
+ this.resolve(this._props.doneHandler());
85
+ this.dismiss();
86
+ }
87
+ }