comparison ios/dw.m @ 2770:f42d78f136b6

iOS: Implement tree context menus and all the signal handler/callbacks. In the process, to simplify things the code shared with the containers has been converted to use NSPointerArray class instead of actual pointer arrays.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 11 Apr 2022 14:01:22 +0000
parents 06f45ee90e0f
children 52f3858035d8
comparison
equal deleted inserted replaced
2769:06f45ee90e0f 2770:f42d78f136b6
531 } 531 }
532 /* Container class selection event */ 532 /* Container class selection event */
533 case _DW_EVENT_ITEM_ENTER: 533 case _DW_EVENT_ITEM_ENTER:
534 { 534 {
535 int (*containerselectfunc)(HWND, char *, void *, void *) = handler->signalfunction; 535 int (*containerselectfunc)(HWND, char *, void *, void *) = handler->signalfunction;
536 void **params = (void **)event; 536
537 537 return containerselectfunc(handler->window, [event pointerAtIndex:0], handler->data,
538 return containerselectfunc(handler->window, params[0], handler->data, params[1]); 538 [event pointerAtIndex:1]);
539 } 539 }
540 /* Container context menu event */ 540 /* Container context menu event */
541 case _DW_EVENT_ITEM_CONTEXT: 541 case _DW_EVENT_ITEM_CONTEXT:
542 { 542 {
543 int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))handler->signalfunction; 543 int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))handler->signalfunction;
544 void **params = (void **)event; 544 char *text = (char *)[event pointerAtIndex:0];
545 char *text = (char *)params[0]; 545 void *user = [event pointerAtIndex:1];
546 void *user = params[1]; 546 int x = DW_POINTER_TO_INT([event pointerAtIndex:2]);
547 int x = DW_POINTER_TO_INT(params[2]); 547 int y = DW_POINTER_TO_INT([event pointerAtIndex:3]);
548 int y = DW_POINTER_TO_INT(params[3]);
549 548
550 return containercontextfunc(handler->window, text, x, y, handler->data, user); 549 return containercontextfunc(handler->window, text, x, y, handler->data, user);
551 } 550 }
552 /* Generic selection changed event for several classes */ 551 /* Generic selection changed event for several classes */
553 case _DW_EVENT_LIST_SELECT: 552 case _DW_EVENT_LIST_SELECT:
566 void *user = NULL; 565 void *user = NULL;
567 id item = nil; 566 id item = nil;
568 567
569 if([object isKindOfClass:[UITableView class]] && event) 568 if([object isKindOfClass:[UITableView class]] && event)
570 { 569 {
571 void **params = (void **)event; 570 /* Event will be NSPointerArray for Containers */
572 571 if([event isKindOfClass:[NSPointerArray class]])
573 text = params[0]; 572 {
574 user = params[1]; 573 text = [event pointerAtIndex:0];
574 user = [event pointerAtIndex:1];
575 }
576 else
577 {
578 /* Event should be DWTreeItem for Trees */
579 const char *title = [[item title] UTF8String];
580 int retval;
581
582 text = strdup(title ? title : "");
583 user = [item data];
584 item = event;
585
586 retval = treeselectfunc(handler->window, item, text, handler->data, user);
587 free(text);
588 return retval;
589 }
575 } 590 }
576 591
577 return treeselectfunc(handler->window, item, text, handler->data, user); 592 return treeselectfunc(handler->window, item, text, handler->data, user);
578 } 593 }
579 /* Set Focus event */ 594 /* Set Focus event */
2355 } 2370 }
2356 -(UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point 2371 -(UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point
2357 { 2372 {
2358 DWWindow *window = (DWWindow *)[self window]; 2373 DWWindow *window = (DWWindow *)[self window];
2359 UIContextMenuConfiguration *config = nil; 2374 UIContextMenuConfiguration *config = nil;
2360 void *params[4]; 2375 NSPointerArray *params = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsOpaqueMemory];
2361 2376
2362 params[0] = [self getRowTitle:(int)indexPath.row]; 2377 [params addPointer:[self getRowTitle:(int)indexPath.row]];
2363 params[1] = [self getRowData:(int)indexPath.row]; 2378 [params addPointer:[self getRowData:(int)indexPath.row]];
2364 params[2] = DW_INT_TO_POINTER((int)point.x); 2379 [params addPointer:DW_INT_TO_POINTER((int)point.x)];
2365 params[3] = DW_INT_TO_POINTER((int)point.y); 2380 [params addPointer:DW_INT_TO_POINTER((int)point.y)];
2366 2381
2367 _dw_event_point = point; 2382 _dw_event_point = point;
2368 _dw_event_handler(self, (id)params, _DW_EVENT_ITEM_CONTEXT); 2383 _dw_event_handler(self, params, _DW_EVENT_ITEM_CONTEXT);
2369 2384
2370 if(window && [window popupMenu]) 2385 if(window && [window popupMenu])
2371 { 2386 {
2372 __block UIMenu *popupmenu = [[[window popupMenu] menu] retain]; 2387 __block UIMenu *popupmenu = [[[window popupMenu] menu] retain];
2373 config = [UIContextMenuConfiguration configurationWithIdentifier:nil 2388 config = [UIContextMenuConfiguration configurationWithIdentifier:nil
2621 [fgcolor retain]; 2636 [fgcolor retain];
2622 [oldfgcolor release]; 2637 [oldfgcolor release];
2623 } 2638 }
2624 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 2639 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
2625 { 2640 {
2626 void *params[2]; 2641 NSPointerArray *params = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsOpaqueMemory];
2627 2642
2628 params[0] = (void *)[self getRowTitle:(int)indexPath.row]; 2643 [params addPointer:[self getRowTitle:(int)indexPath.row]];
2629 params[1] = (void *)[self getRowData:(int)indexPath.row]; 2644 [params addPointer:[self getRowData:(int)indexPath.row]];
2630 2645
2631 /* If multiple selection is enabled, treat it as selectionChanged: */ 2646 /* If multiple selection is enabled, treat it as selectionChanged: */
2632 if([self allowsMultipleSelection]) 2647 if([self allowsMultipleSelection])
2633 { 2648 {
2634 NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; 2649 NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
2635 2650
2636 /* Handler for container class... check for double tap */ 2651 /* Handler for container class... check for double tap */
2637 if(lastClickRow == indexPath.row && now - lastClick < 0.3) 2652 if(lastClickRow == indexPath.row && now - lastClick < 0.3)
2638 _dw_event_handler(self, (id)params, _DW_EVENT_ITEM_ENTER); 2653 _dw_event_handler(self, params, _DW_EVENT_ITEM_ENTER);
2639 else 2654 else
2640 _dw_event_handler(self, (id)params, _DW_EVENT_ITEM_SELECT); 2655 _dw_event_handler(self, params, _DW_EVENT_ITEM_SELECT);
2641 /* Handler for listbox class */ 2656 /* Handler for listbox class */
2642 _dw_event_handler(self, DW_INT_TO_POINTER((int)indexPath.row), _DW_EVENT_LIST_SELECT); 2657 _dw_event_handler(self, DW_INT_TO_POINTER((int)indexPath.row), _DW_EVENT_LIST_SELECT);
2643 /* Update lastClick for double tap check */ 2658 /* Update lastClick for double tap check */
2644 lastClick = now; 2659 lastClick = now;
2645 lastClickRow = indexPath.row; 2660 lastClickRow = indexPath.row;
2646 } 2661 }
2647 else /* Otherwise treat it as doubleClicked: */ 2662 else /* Otherwise treat it as doubleClicked: */
2648 { 2663 {
2649 /* Handler for container class */ 2664 /* Handler for container class */
2650 _dw_event_handler(self, (id)params, _DW_EVENT_ITEM_ENTER); 2665 _dw_event_handler(self, params, _DW_EVENT_ITEM_ENTER);
2651 } 2666 }
2652 } 2667 }
2653 -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 2668 -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
2654 { 2669 {
2655 if([self allowsMultipleSelection]) 2670 if([self allowsMultipleSelection])
2875 -(DWTreeItem *)treeView:(DWTree *)treeView treeItemForRow:(NSInteger)row; 2890 -(DWTreeItem *)treeView:(DWTree *)treeView treeItemForRow:(NSInteger)row;
2876 -(NSInteger)treeView:(DWTree *)treeView rowForTreeItem:(DWTreeItem *)treeItem; 2891 -(NSInteger)treeView:(DWTree *)treeView rowForTreeItem:(DWTreeItem *)treeItem;
2877 -(void)treeView:(DWTree *)treeView removeTreeItem:(DWTreeItem *)treeItem; 2892 -(void)treeView:(DWTree *)treeView removeTreeItem:(DWTreeItem *)treeItem;
2878 -(void)treeView:(DWTree *)treeView moveTreeItem:(DWTreeItem *)treeItem to:(DWTreeItem *)to; 2893 -(void)treeView:(DWTree *)treeView moveTreeItem:(DWTreeItem *)treeItem to:(DWTreeItem *)to;
2879 -(void)treeView:(DWTree *)treeView addTreeItem:(DWTreeItem *)treeItem; 2894 -(void)treeView:(DWTree *)treeView addTreeItem:(DWTreeItem *)treeItem;
2880 //@optional
2881 -(void)treeView:(DWTree *)treeView didSelectForTreeItem:(DWTreeItem *)treeItem; 2895 -(void)treeView:(DWTree *)treeView didSelectForTreeItem:(DWTreeItem *)treeItem;
2896 -(UIContextMenuConfiguration *)treeView:(DWTree *)treeView contextMenuConfigurationForTreeItem:(DWTreeItem *)treeItem point:(CGPoint)point;
2882 -(BOOL)treeView:(DWTree *)treeView queryExpandableInTreeItem:(DWTreeItem *)treeItem; 2897 -(BOOL)treeView:(DWTree *)treeView queryExpandableInTreeItem:(DWTreeItem *)treeItem;
2883 -(void)treeView:(DWTree *)treeView treeItem:(DWTreeItem *)treeItem expanded:(BOOL)expanded; 2898 -(void)treeView:(DWTree *)treeView treeItem:(DWTreeItem *)treeItem expanded:(BOOL)expanded;
2884 @optional 2899 @optional
2885 -(BOOL)treeView:(DWTree *)treeView canEditTreeItem:(DWTreeItem *)treeItem; 2900 -(BOOL)treeView:(DWTree *)treeView canEditTreeItem:(DWTreeItem *)treeItem;
2886 -(BOOL)treeView:(DWTree *)treeView canMoveTreeItem:(DWTreeItem *)treeItem; 2901 -(BOOL)treeView:(DWTree *)treeView canMoveTreeItem:(DWTreeItem *)treeItem;
2985 } 3000 }
2986 } 3001 }
2987 #pragma mark - DWTreeViewDelegate 3002 #pragma mark - DWTreeViewDelegate
2988 -(NSInteger)numberOfRowsInTreeView:(DWTree *)treeView { return [_rootNode visibleNodes].count; } 3003 -(NSInteger)numberOfRowsInTreeView:(DWTree *)treeView { return [_rootNode visibleNodes].count; }
2989 -(void)treeView:(DWTree *)treeView addTreeItem:(DWTreeItem *)treeItem {} 3004 -(void)treeView:(DWTree *)treeView addTreeItem:(DWTreeItem *)treeItem {}
2990 -(void)treeView:(DWTree *)treeView didSelectForTreeItem:(DWTreeItem *)treeItem {} 3005 -(void)treeView:(DWTree *)treeView didSelectForTreeItem:(DWTreeItem *)treeItem
3006 {
3007 if(treeItem)
3008 _dw_event_handler(treeView, (void *)treeItem, _DW_EVENT_ITEM_SELECT);
3009 }
3010 -(UIContextMenuConfiguration *)treeView:(DWTree *)treeView contextMenuConfigurationForTreeItem:(DWTreeItem *)treeItem point:(CGPoint)point
3011 {
3012 UIContextMenuConfiguration *config = nil;
3013 DWWindow *window = (DWWindow *)[self window];
3014 const char *title = [[treeItem title] UTF8String];
3015 NSPointerArray *params = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsOpaqueMemory];
3016
3017 [params addPointer:strdup(title ? title : "")];
3018 [params addPointer:[treeItem data]];
3019 [params addPointer:DW_INT_TO_POINTER((int)point.x)];
3020 [params addPointer:DW_INT_TO_POINTER((int)point.y)];
3021
3022 _dw_event_point = point;
3023 _dw_event_handler(self, params, _DW_EVENT_ITEM_CONTEXT);
3024 free([params pointerAtIndex:0]);
3025
3026 if(window && [window popupMenu])
3027 {
3028 __block UIMenu *popupmenu = [[[window popupMenu] menu] retain];
3029 config = [UIContextMenuConfiguration configurationWithIdentifier:nil
3030 previewProvider:nil
3031 actionProvider:^(NSArray* suggestedAction){return popupmenu;}];
3032 [window setPopupMenu:nil];
3033 }
3034 return config;
3035 }
2991 -(void)treeView:(DWTree *)treeView moveTreeItem:(DWTreeItem *)treeItem to:(DWTreeItem *)to {} 3036 -(void)treeView:(DWTree *)treeView moveTreeItem:(DWTreeItem *)treeItem to:(DWTreeItem *)to {}
2992 -(BOOL)treeView:(DWTree *)treeView queryExpandableInTreeItem:(DWTreeItem *)treeItem { return YES; } 3037 -(BOOL)treeView:(DWTree *)treeView queryExpandableInTreeItem:(DWTreeItem *)treeItem { return YES; }
2993 -(void)treeView:(DWTree *)treeView removeTreeItem:(DWTreeItem *)treeItem {} 3038 -(void)treeView:(DWTree *)treeView removeTreeItem:(DWTreeItem *)treeItem {}
2994 -(NSInteger)treeView:(DWTree *)treeView rowForTreeItem:(DWTreeItem *)treeItem { return [[_rootNode visibleNodes] indexOfObject:treeItem]; } 3039 -(NSInteger)treeView:(DWTree *)treeView rowForTreeItem:(DWTreeItem *)treeItem { return [[_rootNode visibleNodes] indexOfObject:treeItem]; }
2995 -(void)treeView:(DWTree *)treeView treeItem:(DWTreeItem *)treeItem expanded:(BOOL)expanded {} 3040 -(void)treeView:(DWTree *)treeView treeItem:(DWTreeItem *)treeItem expanded:(BOOL)expanded
3041 {
3042 if(treeItem)
3043 _dw_event_handler(treeView, (void *)treeItem, _DW_EVENT_TREE_EXPAND);
3044 }
2996 - (DWTreeItem *)treeView:(DWTree *)treeView treeItemForRow:(NSInteger)row { return [[_rootNode visibleNodes] objectAtIndex:row]; } 3045 - (DWTreeItem *)treeView:(DWTree *)treeView treeItemForRow:(NSInteger)row { return [[_rootNode visibleNodes] objectAtIndex:row]; }
2997 #pragma mark - UITableViewDataSource 3046 #pragma mark - UITableViewDataSource
2998 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } 3047 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
2999 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 3048 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
3000 { 3049 {
3048 { 3097 {
3049 if([fromIndexPath isEqual:toIndexPath]) 3098 if([fromIndexPath isEqual:toIndexPath])
3050 return; 3099 return;
3051 DWTreeItem *srcNode = [self treeItemForIndexPath:fromIndexPath]; 3100 DWTreeItem *srcNode = [self treeItemForIndexPath:fromIndexPath];
3052 DWTreeItem *targetNode = [self treeItemForIndexPath:toIndexPath]; 3101 DWTreeItem *targetNode = [self treeItemForIndexPath:toIndexPath];
3053 [srcNode moveToDestination:targetNode]; 3102
3054 3103 if(srcNode && targetNode)
3055 if([_treeViewDelegate respondsToSelector:@selector(treeView:moveTreeItem:to:)]) 3104 {
3056 [_treeViewDelegate treeView:self moveTreeItem:srcNode to:targetNode]; 3105 [srcNode moveToDestination:targetNode];
3057 3106
3058 [self reloadData]; 3107 if([_treeViewDelegate respondsToSelector:@selector(treeView:moveTreeItem:to:)])
3059 [self resetSelection:NO]; 3108 [_treeViewDelegate treeView:self moveTreeItem:srcNode to:targetNode];
3109
3110 [self reloadData];
3111 [self resetSelection:NO];
3112 }
3060 } 3113 }
3061 -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 3114 -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
3062 { 3115 {
3063 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath]; 3116 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath];
3064 if([_treeViewDelegate respondsToSelector:@selector(treeView:canMoveTreeItem:)]) 3117 if(treeItem && [_treeViewDelegate respondsToSelector:@selector(treeView:canMoveTreeItem:)])
3065 return [_treeViewDelegate treeView:self canMoveTreeItem:treeItem]; 3118 return [_treeViewDelegate treeView:self canMoveTreeItem:treeItem];
3066 else 3119 return NO;
3067 return (treeItem.isRoot == NO);
3068 } 3120 }
3069 #pragma mark - DWTableViewDelegate 3121 #pragma mark - DWTableViewDelegate
3070 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 3122 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
3071 { 3123 {
3072 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath]; 3124 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath];
3073 if([_treeViewDelegate respondsToSelector:@selector(treeView:didSelectForTreeItem:)]) 3125 if(treeItem && [_treeViewDelegate respondsToSelector:@selector(treeView:didSelectForTreeItem:)])
3074 [_treeViewDelegate treeView:self didSelectForTreeItem:treeItem]; 3126 [_treeViewDelegate treeView:self didSelectForTreeItem:treeItem];
3075 _selectedNode = treeItem; 3127 _selectedNode = treeItem;
3128 }
3129 -(UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point
3130 {
3131 UIContextMenuConfiguration *config = nil;
3132 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath];
3133 if(treeItem && [_treeViewDelegate respondsToSelector:@selector(treeView:contextMenuConfigurationForTreeItem:point:)])
3134 config = [_treeViewDelegate treeView:self contextMenuConfigurationForTreeItem:treeItem point:point];
3135
3136 return config;
3076 } 3137 }
3077 -(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 3138 -(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
3078 { 3139 {
3079 DWTreeItem *srcNode = [self treeItemForIndexPath:sourceIndexPath]; 3140 DWTreeItem *srcNode = [self treeItemForIndexPath:sourceIndexPath];
3080 DWTreeItem *targetNode = [self treeItemForIndexPath:proposedDestinationIndexPath]; 3141 DWTreeItem *targetNode = [self treeItemForIndexPath:proposedDestinationIndexPath];