# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1649528372 0 # Node ID de144e0fbdf1bb5619b1241ab52ff023ba12c33a # Parent 9b9bc2c2bbade7124f6e39605dfe79f024b8970c iOS: Implement all the tree functions. Fix incorrect display due to incorrect indentation due to the addition of an unrendered root node. Fix incorrect display due to an additional UIImageView. Use the systme image view instead of one we added ourself. Just need to implment callbacks and figure out why the expand button isn't working. diff -r 9b9bc2c2bbad -r de144e0fbdf1 ios/dw.m --- a/ios/dw.m Fri Apr 08 16:33:38 2022 +0000 +++ b/ios/dw.m Sat Apr 09 18:19:32 2022 +0000 @@ -2784,12 +2784,13 @@ @property(nonatomic, strong) UILabel *titleLabel; @property(nonatomic) NSUInteger level; @property(nonatomic) BOOL expanded; -@property(nonatomic) BOOL isFolder; +@property(nonatomic) BOOL children; @property(nonatomic, assign) id delegate; -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier level:(NSUInteger)level - expanded:(BOOL)expanded; + expanded:(BOOL)expanded + children:(BOOL)children; @end CGRect DWRectInflate(CGRect rect, CGFloat dx, CGFloat dy) @@ -2797,25 +2798,30 @@ return CGRectMake(rect.origin.x-dx, rect.origin.y-dy, rect.size.width+2*dx, rect.size.height+2*dy); } -static CGFloat IMG_HEIGHT_WIDTH = 20; -static CGFloat XOFFSET = 3; +static CGFloat _DW_TREE_IMG_HEIGHT_WIDTH = 20; +static CGFloat _DW_TREE_XOFFSET = 3; @implementation DWTreeViewCell { DWButton *_arrowImageButton; - UIImageView *_itemImage; } -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier level:(NSUInteger)level expanded:(BOOL)expanded -{ + children:(BOOL)children +{ + // We should never display the root node + if(level < 1) + return nil; + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if(self) { - _level = level; + _level = level - 1; _expanded = expanded; + _children = children; UIView *content = self.contentView; @@ -2826,11 +2832,9 @@ [content addSubview:titleLabel]; _titleLabel = titleLabel; - UIImageView *itemImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, IMG_HEIGHT_WIDTH, IMG_HEIGHT_WIDTH)]; - [content addSubview:itemImage]; - _itemImage = itemImage; - - DWButton *arrowImageButton = [[DWButton alloc] initWithFrame:CGRectMake(0, 0, IMG_HEIGHT_WIDTH, IMG_HEIGHT_WIDTH)]; + DWButton *arrowImageButton = [[DWButton alloc] initWithFrame:CGRectMake(0, 0, + _DW_TREE_IMG_HEIGHT_WIDTH, + _DW_TREE_IMG_HEIGHT_WIDTH)]; [arrowImageButton setType:_DW_BUTTON_TYPE_TREE]; [arrowImageButton setDidCheckedChanged:^(BOOL checked) { _expanded = checked; @@ -2838,6 +2842,9 @@ [_delegate treeViewCell:self expanded:checked]; }]; [arrowImageButton setCheckState:_expanded]; + [arrowImageButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter]; + if(!children) + [arrowImageButton setHidden:YES]; [content addSubview:arrowImageButton]; _arrowImageButton = arrowImageButton; } @@ -2852,10 +2859,10 @@ CGSize size = self.contentView.bounds.size; CGFloat stepSize = size.height; CGRect rc = CGRectMake(_level * stepSize, 0, stepSize, stepSize); - _arrowImageButton.frame = DWRectInflate(rc, -XOFFSET, -XOFFSET); + _arrowImageButton.frame = DWRectInflate(rc, -_DW_TREE_XOFFSET, -_DW_TREE_XOFFSET); rc = CGRectMake((_level + 1) * stepSize, 0, stepSize, stepSize); - _itemImage.frame = DWRectInflate(rc, -XOFFSET, -XOFFSET); + self.imageView.frame = DWRectInflate(rc, -_DW_TREE_XOFFSET, -_DW_TREE_XOFFSET); _titleLabel.frame = CGRectMake((_level + 2) * stepSize, 0, size.width - (_level + 3) * stepSize, stepSize); } @end @@ -2914,21 +2921,24 @@ { DWTreeItem *targetNode = nil; - NSArray *cells = [self visibleCells]; - - // Target the selected tree node first if any - for(DWTreeViewCell *cell in cells) - { - DWTreeItem *iter = [self treeItemForTreeViewCell:cell]; - if(iter == _selectedNode) - { - targetNode = iter; - break; - } - } - // Otherwise target first visible node if any - if(targetNode == nil && [cells count]) - targetNode = [self treeItemForTreeViewCell:cells[0]]; + if([self window]) + { + NSArray *cells = [self visibleCells]; + + // Target the selected tree node first if any + for(DWTreeViewCell *cell in cells) + { + DWTreeItem *iter = [self treeItemForTreeViewCell:cell]; + if(iter == _selectedNode) + { + targetNode = iter; + break; + } + } + // Otherwise target first visible node if any + if(targetNode == nil && [cells count]) + targetNode = [self treeItemForTreeViewCell:cells[0]]; + } // Finally put it on the root level if(targetNode == nil) targetNode = _rootNode; @@ -2951,6 +2961,12 @@ [self reloadData]; [self resetSelection:NO]; } +-(void)clear +{ + [[_rootNode children] removeAllObjects]; + [self reloadData]; + [self resetSelection:NO]; +} -(void)resetSelection:(BOOL)delay { NSInteger row = NSNotFound; @@ -2995,7 +3011,8 @@ DWTreeViewCell *cell = [[DWTreeViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier level:[treeItem levelDepth] - expanded:treeItem.expanded]; + expanded:treeItem.expanded + children:[treeItem hasChildren]]; cell.titleLabel.text = treeItem.title; cell.imageView.image = treeItem.icon; cell.titleLabel.font = _font; @@ -6657,10 +6674,19 @@ * title: The text title of the entry. * icon: Handle to coresponding icon. */ -void API dw_tree_item_change(HWND handle, HTREEITEM item, const char *title, HICN icon) -{ - /* TODO: Implement tree for iOS if possible */ - +DW_FUNCTION_DEFINITION(dw_tree_item_change, void, HWND handle, HTREEITEM item, const char *title, HICN icon) +DW_FUNCTION_ADD_PARAM4(handle, item, title, icon) +DW_FUNCTION_NO_RETURN(dw_tree_item_change) +DW_FUNCTION_RESTORE_PARAM4(DW_UNUSED(handle), HWND, item, HTREEITEM, title, const char *, icon, HICN) +{ + DW_FUNCTION_INIT; + DWTreeItem *treeitem = item; + if(handle && treeitem) + { + [treeitem setIcon:icon]; + [treeitem setTitle:[NSString stringWithUTF8String:(title ? title : "")]]; + } + DW_FUNCTION_RETURN_NOTHING; } /* @@ -6670,10 +6696,16 @@ * item: Handle of the item to be modified. * itemdata: User defined data to be associated with item. */ -void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata) -{ - /* TODO: Implement tree for iOS if possible */ - +DW_FUNCTION_DEFINITION(dw_tree_item_set_data, void, HWND handle, HTREEITEM item, void *itemdata) +DW_FUNCTION_ADD_PARAM3(handle, item, itemdata) +DW_FUNCTION_NO_RETURN(dw_tree_item_set_data) +DW_FUNCTION_RESTORE_PARAM3(DW_UNUSED(handle), HWND, item, HTREEITEM, itemdata, void *) +{ + DW_FUNCTION_INIT; + DWTreeItem *treeitem = item; + if(handle && treeitem) + [treeitem setData:itemdata]; + DW_FUNCTION_RETURN_NOTHING; } /* @@ -6684,10 +6716,17 @@ * Returns: * A pointer to tree item data or NULL on failure. */ -void * API dw_tree_item_get_data(HWND handle, HTREEITEM item) -{ - /* TODO: Implement tree for iOS if possible */ - return NULL; +DW_FUNCTION_DEFINITION(dw_tree_item_get_data, void *, HWND handle, HTREEITEM item) +DW_FUNCTION_ADD_PARAM2(handle, item) +DW_FUNCTION_RETURN(dw_tree_item_get_data, void *) +DW_FUNCTION_RESTORE_PARAM2(DW_UNUSED(handle), HWND, item, HTREEITEM) +{ + DW_FUNCTION_INIT; + void *result = NULL; + DWTreeItem *treeitem = item; + if(handle && treeitem) + result = [treeitem data]; + DW_FUNCTION_RETURN_THIS(result); } /* @@ -6706,9 +6745,15 @@ * Parameters: * handle: Handle to the window (widget) to be cleared. */ -void API dw_tree_clear(HWND handle) -{ - /* TODO: Implement tree for iOS if possible */ +DW_FUNCTION_DEFINITION(dw_tree_clear, void, HWND handle) +DW_FUNCTION_ADD_PARAM1(handle) +DW_FUNCTION_NO_RETURN(dw_tree_clear) +DW_FUNCTION_RESTORE_PARAM1(handle, HWND) +{ + DW_FUNCTION_INIT; + DWTree *tree = handle; + [tree clear]; + DW_FUNCTION_RETURN_NOTHING; } /* @@ -6717,9 +6762,21 @@ * handle: Handle to the tree window (widget). * item: Handle to node to be expanded. */ -void API dw_tree_item_expand(HWND handle, HTREEITEM item) -{ - /* TODO: Implement tree for iOS if possible */ +DW_FUNCTION_DEFINITION(dw_tree_item_expand, void, HWND handle, HTREEITEM item) +DW_FUNCTION_ADD_PARAM2(handle, item) +DW_FUNCTION_NO_RETURN(dw_tree_item_expand) +DW_FUNCTION_RESTORE_PARAM2(handle, HWND, item, HTREEITEM) +{ + DW_FUNCTION_INIT; + DWTree *tree = handle; + DWTreeItem *treeitem = item; + if(![treeitem expanded]) + { + [treeitem setExpanded:YES]; + [tree reloadData]; + [tree resetSelection:NO]; + } + DW_FUNCTION_RETURN_NOTHING; } /* @@ -6728,9 +6785,21 @@ * handle: Handle to the tree window (widget). * item: Handle to node to be collapsed. */ -void API dw_tree_item_collapse(HWND handle, HTREEITEM item) -{ - /* TODO: Implement tree for iOS if possible */ +DW_FUNCTION_DEFINITION(dw_tree_item_collapse, void, HWND handle, HTREEITEM item) +DW_FUNCTION_ADD_PARAM2(handle, item) +DW_FUNCTION_NO_RETURN(dw_tree_item_collapse) +DW_FUNCTION_RESTORE_PARAM2(handle, HWND, item, HTREEITEM) +{ + DW_FUNCTION_INIT; + DWTree *tree = handle; + DWTreeItem *treeitem = item; + if([treeitem expanded]) + { + [treeitem setExpanded:NO]; + [tree reloadData]; + [tree resetSelection:NO]; + } + DW_FUNCTION_RETURN_NOTHING; } /* @@ -6739,10 +6808,20 @@ * handle: Handle to the window (widget) to be cleared. * item: Handle to node to be deleted. */ -void API dw_tree_item_delete(HWND handle, HTREEITEM item) -{ - /* TODO: Implement tree for iOS if possible */ -} +DW_FUNCTION_DEFINITION(dw_tree_item_delete, void, HWND handle, HTREEITEM item) +DW_FUNCTION_ADD_PARAM2(handle, item) +DW_FUNCTION_NO_RETURN(dw_tree_item_delete) +DW_FUNCTION_RESTORE_PARAM2(handle, HWND, item, HTREEITEM) +{ + DW_FUNCTION_INIT; + DWTree *tree = handle; + DWTreeItem *treeitem = item; + [treeitem removeFromParent]; + [tree reloadData]; + [tree resetSelection:NO]; + DW_FUNCTION_RETURN_NOTHING; +} + /* * Create a container object to be packed.