@react-native-ohos/react-native-context-menu-view 1.16.1-rc.1

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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.OpenSource +11 -0
  3. package/README.md +13 -0
  4. package/harmony/context_menu/BuildProfile.ets +17 -0
  5. package/harmony/context_menu/build-profile.json5 +12 -0
  6. package/harmony/context_menu/hvigorfile.ts +2 -0
  7. package/harmony/context_menu/index.ets +28 -0
  8. package/harmony/context_menu/oh-package.json5 +12 -0
  9. package/harmony/context_menu/src/main/cpp/CMakeLists.txt +8 -0
  10. package/harmony/context_menu/src/main/cpp/ComponentDescriptors.h +18 -0
  11. package/harmony/context_menu/src/main/cpp/ContextMenuJSIBinder.h +58 -0
  12. package/harmony/context_menu/src/main/cpp/ContextMenuPackage.h +140 -0
  13. package/harmony/context_menu/src/main/cpp/ContextMenuTurboModule.cpp +36 -0
  14. package/harmony/context_menu/src/main/cpp/ContextMenuTurboModule.h +38 -0
  15. package/harmony/context_menu/src/main/cpp/EventEmitters.cpp +49 -0
  16. package/harmony/context_menu/src/main/cpp/EventEmitters.h +41 -0
  17. package/harmony/context_menu/src/main/cpp/Props.cpp +33 -0
  18. package/harmony/context_menu/src/main/cpp/Props.h +115 -0
  19. package/harmony/context_menu/src/main/cpp/RTNContextMenuComponentInstance.cpp +286 -0
  20. package/harmony/context_menu/src/main/cpp/RTNContextMenuComponentInstance.h +165 -0
  21. package/harmony/context_menu/src/main/cpp/ShadowNodes.cpp +15 -0
  22. package/harmony/context_menu/src/main/cpp/ShadowNodes.h +30 -0
  23. package/harmony/context_menu/src/main/cpp/States.cpp +15 -0
  24. package/harmony/context_menu/src/main/cpp/States.h +34 -0
  25. package/harmony/context_menu/src/main/ets/ContextMenuLongPress.ets +374 -0
  26. package/harmony/context_menu/src/main/ets/ContextMenuLongPressWithNoSelect.ets +356 -0
  27. package/harmony/context_menu/src/main/ets/ContextMenuPackage.ets +48 -0
  28. package/harmony/context_menu/src/main/ets/ContextMenuThreeMenu.ets +224 -0
  29. package/harmony/context_menu/src/main/ets/ContextMenuThreeMenuWithNoSelect.ets +221 -0
  30. package/harmony/context_menu/src/main/ets/ContextMenuTurboModule.ets +293 -0
  31. package/harmony/context_menu/src/main/ets/ContextMenuTwoMenu.ets +209 -0
  32. package/harmony/context_menu/src/main/ets/ContextMenuTwoMenuWithNoSelect.ets +207 -0
  33. package/harmony/context_menu/src/main/ets/Logger.ets +64 -0
  34. package/harmony/context_menu/src/main/module.json5 +7 -0
  35. package/harmony/context_menu/src/main/resources/base/element/string.json +8 -0
  36. package/harmony/context_menu/src/main/resources/base/media/airplane_fill.png +0 -0
  37. package/harmony/context_menu/src/main/resources/base/media/background.png +0 -0
  38. package/harmony/context_menu/src/main/resources/base/media/foreground.png +0 -0
  39. package/harmony/context_menu/src/main/resources/base/media/layered_image.json +7 -0
  40. package/harmony/context_menu/src/main/resources/base/media/startIcon.png +0 -0
  41. package/harmony/context_menu/src/main/resources/base/profile/backup_config.json +3 -0
  42. package/harmony/context_menu/src/main/resources/base/profile/main_pages.json +5 -0
  43. package/harmony/context_menu/src/main/resources/en_US/element/string.json +8 -0
  44. package/harmony/context_menu/src/main/resources/zh_CN/element/string.json +8 -0
  45. package/harmony/context_menu/ts.ets +26 -0
  46. package/harmony/context_menu.har +0 -0
  47. package/index.js +44 -0
  48. package/package.json +49 -0
  49. package/react-native-context-menu-view.podspec +26 -0
  50. package/src/RTNContextMenuNativeComponent.ts +50 -0
@@ -0,0 +1,356 @@
1
+ /**
2
+ * MIT License
3
+ *
4
+ * Copyright (C) 2024 Huawei Device Co., Ltd.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { RNOHContext, } from '@rnoh/react-native-openharmony'
26
+ import Logger from './Logger';
27
+ import { SymbolGlyphModifier } from '@kit.ArkUI';
28
+ import { ContextMenuTwoMenu } from './ContextMenuTwoMenu';
29
+ import { ContextMenuTwoMenuWithNoSelect } from './ContextMenuTwoMenuWithNoSelect';
30
+
31
+ //这里的属性类型要和ContextMenuTurboModule.ets下的ContextMenuProps一致
32
+ interface ContextMenuProps {
33
+ tag?: number;
34
+ width?: number;
35
+ height?: number;
36
+ x?: number;
37
+ y?: number;
38
+ windowX?: number;
39
+ windowY?: number;
40
+ title?: string;
41
+ action?: string;
42
+ dropdownMenuMode?: boolean;
43
+ disabled?: boolean;
44
+ subtitle?: string;
45
+
46
+ // disabledArray?: Array<boolean>;
47
+ selected?: boolean;
48
+ previewBackgroundColor?: string;
49
+ actionsTitle?: string;
50
+ touchViewActions?: ContextMenuProps
51
+ ctx: RNOHContext
52
+ romWidth?: number;
53
+ romHeight?: number;
54
+ systemIcon?: string;
55
+ icon?: string;
56
+ destructive?: string
57
+ iconColor?: string;
58
+
59
+ //二级目录
60
+ inlineChildren?: boolean;
61
+ d_childActions?: ContextMenuProps;
62
+ childActionsTag?: number;
63
+
64
+ //2+目录
65
+ childActions?: ContextMenuProps;
66
+ }
67
+
68
+ @Component
69
+ export struct ContextMenuLongPressWithNoSelect {
70
+ public static readonly NAME = "ContextMenuLongPressWithNoSelect"
71
+ menuCtx!: RNOHContext;
72
+ menuTag: number = 0;
73
+ @State realViewPoint: Object = [];
74
+ @State listDate: ContextMenuProps[] = [];
75
+ @State menuTitle: string = '';
76
+ @State menuX: number = 0;
77
+ @State menuY: number = 0;
78
+ @State menuWidth: number = 0;
79
+ @State menuHeight: number = 0;
80
+ @State menuDisable: boolean = true;
81
+ @State menuRomWidth: number = 0;
82
+ @State menuRomHeight: number = 0;
83
+ @State menuWindowX: number = 0;
84
+ @State menuWindowY: number = 0;
85
+ @State menuIndexPath: number[] = [];
86
+ @State menuDestructive: string = '';
87
+ @State childActionsListDate: ESObject[] = [];
88
+ @State isTouch: boolean | undefined = false;
89
+ @State isTouchWithNoSelect: boolean | undefined = false;
90
+ @State isTouchViewNumber: number = 0;
91
+ @State isChildActionsTouchViewNumber: number = 0;
92
+ @State menuChildActions: ContextMenuProps[] = [];
93
+ @State menuChild: ESObject[] = [];
94
+ @State deepChildActions: ESObject[] = [];
95
+ @State isShow: boolean = false;
96
+ @State twoMenu: ESObject[] = [];
97
+ @State selectedFlag: ESObject[] = [ ];
98
+
99
+ aboutToAppear() {
100
+ let longPress: ESObject = this.realViewPoint;
101
+ //menu的大标题
102
+ this.menuTitle = longPress.title;
103
+ //获取menu的xy轴,以及view视图的长宽
104
+ this.menuX = longPress.x;
105
+ this.menuY = longPress.y;
106
+ this.menuWidth = longPress.width;
107
+ this.menuHeight = longPress.height;
108
+ this.menuCtx = longPress.ctx;
109
+ this.menuTag = longPress.tag;
110
+ //获取设备的长宽
111
+ this.menuRomWidth = longPress.romWidth;
112
+ this.menuRomHeight = longPress.romHeight;
113
+ //获取点击时候的点击事件的xy,基于屏幕左上角
114
+ this.menuWindowX = longPress.windowX;
115
+ this.menuWindowY = longPress.windowY;
116
+ this.listDate = longPress.touchViewActions;
117
+ //判断destructive(可破坏),默认false,表示不可破坏。
118
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
119
+ if (longPress.touchViewActions[i].destructive) {
120
+ //可破坏为红色
121
+ this.listDate[i].destructive = 'red';
122
+ } else {
123
+ //不可破坏为black
124
+ this.listDate[i].destructive = 'black';
125
+ }
126
+ }
127
+ // contextMenu入参为disabled,是否禁用选项,默认为false,表示不用禁用.
128
+ // 但是在harmony Next调用enable的入参,harmony Next:true = RN:false
129
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
130
+ if (longPress.touchViewActions[i].disabled) {
131
+ //为true,表示禁用,对应harmony next 的false
132
+ this.listDate[i].disabled = false;
133
+ } else {
134
+ //contextMenu的false 对标 harmony 的 true
135
+ this.listDate[i].disabled = true;
136
+ }
137
+ }
138
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
139
+ if (longPress.touchViewActions[i].selected) {
140
+ //复选框,默认为false
141
+ this.listDate[i].selected = true;
142
+ } else {
143
+ this.listDate[i].selected = false;
144
+ }
145
+ }
146
+
147
+ //遍历传递回前端的indexPath,indexPath只会计算子节点index
148
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
149
+ this.menuIndexPath[i] = i;
150
+ }
151
+
152
+ //二级目录,均和一级目录一致
153
+ // 遍历查询是否有二级目录
154
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
155
+ if (longPress.touchViewActions[i].d_childActions !== '' ||
156
+ longPress.touchViewActions[i].d_childActions !== undefined ||
157
+ longPress.touchViewActions[i].d_childActions !== null) {
158
+ //有二级菜单
159
+ this.childActionsListDate[i] = longPress.touchViewActions[i].d_childActions;
160
+ }
161
+ }
162
+ ;
163
+
164
+ for (let i = 0; i < this.childActionsListDate.length; i++) {
165
+ if (this.childActionsListDate[i] !== null && this.childActionsListDate[i] !== undefined &&
166
+ this.childActionsListDate[i] !== '') {
167
+ let j = i;
168
+ //默认为false,这里判断disabled
169
+ for (let k = 0; k < this.childActionsListDate[j].length; k++) {
170
+ this.menuIndexPath[k] = k;
171
+ if ((this.childActionsListDate[j])[k].disabled) {
172
+ (this.childActionsListDate[j])[k].disabled = false;
173
+ } else {
174
+ //contextMenu的false 对标 harmony 的 true
175
+ (this.childActionsListDate[j])[k].disabled = true;
176
+ }
177
+ if ((this.childActionsListDate[j])[k].selected) {
178
+ this.selectedFlag[k] = 1;
179
+ } else {
180
+ this.selectedFlag[k] = 0;
181
+ }
182
+ }
183
+ }
184
+ }
185
+ console.log('20240919----------------------'+JSON.stringify(this.childActionsListDate.length));
186
+ }
187
+
188
+ //退出组件
189
+ aboutToDisappear() {
190
+ }
191
+
192
+ @Builder
193
+ twoMenuView() {
194
+ ContextMenuTwoMenu(
195
+ {
196
+ realViewPoint: this.twoMenu,
197
+ menuCtx: this.menuCtx,
198
+ menuTag: this.menuTag
199
+ });
200
+ }
201
+
202
+ @Builder
203
+ twoMenuViewWithNoSelect() {
204
+ ContextMenuTwoMenuWithNoSelect(
205
+ {
206
+ realViewPoint: this.twoMenu,
207
+ menuCtx: this.menuCtx,
208
+ menuTag: this.menuTag
209
+ });
210
+ }
211
+
212
+ build() {
213
+ Menu() {
214
+ MenuItemGroup({ header: this.menuTitle }) {
215
+ //遍历数据,把每个menuTitle塞入到对应的menu中
216
+ ForEach(this.listDate, (item: ContextMenuProps, index) => {
217
+ if (item.systemIcon) {
218
+ if (this.childActionsListDate.length >= 0) {
219
+ MenuItem({
220
+ content: item.title,
221
+ symbolEndIcon: new SymbolGlyphModifier($r(item.systemIcon)).fontSize('24vp')
222
+ .fontColor([item.iconColor]),
223
+ labelInfo: item.subtitle,
224
+ })
225
+ .alignSelf(ItemAlign.Start)
226
+ .enabled(item.disabled)
227
+ .contentFontColor(item.destructive)
228
+ .onClick(() => {
229
+ //当item.inlineChildren默认为false,表示以二级目录展示
230
+ //true的时候,以同目录展示
231
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
232
+ this.isTouchWithNoSelect = this.isTouch ;
233
+ this.isTouchViewNumber = index;
234
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
235
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
236
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
237
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
238
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
239
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
240
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
241
+ itemTitle: item.title,
242
+ itemTag: this.menuTag,
243
+ itemIndex: index,
244
+ itemIndexPath: [0],
245
+ itemInlineChildren: item.inlineChildren
246
+ });
247
+ } })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
248
+ .bindContextMenu(this.isTouch, this.twoMenuView())
249
+
250
+ } else {
251
+ MenuItem({
252
+ content: item.title,
253
+ symbolEndIcon: new SymbolGlyphModifier($r(item.systemIcon)).fontSize('24vp')
254
+ .fontColor([item.iconColor]),
255
+ labelInfo: item.subtitle,
256
+ })
257
+ .alignSelf(ItemAlign.Start)
258
+ .enabled(item.disabled)
259
+ .contentFontColor(item.destructive)
260
+ .onClick(() => {
261
+ //当item.inlineChildren默认为false,表示以二级目录展示
262
+ //true的时候,以同目录展示
263
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
264
+ this.isTouchWithNoSelect = this.isTouch ;
265
+ this.isTouchViewNumber = index;
266
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
267
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
268
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
269
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
270
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
271
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
272
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
273
+ itemTitle: item.title,
274
+ itemTag: this.menuTag,
275
+ itemIndex: index,
276
+ itemIndexPath: [0],
277
+ itemInlineChildren: item.inlineChildren
278
+ });
279
+ }
280
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
281
+ .bindContextMenu(this.isTouchWithNoSelect, this.twoMenuViewWithNoSelect())
282
+ }
283
+ } else {
284
+ //如果没有systemIcon,则走自定义图标
285
+ if (this.childActionsListDate.length >= 0) {
286
+ MenuItem({
287
+ content: item.title,
288
+ endIcon: $r(item.icon),
289
+ labelInfo: item.subtitle,
290
+ })
291
+ .alignSelf(ItemAlign.Start)
292
+ .enabled(item.disabled)
293
+ .contentFontColor(item.destructive)
294
+ .onClick(() => {
295
+ //当item.inlineChildren默认为false,表示以二级目录展示
296
+ //true的时候,以同目录展示
297
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
298
+ this.isTouchViewNumber = index;
299
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
300
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
301
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
302
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
303
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
304
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
305
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
306
+ itemTitle: item.title,
307
+ itemTag: this.menuTag,
308
+ itemIndex: index,
309
+ itemIndexPath: [0],
310
+ itemInlineChildren: item.inlineChildren
311
+ });
312
+ }
313
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
314
+ .bindContextMenu(this.isTouch, this.twoMenuView())
315
+ } else {
316
+ MenuItem({
317
+ content: item.title,
318
+ endIcon: $r(item.icon),
319
+ labelInfo: item.subtitle,
320
+ })
321
+ .alignSelf(ItemAlign.Start)
322
+ .enabled(item.disabled)
323
+ .contentFontColor(item.destructive)
324
+ .onClick(() => {
325
+ //当item.inlineChildren默认为false,表示以二级目录展示
326
+ //true的时候,以同目录展示
327
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
328
+ this.isTouchWithNoSelect = this.isTouch;
329
+ this.isTouchViewNumber = index;
330
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
331
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
332
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
333
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
334
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
335
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
336
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
337
+ itemTitle: item.title,
338
+ itemTag: this.menuTag,
339
+ itemIndex: index,
340
+ itemIndexPath: [0],
341
+ itemInlineChildren: item.inlineChildren
342
+ });
343
+ }
344
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
345
+ .bindContextMenu(this.isTouchWithNoSelect, this.twoMenuViewWithNoSelect())
346
+ }
347
+ }
348
+ })
349
+ }.backgroundColor('white')
350
+ }.onDisAppear(() => {
351
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::onCancel', {
352
+ itemTag: this.menuTag,
353
+ });
354
+ })
355
+ }
356
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * MIT License
3
+ *
4
+ * Copyright (C) 2024 Huawei Device Co., Ltd.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { TurboModulesFactory} from '@rnoh/react-native-openharmony/ts';
26
+ import { RNOHPackage } from '@rnoh/react-native-openharmony'
27
+ import type {TurboModule, TurboModuleContext} from '@rnoh/react-native-openharmony/ts';
28
+ import { ContextMenuTurboModule } from './ContextMenuTurboModule';
29
+
30
+ class ContextMenuTurboModulesFactory extends TurboModulesFactory {
31
+ createTurboModule(name: string): TurboModule | null {
32
+ if (name === "ContextMenuTurboModule") {
33
+ console.log('20240722---我在ArkTs侧获取到了点击事件!ContextMenuTurboModulesFactory')
34
+ return new ContextMenuTurboModule(this.ctx);
35
+ }
36
+ return null;
37
+ }
38
+
39
+ hasTurboModule(name: string): boolean {
40
+ return name === "ContextMenuTurboModule";
41
+ }
42
+ }
43
+
44
+ export class ContextMenuPackage extends RNOHPackage {
45
+ createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory {
46
+ return new ContextMenuTurboModulesFactory(ctx);
47
+ }
48
+ }
@@ -0,0 +1,224 @@
1
+ /**
2
+ * MIT License
3
+ *
4
+ * Copyright (C) 2024 Huawei Device Co., Ltd.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { RNOHContext, } from '@rnoh/react-native-openharmony'
26
+ import Logger from './Logger';
27
+ import { SymbolGlyphModifier } from '@kit.ArkUI';
28
+ import { ContextMenuThreeMenuWithNoSelect } from './ContextMenuThreeMenuWithNoSelect';
29
+
30
+ //这里的属性类型要和ContextMenuTurboModule.ets下的ContextMenuProps一致
31
+ interface ContextMenuProps {
32
+ tag?: number;
33
+ width?: number;
34
+ height?: number;
35
+ x?: number;
36
+ y?: number;
37
+ windowX?: number;
38
+ windowY?: number;
39
+ title?: string;
40
+ action?: string;
41
+ dropdownMenuMode?: boolean;
42
+ disabled?: boolean;
43
+ subtitle?: string;
44
+
45
+ // disabledArray?: Array<boolean>;
46
+ selected?: boolean;
47
+ previewBackgroundColor?: string;
48
+ actionsTitle?: string;
49
+ touchViewActions?: ContextMenuProps
50
+ ctx: RNOHContext
51
+ romWidth?: number;
52
+ romHeight?: number;
53
+ systemIcon?: string;
54
+ icon?: string;
55
+ destructive?: string
56
+ iconColor?: string;
57
+
58
+ //二级目录
59
+ inlineChildren?: boolean;
60
+ d_childActions?: ContextMenuProps;
61
+ childActionsTag?: number;
62
+
63
+ //2+目录
64
+ childActions?: ContextMenuProps;
65
+ }
66
+
67
+ @Component
68
+ export struct ContextMenuThreeMenu {
69
+ public static readonly NAME = "ContextMenuThreeMenu"
70
+ menuCtx!: RNOHContext;
71
+ menuTag: number = 0;
72
+ longPress: ESObject = []
73
+ @State realViewPoint: Object = [];
74
+ @State listDate: ContextMenuProps[] = [];
75
+ @State menuIndexPath: number[] = [];
76
+ @State menuDestructive: string = '';
77
+ @State childActionsListDate: ESObject[] = [];
78
+ @State isTouch: boolean | undefined = false;
79
+ @State isTouchViewNumber: number = 0;
80
+ @State isChildActionsTouchViewNumber: number = 0;
81
+ @State menuChildActions: ContextMenuProps[] = [];
82
+ @State menuChild: ESObject[] = [];
83
+ @State deepChildActions: ESObject[] = [];
84
+ @State isShow: boolean = false;
85
+ @State nextMenu: ESObject[] = [];
86
+ @State selectedFlag: number = 0;
87
+
88
+ aboutToAppear() {
89
+ //从前一个菜单传递过来的
90
+ this.longPress = this.realViewPoint;
91
+ this.menuCtx = this.menuCtx;
92
+ this.menuTag = this.menuTag;
93
+ Logger.info('2024-3menu:' + JSON.stringify(this.longPress))
94
+ //menu的大标题
95
+ this.listDate = this.longPress;
96
+ Logger.info('2024-3menu,this.listDate:' + JSON.stringify(this.listDate))
97
+ for (let i = 0; i < this.listDate.length; i++) {
98
+ if (this.listDate[i] !== null && this.listDate[i] !== undefined) {
99
+ //为true,表示禁用,对应harmony next 的false
100
+ if (this.listDate[i].disabled) {
101
+ //为true,表示禁用,对应harmony next 的false
102
+ this.listDate[i].disabled = false;
103
+ } else {
104
+ //contextMenu的false 对标 harmony 的 true
105
+ this.listDate[i].disabled = true;
106
+ }
107
+ }
108
+ }
109
+ //遍历传递回前端的indexPath,indexPath只会计算子节点index
110
+ //第一个节点表示对应的深层目录,从3级起算
111
+ for (let i = 0; i < this.listDate.length; i++) {
112
+ this.menuIndexPath[i+1] = i;
113
+ }
114
+ for (let i = 0; i < this.listDate.length; i++) {
115
+ if (this.longPress[i].selected) {
116
+ this.selectedFlag++;
117
+ }
118
+ }
119
+ }
120
+
121
+ //退出组件
122
+ aboutToDisappear() {
123
+ }
124
+
125
+ @Builder
126
+ NextMenu() {
127
+ ContextMenuThreeMenu(
128
+ {
129
+ realViewPoint: this.nextMenu,
130
+ menuCtx: this.menuCtx,
131
+ menuTag: this.menuTag
132
+ });
133
+ }
134
+
135
+ @Builder
136
+ NextMenuWithNoSelect() {
137
+ ContextMenuThreeMenuWithNoSelect(
138
+ {
139
+ realViewPoint: this.nextMenu,
140
+ menuCtx: this.menuCtx,
141
+ menuTag: this.menuTag
142
+ });
143
+ }
144
+
145
+ build() {
146
+ Menu() {
147
+ ForEach(this.listDate, (childItem: ContextMenuProps, index1) => {
148
+ if (childItem.systemIcon) {
149
+ MenuItem({
150
+ content: childItem.title,
151
+ symbolEndIcon: new SymbolGlyphModifier($r(childItem.systemIcon)).fontSize('24vp')
152
+ .fontColor([childItem.iconColor]),
153
+ labelInfo: childItem.subtitle,
154
+ builder: (): void => {
155
+ if (childItem.childActions !== undefined) {
156
+ this.nextMenu = this.longPress[index1].childActions;
157
+ if (this.selectedFlag !== 0) {
158
+ this.NextMenu();
159
+ } else {
160
+ this.NextMenuWithNoSelect();
161
+ }
162
+ }
163
+ }
164
+ })//selected复选标记,根据传入的selected来判断selected为默认为false,不显示
165
+ .selected(childItem.selected)
166
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
167
+ .alignSelf(ItemAlign.Start)
168
+ .enabled(childItem.disabled)
169
+ .contentFontColor(childItem.destructive)
170
+ .onClick(() => {
171
+ this.nextMenu = this.longPress[index1].childActions;
172
+ this.isTouch = true && (!childItem.inlineChildren) && (childItem.childActions !== undefined);
173
+ this.isTouchViewNumber = index1;
174
+ if (childItem.inlineChildren || (childItem.childActions == undefined)) {
175
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
176
+ itemTitle: childItem.title,
177
+ itemTag: this.menuTag,
178
+ itemIndex: index1,
179
+ itemIndexPath: this.menuIndexPath,
180
+ itemInlineChildren: childItem.inlineChildren
181
+ });
182
+ }
183
+ })
184
+ } else {
185
+ MenuItem({
186
+ content: childItem.title,
187
+ endIcon: $r(childItem.icon),
188
+ labelInfo: childItem.subtitle,
189
+ builder: (): void => {
190
+ if (childItem.childActions !== undefined) {
191
+ this.nextMenu = this.longPress[index1].childActions;
192
+ if (this.selectedFlag !== 0) {
193
+ this.NextMenu();
194
+ } else {
195
+ this.NextMenuWithNoSelect();
196
+ }
197
+ }
198
+ }
199
+ })//selected复选标记,根据传入的selected来判断selected为默认为false,不显示
200
+ .selected(childItem.selected)
201
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
202
+ .alignSelf(ItemAlign.Start)
203
+ .enabled(childItem.disabled)
204
+ .contentFontColor(childItem.destructive)
205
+ .onClick(() => {
206
+ this.nextMenu = this.longPress[index1].childActions;
207
+ this.isTouch = true && (!childItem.inlineChildren) && (childItem.childActions !== undefined);
208
+ this.isTouchViewNumber = index1;
209
+ if (childItem.inlineChildren || (childItem.childActions == undefined)) {
210
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
211
+ itemTitle: childItem.title,
212
+ itemTag: this.menuTag,
213
+ itemIndex: index1,
214
+ itemIndexPath: this.menuIndexPath,
215
+ itemInlineChildren: childItem.inlineChildren
216
+ });
217
+ }
218
+ })
219
+ }
220
+
221
+ })
222
+ }
223
+ }
224
+ }