@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,393 @@
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 ContextMenuLongPress {
72
+ public static readonly NAME = "ContextMenuLongPress"
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: number = 0;
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++;
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ //退出组件
193
+ aboutToDisappear() {
194
+ }
195
+
196
+ @Builder
197
+ twoMenuView() {
198
+ ContextMenuTwoMenu(
199
+ {
200
+ realViewPoint: this.twoMenu,
201
+ menuCtx: this.menuCtx,
202
+ menuTag: this.menuTag
203
+ });
204
+ }
205
+
206
+ @Builder
207
+ twoMenuViewWithNoSelect() {
208
+ ContextMenuTwoMenuWithNoSelect(
209
+ {
210
+ realViewPoint: this.twoMenu,
211
+ menuCtx: this.menuCtx,
212
+ menuTag: this.menuTag
213
+ });
214
+ }
215
+
216
+ build() {
217
+ Menu() {
218
+ MenuItemGroup({ header: this.menuTitle }) {
219
+ //遍历数据,把每个menuTitle塞入到对应的menu中
220
+ ForEach(this.listDate, (item: ContextMenuProps, index) => {
221
+ if (item.systemIcon) {
222
+ if (this.selectedFlag !== 0) {
223
+ MenuItem({
224
+ content: item.title,
225
+ symbolEndIcon: new SymbolGlyphModifier($r(item.systemIcon)).fontSize('24vp')
226
+ .fontColor([item.iconColor]),
227
+ labelInfo: item.subtitle,
228
+ })
229
+ .contentFont({
230
+ family : this.menuFontName
231
+ })
232
+ .selected(item.selected)
233
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
234
+ .alignSelf(ItemAlign.Start)
235
+ .enabled(item.disabled)
236
+ .contentFontColor(item.titleColor)
237
+ .onClick(() => {
238
+ //当item.inlineChildren默认为false,表示以二级目录展示
239
+ //true的时候,以同目录展示
240
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
241
+ this.isTouchWithNoSelect = this.isTouch && (this.selectedFlag == 0);
242
+ if (this.isTouchWithNoSelect && this.isTouch) {
243
+ this.isTouch = false;
244
+ }
245
+ this.isTouchViewNumber = index;
246
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
247
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
248
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
249
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
250
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
251
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
252
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
253
+ itemTitle: item.title,
254
+ itemTag: this.menuTag,
255
+ itemIndex: index,
256
+ itemIndexPath: [0],
257
+ itemInlineChildren: item.inlineChildren
258
+ });
259
+ }
260
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
261
+ .bindContextMenu(this.isTouch, this.twoMenuView())
262
+ } else {
263
+ MenuItem({
264
+ content: item.title,
265
+ symbolEndIcon: new SymbolGlyphModifier($r(item.systemIcon)).fontSize('24vp')
266
+ .fontColor([item.iconColor]),
267
+ labelInfo: item.subtitle,
268
+ })
269
+ .contentFont({
270
+ family : this.menuFontName
271
+ })
272
+ .selected(item.selected)
273
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
274
+ .alignSelf(ItemAlign.Start)
275
+ .enabled(item.disabled)
276
+ .contentFontColor(item.titleColor)
277
+ .onClick(() => {
278
+ //当item.inlineChildren默认为false,表示以二级目录展示
279
+ //true的时候,以同目录展示
280
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
281
+ this.isTouchWithNoSelect = this.isTouch && (this.selectedFlag == 0);
282
+ if (this.isTouchWithNoSelect && this.isTouch) {
283
+ this.isTouch = false;
284
+ }
285
+ this.isTouchViewNumber = index;
286
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
287
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
288
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
289
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
290
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
291
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
292
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
293
+ itemTitle: item.title,
294
+ itemTag: this.menuTag,
295
+ itemIndex: index,
296
+ itemIndexPath: [0],
297
+ itemInlineChildren: item.inlineChildren
298
+ });
299
+ }
300
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
301
+ .bindContextMenu(this.isTouchWithNoSelect, this.twoMenuViewWithNoSelect())
302
+ }
303
+ } else {
304
+ //如果没有systemIcon,则走自定义图标
305
+ if (this.selectedFlag !== 0) {
306
+ MenuItem({
307
+ content: item.title,
308
+ endIcon: $r(item.icon),
309
+ labelInfo: item.subtitle,
310
+ })
311
+ .contentFont({
312
+ family : this.menuFontName
313
+ })
314
+ .selected(item.selected)
315
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
316
+ .alignSelf(ItemAlign.Start)
317
+ .enabled(item.disabled)
318
+ .contentFontColor(item.titleColor)
319
+ .onClick(() => {
320
+ //当item.inlineChildren默认为false,表示以二级目录展示
321
+ //true的时候,以同目录展示
322
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
323
+ this.isTouchWithNoSelect = this.isTouch && (this.selectedFlag == 0);
324
+ if (this.isTouchWithNoSelect && this.isTouch) {
325
+ this.isTouch = false;
326
+ }
327
+ this.isTouchViewNumber = index;
328
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
329
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
330
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
331
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
332
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
333
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
334
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
335
+ itemTitle: item.title,
336
+ itemTag: this.menuTag,
337
+ itemIndex: index,
338
+ itemIndexPath: [0],
339
+ itemInlineChildren: item.inlineChildren
340
+ });
341
+ }
342
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
343
+ .bindContextMenu(this.isTouch, this.twoMenuView())
344
+ } else {
345
+ MenuItem({
346
+ content: item.title,
347
+ endIcon: $r(item.icon),
348
+ labelInfo: item.subtitle,
349
+ })
350
+ .contentFont({
351
+ family : this.menuFontName
352
+ })
353
+ .selected(item.selected)
354
+ .selectIcon(new SymbolGlyphModifier($r('sys.symbol.checkmark')).fontSize('24vp'))
355
+ .alignSelf(ItemAlign.Start)
356
+ .enabled(item.disabled)
357
+ .contentFontColor(item.titleColor)
358
+ .onClick(() => {
359
+ //当item.inlineChildren默认为false,表示以二级目录展示
360
+ //true的时候,以同目录展示
361
+ this.isTouch = true && (!item.inlineChildren) && (item.d_childActions !== undefined);
362
+ this.isTouchWithNoSelect = this.isTouch && (this.selectedFlag == 0);
363
+ if (this.isTouchWithNoSelect && this.isTouch) {
364
+ this.isTouch = false;
365
+ }
366
+ this.isTouchViewNumber = index;
367
+ this.twoMenu = this.childActionsListDate[this.isTouchViewNumber]
368
+ console.log('2024touch:' + this.isTouch + ',' + 'inlineChildren:' + item.inlineChildren + ',' +
369
+ 'isTouchViewNumber:' + this.isTouchViewNumber);
370
+ //当item.inlineChildren默认为false,二级目录展示时候,点击一级目录,不关闭,在二级目录后关闭
371
+ //当item.inlineChildren为false的时候,就不需要关闭该窗口.
372
+ if (item.inlineChildren || (item.d_childActions == undefined)) {
373
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::SET_NATIVE_RESPONDERS_BLOCK', {
374
+ itemTitle: item.title,
375
+ itemTag: this.menuTag,
376
+ itemIndex: index,
377
+ itemIndexPath: [0],
378
+ itemInlineChildren: item.inlineChildren
379
+ });
380
+ }
381
+ })//弹框,通过inlineChildren来判定是否有二级目录,ture有二级目录
382
+ .bindContextMenu(this.isTouchWithNoSelect, this.twoMenuViewWithNoSelect())
383
+ }
384
+ }
385
+ })
386
+ }.backgroundColor('white')
387
+ }.onDisAppear(() => {
388
+ this.menuCtx.rnInstance.postMessageToCpp('contextMenu::onCancel', {
389
+ itemTag: this.menuTag,
390
+ });
391
+ })
392
+ }
393
+ }