@react-native-ohos/react-native-context-menu-view 1.19.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 +9 -0
  6. package/harmony/context_menu/hvigorfile.ts +2 -0
  7. package/harmony/context_menu/index.ets +26 -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 +59 -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 +34 -0
  18. package/harmony/context_menu/src/main/cpp/Props.h +121 -0
  19. package/harmony/context_menu/src/main/cpp/RTNContextMenuComponentInstance.cpp +290 -0
  20. package/harmony/context_menu/src/main/cpp/RTNContextMenuComponentInstance.h +168 -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 +393 -0
  26. package/harmony/context_menu/src/main/ets/ContextMenuLongPressWithNoSelect.ets +375 -0
  27. package/harmony/context_menu/src/main/ets/ContextMenuPackage.ets +47 -0
  28. package/harmony/context_menu/src/main/ets/ContextMenuThreeMenu.ets +225 -0
  29. package/harmony/context_menu/src/main/ets/ContextMenuThreeMenuWithNoSelect.ets +222 -0
  30. package/harmony/context_menu/src/main/ets/ContextMenuTurboModule.ets +297 -0
  31. package/harmony/context_menu/src/main/ets/ContextMenuTwoMenu.ets +210 -0
  32. package/harmony/context_menu/src/main/ets/ContextMenuTwoMenuWithNoSelect.ets +208 -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 +39 -0
  49. package/react-native-context-menu-view.podspec +26 -0
  50. package/src/RTNContextMenuNativeComponent.ts +50 -0
@@ -0,0 +1,375 @@
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
+ titleColor?: string;
42
+ action?: string;
43
+ dropdownMenuMode?: boolean;
44
+ disabled?: boolean;
45
+ subtitle?: string;
46
+
47
+ // disabledArray?: Array<boolean>;
48
+ selected?: boolean;
49
+ previewBackgroundColor?: string;
50
+ actionsTitle?: string;
51
+ touchViewActions?: ContextMenuProps
52
+ ctx: RNOHContext
53
+ romWidth?: number;
54
+ romHeight?: number;
55
+ systemIcon?: string;
56
+ icon?: string;
57
+ destructive?: string
58
+ iconColor?: string;
59
+ fontName?: string;
60
+
61
+ //二级目录
62
+ inlineChildren?: boolean;
63
+ d_childActions?: ContextMenuProps;
64
+ childActionsTag?: number;
65
+
66
+ //2+目录
67
+ childActions?: ContextMenuProps;
68
+ }
69
+
70
+ @Component
71
+ export struct ContextMenuLongPressWithNoSelect {
72
+ public static readonly NAME = "ContextMenuLongPressWithNoSelect"
73
+ menuCtx!: RNOHContext;
74
+ menuTag: number = 0;
75
+ @State realViewPoint: Object = [];
76
+ @State listDate: ContextMenuProps[] = [];
77
+ @State menuTitle: string = '';
78
+ @State menuX: number = 0;
79
+ @State menuY: number = 0;
80
+ @State menuWidth: number = 0;
81
+ @State menuHeight: number = 0;
82
+ @State menuDisable: boolean = true;
83
+ @State menuRomWidth: number = 0;
84
+ @State menuRomHeight: number = 0;
85
+ @State menuWindowX: number = 0;
86
+ @State menuWindowY: number = 0;
87
+ @State menuIndexPath: number[] = [];
88
+ @State menuDestructive: string = '';
89
+ @State childActionsListDate: ESObject[] = [];
90
+ @State isTouch: boolean | undefined = false;
91
+ @State isTouchWithNoSelect: boolean | undefined = false;
92
+ @State isTouchViewNumber: number = 0;
93
+ @State isChildActionsTouchViewNumber: number = 0;
94
+ @State menuChildActions: ContextMenuProps[] = [];
95
+ @State menuChild: ESObject[] = [];
96
+ @State deepChildActions: ESObject[] = [];
97
+ @State isShow: boolean = false;
98
+ @State twoMenu: ESObject[] = [];
99
+ @State selectedFlag: ESObject[] = [ ];
100
+ @State menuFontName: string = '';
101
+ private uiContext: UIContext = this.getUIContext();
102
+
103
+ aboutToAppear() {
104
+ let longPress: ESObject = this.realViewPoint;
105
+ // 获取Font资源
106
+ this.menuFontName = longPress.fontName
107
+ this.uiContext.getFont().registerFont({
108
+ familyName: this.menuFontName,
109
+ familySrc: $rawfile(`${this.menuFontName}.TTF`)
110
+ })
111
+ //menu的大标题
112
+ this.menuTitle = longPress.title;
113
+ //获取menu的xy轴,以及view视图的长宽
114
+ this.menuX = longPress.x;
115
+ this.menuY = longPress.y;
116
+ this.menuWidth = longPress.width;
117
+ this.menuHeight = longPress.height;
118
+ this.menuCtx = longPress.ctx;
119
+ this.menuTag = longPress.tag;
120
+ //获取设备的长宽
121
+ this.menuRomWidth = longPress.romWidth;
122
+ this.menuRomHeight = longPress.romHeight;
123
+ //获取点击时候的点击事件的xy,基于屏幕左上角
124
+ this.menuWindowX = longPress.windowX;
125
+ this.menuWindowY = longPress.windowY;
126
+ this.listDate = longPress.touchViewActions;
127
+ //判断destructive(可破坏),默认false,表示不可破坏。
128
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
129
+ if (longPress.touchViewActions[i].destructive) {
130
+ //可破坏为红色
131
+ this.listDate[i].titleColor = 'red';
132
+ }
133
+ }
134
+ // contextMenu入参为disabled,是否禁用选项,默认为false,表示不用禁用.
135
+ // 但是在harmony Next调用enable的入参,harmony Next:true = RN:false
136
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
137
+ if (longPress.touchViewActions[i].disabled) {
138
+ //为true,表示禁用,对应harmony next 的false
139
+ this.listDate[i].disabled = false;
140
+ } else {
141
+ //contextMenu的false 对标 harmony 的 true
142
+ this.listDate[i].disabled = true;
143
+ }
144
+ }
145
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
146
+ if (longPress.touchViewActions[i].selected) {
147
+ //复选框,默认为false
148
+ this.listDate[i].selected = true;
149
+ } else {
150
+ this.listDate[i].selected = false;
151
+ }
152
+ }
153
+
154
+ //遍历传递回前端的indexPath,indexPath只会计算子节点index
155
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
156
+ this.menuIndexPath[i] = i;
157
+ }
158
+
159
+ //二级目录,均和一级目录一致
160
+ // 遍历查询是否有二级目录
161
+ for (let i = 0; i < longPress.touchViewActions.length; i++) {
162
+ if (longPress.touchViewActions[i].d_childActions !== '' ||
163
+ longPress.touchViewActions[i].d_childActions !== undefined ||
164
+ longPress.touchViewActions[i].d_childActions !== null) {
165
+ //有二级菜单
166
+ this.childActionsListDate[i] = longPress.touchViewActions[i].d_childActions;
167
+ }
168
+ }
169
+ ;
170
+
171
+ for (let i = 0; i < this.childActionsListDate.length; i++) {
172
+ if (this.childActionsListDate[i] !== null && this.childActionsListDate[i] !== undefined &&
173
+ this.childActionsListDate[i] !== '') {
174
+ let j = i;
175
+ //默认为false,这里判断disabled
176
+ for (let k = 0; k < this.childActionsListDate[j].length; k++) {
177
+ this.menuIndexPath[k] = k;
178
+ if ((this.childActionsListDate[j])[k].disabled) {
179
+ (this.childActionsListDate[j])[k].disabled = false;
180
+ } else {
181
+ //contextMenu的false 对标 harmony 的 true
182
+ (this.childActionsListDate[j])[k].disabled = true;
183
+ }
184
+ if ((this.childActionsListDate[j])[k].selected) {
185
+ this.selectedFlag[k] = 1;
186
+ } else {
187
+ this.selectedFlag[k] = 0;
188
+ }
189
+ }
190
+ }
191
+ }
192
+ console.log('20240919----------------------'+JSON.stringify(this.childActionsListDate.length));
193
+ }
194
+
195
+ //退出组件
196
+ aboutToDisappear() {
197
+ }
198
+
199
+ @Builder
200
+ twoMenuView() {
201
+ ContextMenuTwoMenu(
202
+ {
203
+ realViewPoint: this.twoMenu,
204
+ menuCtx: this.menuCtx,
205
+ menuTag: this.menuTag
206
+ });
207
+ }
208
+
209
+ @Builder
210
+ twoMenuViewWithNoSelect() {
211
+ ContextMenuTwoMenuWithNoSelect(
212
+ {
213
+ realViewPoint: this.twoMenu,
214
+ menuCtx: this.menuCtx,
215
+ menuTag: this.menuTag
216
+ });
217
+ }
218
+
219
+ build() {
220
+ Menu() {
221
+ MenuItemGroup({ header: this.menuTitle }) {
222
+ //遍历数据,把每个menuTitle塞入到对应的menu中
223
+ ForEach(this.listDate, (item: ContextMenuProps, index) => {
224
+ if (item.systemIcon) {
225
+ if (this.childActionsListDate.length >= 0) {
226
+ MenuItem({
227
+ content: item.title,
228
+ symbolEndIcon: new SymbolGlyphModifier($r(item.systemIcon)).fontSize('24vp')
229
+ .fontColor([item.iconColor]),
230
+ labelInfo: item.subtitle,
231
+ })
232
+ .contentFont({
233
+ family : this.menuFontName
234
+ })
235
+ .alignSelf(ItemAlign.Start)
236
+ .enabled(item.disabled)
237
+ .contentFontColor(item.titleColor)
238
+ .onClick(() => {
239
+ //当item.inlineChildren默认为false,表示以二级目录展示
240
+ //true的时候,以同目录展示
241
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
242
+ this.isTouchWithNoSelect = this.isTouch ;
243
+ this.isTouchViewNumber = index;
244
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
245
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
246
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
247
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
248
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
249
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
250
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
251
+ itemTitle: item.title,
252
+ itemTag: this.menuTag,
253
+ itemIndex: index,
254
+ itemIndexPath: [0],
255
+ itemInlineChildren: item.inlineChildren
256
+ });
257
+ } })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
258
+ .bindContextMenu(this.isTouch, this.twoMenuView())
259
+
260
+ } else {
261
+ MenuItem({
262
+ content: item.title,
263
+ symbolEndIcon: new SymbolGlyphModifier($r(item.systemIcon)).fontSize('24vp')
264
+ .fontColor([item.iconColor]),
265
+ labelInfo: item.subtitle,
266
+ })
267
+ .contentFont({
268
+ family : this.menuFontName
269
+ })
270
+ .alignSelf(ItemAlign.Start)
271
+ .enabled(item.disabled)
272
+ .contentFontColor(item.titleColor)
273
+ .onClick(() => {
274
+ //当item.inlineChildren默认为false,表示以二级目录展示
275
+ //true的时候,以同目录展示
276
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
277
+ this.isTouchWithNoSelect = this.isTouch ;
278
+ this.isTouchViewNumber = index;
279
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
280
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
281
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
282
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
283
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
284
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
285
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
286
+ itemTitle: item.title,
287
+ itemTag: this.menuTag,
288
+ itemIndex: index,
289
+ itemIndexPath: [0],
290
+ itemInlineChildren: item.inlineChildren
291
+ });
292
+ }
293
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
294
+ .bindContextMenu(this.isTouchWithNoSelect, this.twoMenuViewWithNoSelect())
295
+ }
296
+ } else {
297
+ //如果没有systemIcon,则走自定义图标
298
+ if (this.childActionsListDate.length >= 0) {
299
+ MenuItem({
300
+ content: item.title,
301
+ endIcon: $r(item.icon),
302
+ labelInfo: item.subtitle,
303
+ })
304
+ .contentFont({
305
+ family : this.menuFontName
306
+ })
307
+ .alignSelf(ItemAlign.Start)
308
+ .enabled(item.disabled)
309
+ .contentFontColor(item.titleColor)
310
+ .onClick(() => {
311
+ //当item.inlineChildren默认为false,表示以二级目录展示
312
+ //true的时候,以同目录展示
313
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
314
+ this.isTouchViewNumber = index;
315
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
316
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
317
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
318
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
319
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
320
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
321
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
322
+ itemTitle: item.title,
323
+ itemTag: this.menuTag,
324
+ itemIndex: index,
325
+ itemIndexPath: [0],
326
+ itemInlineChildren: item.inlineChildren
327
+ });
328
+ }
329
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
330
+ .bindContextMenu(this.isTouch, this.twoMenuView())
331
+ } else {
332
+ MenuItem({
333
+ content: item.title,
334
+ endIcon: $r(item.icon),
335
+ labelInfo: item.subtitle,
336
+ })
337
+ .contentFont({
338
+ family : this.menuFontName
339
+ })
340
+ .alignSelf(ItemAlign.Start)
341
+ .enabled(item.disabled)
342
+ .contentFontColor(item.titleColor)
343
+ .onClick(() => {
344
+ //当item.inlineChildren默认为false,表示以二级目录展示
345
+ //true的时候,以同目录展示
346
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
347
+ this.isTouchWithNoSelect = this.isTouch;
348
+ this.isTouchViewNumber = index;
349
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
350
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
351
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
352
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
353
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
354
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
355
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
356
+ itemTitle: item.title,
357
+ itemTag: this.menuTag,
358
+ itemIndex: index,
359
+ itemIndexPath: [0],
360
+ itemInlineChildren: item.inlineChildren
361
+ });
362
+ }
363
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
364
+ .bindContextMenu(this.isTouchWithNoSelect, this.twoMenuViewWithNoSelect())
365
+ }
366
+ }
367
+ })
368
+ }.backgroundColor('white')
369
+ }.onDisAppear(() => {
370
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::onCancel', {
371
+ itemTag: this.menuTag,
372
+ });
373
+ })
374
+ }
375
+ }
@@ -0,0 +1,47 @@
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 {RNPackage, TurboModulesFactory} from '@rnoh/react-native-openharmony/ts';
26
+ import type {TurboModule, TurboModuleContext} from '@rnoh/react-native-openharmony/ts';
27
+ import { ContextMenuTurboModule } from './ContextMenuTurboModule';
28
+
29
+ class ContextMenuTurboModulesFactory extends TurboModulesFactory {
30
+ createTurboModule(name: string): TurboModule | null {
31
+ if (name === "ContextMenuTurboModule") {
32
+ console.log('20240722---我在ArkTs侧获取到了点击事件!ContextMenuTurboModulesFactory')
33
+ return new ContextMenuTurboModule(this.ctx);
34
+ }
35
+ return null;
36
+ }
37
+
38
+ hasTurboModule(name: string): boolean {
39
+ return name === "ContextMenuTurboModule";
40
+ }
41
+ }
42
+
43
+ export class ContextMenuPackage extends RNPackage {
44
+ createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory {
45
+ return new ContextMenuTurboModulesFactory(ctx);
46
+ }
47
+ }
@@ -0,0 +1,225 @@
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
+ titleColor?: 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 ContextMenuThreeMenu {
70
+ public static readonly NAME = "ContextMenuThreeMenu"
71
+ menuCtx!: RNOHContext;
72
+ menuTag: number = 0;
73
+ longPress: ESObject = []
74
+ @State realViewPoint: Object = [];
75
+ @State listDate: ContextMenuProps[] = [];
76
+ @State menuIndexPath: number[] = [];
77
+ @State menuDestructive: string = '';
78
+ @State childActionsListDate: ESObject[] = [];
79
+ @State isTouch: boolean | undefined = false;
80
+ @State isTouchViewNumber: number = 0;
81
+ @State isChildActionsTouchViewNumber: number = 0;
82
+ @State menuChildActions: ContextMenuProps[] = [];
83
+ @State menuChild: ESObject[] = [];
84
+ @State deepChildActions: ESObject[] = [];
85
+ @State isShow: boolean = false;
86
+ @State nextMenu: ESObject[] = [];
87
+ @State selectedFlag: number = 0;
88
+
89
+ aboutToAppear() {
90
+ //从前一个菜单传递过来的
91
+ this.longPress = this.realViewPoint;
92
+ this.menuCtx = this.menuCtx;
93
+ this.menuTag = this.menuTag;
94
+ Logger.info('2024-3menu:' + JSON.stringify(this.longPress))
95
+ //menu的大标题
96
+ this.listDate = this.longPress;
97
+ Logger.info('2024-3menu,this.listDate:' + JSON.stringify(this.listDate))
98
+ for (let i = 0; i < this.listDate.length; i++) {
99
+ if (this.listDate[i] !== null && this.listDate[i] !== undefined) {
100
+ //为true,表示禁用,对应harmony next 的false
101
+ if (this.listDate[i].disabled) {
102
+ //为true,表示禁用,对应harmony next 的false
103
+ this.listDate[i].disabled = false;
104
+ } else {
105
+ //contextMenu的false 对标 harmony 的 true
106
+ this.listDate[i].disabled = true;
107
+ }
108
+ }
109
+ }
110
+ //遍历传递回前端的indexPath,indexPath只会计算子节点index
111
+ //第一个节点表示对应的深层目录,从3级起算
112
+ for (let i = 0; i < this.listDate.length; i++) {
113
+ this.menuIndexPath[i+1] = i;
114
+ }
115
+ for (let i = 0; i < this.listDate.length; i++) {
116
+ if (this.longPress[i].selected) {
117
+ this.selectedFlag++;
118
+ }
119
+ }
120
+ }
121
+
122
+ //退出组件
123
+ aboutToDisappear() {
124
+ }
125
+
126
+ @Builder
127
+ NextMenu() {
128
+ ContextMenuThreeMenu(
129
+ {
130
+ realViewPoint: this.nextMenu,
131
+ menuCtx: this.menuCtx,
132
+ menuTag: this.menuTag
133
+ });
134
+ }
135
+
136
+ @Builder
137
+ NextMenuWithNoSelect() {
138
+ ContextMenuThreeMenuWithNoSelect(
139
+ {
140
+ realViewPoint: this.nextMenu,
141
+ menuCtx: this.menuCtx,
142
+ menuTag: this.menuTag
143
+ });
144
+ }
145
+
146
+ build() {
147
+ Menu() {
148
+ ForEach(this.listDate, (childItem: ContextMenuProps, index1) => {
149
+ if (childItem.systemIcon) {
150
+ MenuItem({
151
+ content: childItem.title,
152
+ symbolEndIcon: new SymbolGlyphModifier($r(childItem.systemIcon)).fontSize('24vp')
153
+ .fontColor([childItem.iconColor]),
154
+ labelInfo: childItem.subtitle,
155
+ builder: (): void => {
156
+ if (childItem.childActions !== undefined) {
157
+ this.nextMenu = this.longPress[index1].childActions;
158
+ if (this.selectedFlag !== 0) {
159
+ this.NextMenu();
160
+ } else {
161
+ this.NextMenuWithNoSelect();
162
+ }
163
+ }
164
+ }
165
+ })//selected复选标记,根据传入的selected来判断selected为默认为false,不显示
166
+ .selected(childItem.selected)
167
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
168
+ .alignSelf(ItemAlign.Start)
169
+ .enabled(childItem.disabled)
170
+ .contentFontColor(childItem.titleColor)
171
+ .onClick(() => {
172
+ this.nextMenu = this.longPress[index1].childActions;
173
+ this.isTouch = true && (!childItem.inlineChildren) && (childItem.childActions !== undefined);
174
+ this.isTouchViewNumber = index1;
175
+ if (childItem.inlineChildren || (childItem.childActions == undefined)) {
176
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
177
+ itemTitle: childItem.title,
178
+ itemTag: this.menuTag,
179
+ itemIndex: index1,
180
+ itemIndexPath: this.menuIndexPath,
181
+ itemInlineChildren: childItem.inlineChildren
182
+ });
183
+ }
184
+ })
185
+ } else {
186
+ MenuItem({
187
+ content: childItem.title,
188
+ endIcon: $r(childItem.icon),
189
+ labelInfo: childItem.subtitle,
190
+ builder: (): void => {
191
+ if (childItem.childActions !== undefined) {
192
+ this.nextMenu = this.longPress[index1].childActions;
193
+ if (this.selectedFlag !== 0) {
194
+ this.NextMenu();
195
+ } else {
196
+ this.NextMenuWithNoSelect();
197
+ }
198
+ }
199
+ }
200
+ })//selected复选标记,根据传入的selected来判断selected为默认为false,不显示
201
+ .selected(childItem.selected)
202
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
203
+ .alignSelf(ItemAlign.Start)
204
+ .enabled(childItem.disabled)
205
+ .contentFontColor(childItem.titleColor)
206
+ .onClick(() => {
207
+ this.nextMenu = this.longPress[index1].childActions;
208
+ this.isTouch = true && (!childItem.inlineChildren) && (childItem.childActions !== undefined);
209
+ this.isTouchViewNumber = index1;
210
+ if (childItem.inlineChildren || (childItem.childActions == undefined)) {
211
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
212
+ itemTitle: childItem.title,
213
+ itemTag: this.menuTag,
214
+ itemIndex: index1,
215
+ itemIndexPath: this.menuIndexPath,
216
+ itemInlineChildren: childItem.inlineChildren
217
+ });
218
+ }
219
+ })
220
+ }
221
+
222
+ })
223
+ }
224
+ }
225
+ }