comparison ios/dw.m @ 2767:de144e0fbdf1

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sat, 09 Apr 2022 18:19:32 +0000
parents 9b9bc2c2bbad
children 06f45ee90e0f
comparison
equal deleted inserted replaced
2766:9b9bc2c2bbad 2767:de144e0fbdf1
2782 2782
2783 @interface DWTreeViewCell : UITableViewCell 2783 @interface DWTreeViewCell : UITableViewCell
2784 @property(nonatomic, strong) UILabel *titleLabel; 2784 @property(nonatomic, strong) UILabel *titleLabel;
2785 @property(nonatomic) NSUInteger level; 2785 @property(nonatomic) NSUInteger level;
2786 @property(nonatomic) BOOL expanded; 2786 @property(nonatomic) BOOL expanded;
2787 @property(nonatomic) BOOL isFolder; 2787 @property(nonatomic) BOOL children;
2788 @property(nonatomic, assign) id <DWTreeViewCellDelegate> delegate; 2788 @property(nonatomic, assign) id <DWTreeViewCellDelegate> delegate;
2789 -(instancetype)initWithStyle:(UITableViewCellStyle)style 2789 -(instancetype)initWithStyle:(UITableViewCellStyle)style
2790 reuseIdentifier:(NSString *)reuseIdentifier 2790 reuseIdentifier:(NSString *)reuseIdentifier
2791 level:(NSUInteger)level 2791 level:(NSUInteger)level
2792 expanded:(BOOL)expanded; 2792 expanded:(BOOL)expanded
2793 children:(BOOL)children;
2793 @end 2794 @end
2794 2795
2795 CGRect DWRectInflate(CGRect rect, CGFloat dx, CGFloat dy) 2796 CGRect DWRectInflate(CGRect rect, CGFloat dx, CGFloat dy)
2796 { 2797 {
2797 return CGRectMake(rect.origin.x-dx, rect.origin.y-dy, rect.size.width+2*dx, rect.size.height+2*dy); 2798 return CGRectMake(rect.origin.x-dx, rect.origin.y-dy, rect.size.width+2*dx, rect.size.height+2*dy);
2798 } 2799 }
2799 2800
2800 static CGFloat IMG_HEIGHT_WIDTH = 20; 2801 static CGFloat _DW_TREE_IMG_HEIGHT_WIDTH = 20;
2801 static CGFloat XOFFSET = 3; 2802 static CGFloat _DW_TREE_XOFFSET = 3;
2802 2803
2803 @implementation DWTreeViewCell 2804 @implementation DWTreeViewCell
2804 { 2805 {
2805 DWButton *_arrowImageButton; 2806 DWButton *_arrowImageButton;
2806 UIImageView *_itemImage;
2807 } 2807 }
2808 -(id)initWithStyle:(UITableViewCellStyle)style 2808 -(id)initWithStyle:(UITableViewCellStyle)style
2809 reuseIdentifier:(NSString *)reuseIdentifier 2809 reuseIdentifier:(NSString *)reuseIdentifier
2810 level:(NSUInteger)level 2810 level:(NSUInteger)level
2811 expanded:(BOOL)expanded 2811 expanded:(BOOL)expanded
2812 { 2812 children:(BOOL)children
2813 {
2814 // We should never display the root node
2815 if(level < 1)
2816 return nil;
2817
2813 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 2818 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
2814 2819
2815 if(self) 2820 if(self)
2816 { 2821 {
2817 _level = level; 2822 _level = level - 1;
2818 _expanded = expanded; 2823 _expanded = expanded;
2824 _children = children;
2819 2825
2820 UIView *content = self.contentView; 2826 UIView *content = self.contentView;
2821 2827
2822 UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 2828 UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
2823 titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 2829 titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
2824 titleLabel.numberOfLines = 0; 2830 titleLabel.numberOfLines = 0;
2825 titleLabel.textAlignment = NSTextAlignmentLeft; 2831 titleLabel.textAlignment = NSTextAlignmentLeft;
2826 [content addSubview:titleLabel]; 2832 [content addSubview:titleLabel];
2827 _titleLabel = titleLabel; 2833 _titleLabel = titleLabel;
2828 2834
2829 UIImageView *itemImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, IMG_HEIGHT_WIDTH, IMG_HEIGHT_WIDTH)]; 2835 DWButton *arrowImageButton = [[DWButton alloc] initWithFrame:CGRectMake(0, 0,
2830 [content addSubview:itemImage]; 2836 _DW_TREE_IMG_HEIGHT_WIDTH,
2831 _itemImage = itemImage; 2837 _DW_TREE_IMG_HEIGHT_WIDTH)];
2832
2833 DWButton *arrowImageButton = [[DWButton alloc] initWithFrame:CGRectMake(0, 0, IMG_HEIGHT_WIDTH, IMG_HEIGHT_WIDTH)];
2834 [arrowImageButton setType:_DW_BUTTON_TYPE_TREE]; 2838 [arrowImageButton setType:_DW_BUTTON_TYPE_TREE];
2835 [arrowImageButton setDidCheckedChanged:^(BOOL checked) { 2839 [arrowImageButton setDidCheckedChanged:^(BOOL checked) {
2836 _expanded = checked; 2840 _expanded = checked;
2837 if([_delegate respondsToSelector:@selector(treeViewCell:expanded:)]) 2841 if([_delegate respondsToSelector:@selector(treeViewCell:expanded:)])
2838 [_delegate treeViewCell:self expanded:checked]; 2842 [_delegate treeViewCell:self expanded:checked];
2839 }]; 2843 }];
2840 [arrowImageButton setCheckState:_expanded]; 2844 [arrowImageButton setCheckState:_expanded];
2845 [arrowImageButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
2846 if(!children)
2847 [arrowImageButton setHidden:YES];
2841 [content addSubview:arrowImageButton]; 2848 [content addSubview:arrowImageButton];
2842 _arrowImageButton = arrowImageButton; 2849 _arrowImageButton = arrowImageButton;
2843 } 2850 }
2844 return self; 2851 return self;
2845 } 2852 }
2850 [super layoutSubviews]; 2857 [super layoutSubviews];
2851 2858
2852 CGSize size = self.contentView.bounds.size; 2859 CGSize size = self.contentView.bounds.size;
2853 CGFloat stepSize = size.height; 2860 CGFloat stepSize = size.height;
2854 CGRect rc = CGRectMake(_level * stepSize, 0, stepSize, stepSize); 2861 CGRect rc = CGRectMake(_level * stepSize, 0, stepSize, stepSize);
2855 _arrowImageButton.frame = DWRectInflate(rc, -XOFFSET, -XOFFSET); 2862 _arrowImageButton.frame = DWRectInflate(rc, -_DW_TREE_XOFFSET, -_DW_TREE_XOFFSET);
2856 2863
2857 rc = CGRectMake((_level + 1) * stepSize, 0, stepSize, stepSize); 2864 rc = CGRectMake((_level + 1) * stepSize, 0, stepSize, stepSize);
2858 _itemImage.frame = DWRectInflate(rc, -XOFFSET, -XOFFSET); 2865 self.imageView.frame = DWRectInflate(rc, -_DW_TREE_XOFFSET, -_DW_TREE_XOFFSET);
2859 _titleLabel.frame = CGRectMake((_level + 2) * stepSize, 0, size.width - (_level + 3) * stepSize, stepSize); 2866 _titleLabel.frame = CGRectMake((_level + 2) * stepSize, 0, size.width - (_level + 3) * stepSize, stepSize);
2860 } 2867 }
2861 @end 2868 @end
2862 2869
2863 @class DWTree; 2870 @class DWTree;
2912 -(void)dealloc { [_rootNode release]; [super dealloc]; } 2919 -(void)dealloc { [_rootNode release]; [super dealloc]; }
2913 -(void)insertTreeItem:(DWTreeItem *)treeItem 2920 -(void)insertTreeItem:(DWTreeItem *)treeItem
2914 { 2921 {
2915 DWTreeItem *targetNode = nil; 2922 DWTreeItem *targetNode = nil;
2916 2923
2917 NSArray<DWTreeViewCell *> *cells = [self visibleCells]; 2924 if([self window])
2918 2925 {
2919 // Target the selected tree node first if any 2926 NSArray<DWTreeViewCell *> *cells = [self visibleCells];
2920 for(DWTreeViewCell *cell in cells) 2927
2921 { 2928 // Target the selected tree node first if any
2922 DWTreeItem *iter = [self treeItemForTreeViewCell:cell]; 2929 for(DWTreeViewCell *cell in cells)
2923 if(iter == _selectedNode) 2930 {
2924 { 2931 DWTreeItem *iter = [self treeItemForTreeViewCell:cell];
2925 targetNode = iter; 2932 if(iter == _selectedNode)
2926 break; 2933 {
2927 } 2934 targetNode = iter;
2928 } 2935 break;
2929 // Otherwise target first visible node if any 2936 }
2930 if(targetNode == nil && [cells count]) 2937 }
2931 targetNode = [self treeItemForTreeViewCell:cells[0]]; 2938 // Otherwise target first visible node if any
2939 if(targetNode == nil && [cells count])
2940 targetNode = [self treeItemForTreeViewCell:cells[0]];
2941 }
2932 // Finally put it on the root level 2942 // Finally put it on the root level
2933 if(targetNode == nil) 2943 if(targetNode == nil)
2934 targetNode = _rootNode; 2944 targetNode = _rootNode;
2935 // If target is still nil something went horrible wrong 2945 // If target is still nil something went horrible wrong
2936 NSAssert(targetNode, @"targetNode == nil, something went wrong!"); 2946 NSAssert(targetNode, @"targetNode == nil, something went wrong!");
2946 [self resetSelection:NO]; 2956 [self resetSelection:NO];
2947 } 2957 }
2948 -(void)setFont:(UIFont *)font 2958 -(void)setFont:(UIFont *)font
2949 { 2959 {
2950 _font = font; 2960 _font = font;
2961 [self reloadData];
2962 [self resetSelection:NO];
2963 }
2964 -(void)clear
2965 {
2966 [[_rootNode children] removeAllObjects];
2951 [self reloadData]; 2967 [self reloadData];
2952 [self resetSelection:NO]; 2968 [self resetSelection:NO];
2953 } 2969 }
2954 -(void)resetSelection:(BOOL)delay 2970 -(void)resetSelection:(BOOL)delay
2955 { 2971 {
2993 3009
2994 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath]; 3010 DWTreeItem *treeItem = [self treeItemForIndexPath:indexPath];
2995 DWTreeViewCell *cell = [[DWTreeViewCell alloc] initWithStyle:UITableViewCellStyleDefault 3011 DWTreeViewCell *cell = [[DWTreeViewCell alloc] initWithStyle:UITableViewCellStyleDefault
2996 reuseIdentifier:CellIdentifier 3012 reuseIdentifier:CellIdentifier
2997 level:[treeItem levelDepth] 3013 level:[treeItem levelDepth]
2998 expanded:treeItem.expanded]; 3014 expanded:treeItem.expanded
3015 children:[treeItem hasChildren]];
2999 cell.titleLabel.text = treeItem.title; 3016 cell.titleLabel.text = treeItem.title;
3000 cell.imageView.image = treeItem.icon; 3017 cell.imageView.image = treeItem.icon;
3001 cell.titleLabel.font = _font; 3018 cell.titleLabel.font = _font;
3002 //cell.selectionStyle = UITableViewCellSelectionStyleNone; 3019 //cell.selectionStyle = UITableViewCellSelectionStyleNone;
3003 cell.delegate = self; 3020 cell.delegate = self;
6655 * handle: Handle to the tree containing the item. 6672 * handle: Handle to the tree containing the item.
6656 * item: Handle of the item to be modified. 6673 * item: Handle of the item to be modified.
6657 * title: The text title of the entry. 6674 * title: The text title of the entry.
6658 * icon: Handle to coresponding icon. 6675 * icon: Handle to coresponding icon.
6659 */ 6676 */
6660 void API dw_tree_item_change(HWND handle, HTREEITEM item, const char *title, HICN icon) 6677 DW_FUNCTION_DEFINITION(dw_tree_item_change, void, HWND handle, HTREEITEM item, const char *title, HICN icon)
6661 { 6678 DW_FUNCTION_ADD_PARAM4(handle, item, title, icon)
6662 /* TODO: Implement tree for iOS if possible */ 6679 DW_FUNCTION_NO_RETURN(dw_tree_item_change)
6663 6680 DW_FUNCTION_RESTORE_PARAM4(DW_UNUSED(handle), HWND, item, HTREEITEM, title, const char *, icon, HICN)
6681 {
6682 DW_FUNCTION_INIT;
6683 DWTreeItem *treeitem = item;
6684 if(handle && treeitem)
6685 {
6686 [treeitem setIcon:icon];
6687 [treeitem setTitle:[NSString stringWithUTF8String:(title ? title : "")]];
6688 }
6689 DW_FUNCTION_RETURN_NOTHING;
6664 } 6690 }
6665 6691
6666 /* 6692 /*
6667 * Sets the item data of a tree item. 6693 * Sets the item data of a tree item.
6668 * Parameters: 6694 * Parameters:
6669 * handle: Handle to the tree containing the item. 6695 * handle: Handle to the tree containing the item.
6670 * item: Handle of the item to be modified. 6696 * item: Handle of the item to be modified.
6671 * itemdata: User defined data to be associated with item. 6697 * itemdata: User defined data to be associated with item.
6672 */ 6698 */
6673 void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata) 6699 DW_FUNCTION_DEFINITION(dw_tree_item_set_data, void, HWND handle, HTREEITEM item, void *itemdata)
6674 { 6700 DW_FUNCTION_ADD_PARAM3(handle, item, itemdata)
6675 /* TODO: Implement tree for iOS if possible */ 6701 DW_FUNCTION_NO_RETURN(dw_tree_item_set_data)
6676 6702 DW_FUNCTION_RESTORE_PARAM3(DW_UNUSED(handle), HWND, item, HTREEITEM, itemdata, void *)
6703 {
6704 DW_FUNCTION_INIT;
6705 DWTreeItem *treeitem = item;
6706 if(handle && treeitem)
6707 [treeitem setData:itemdata];
6708 DW_FUNCTION_RETURN_NOTHING;
6677 } 6709 }
6678 6710
6679 /* 6711 /*
6680 * Gets the item data of a tree item. 6712 * Gets the item data of a tree item.
6681 * Parameters: 6713 * Parameters:
6682 * handle: Handle to the tree containing the item. 6714 * handle: Handle to the tree containing the item.
6683 * item: Handle of the item to be modified. 6715 * item: Handle of the item to be modified.
6684 * Returns: 6716 * Returns:
6685 * A pointer to tree item data or NULL on failure. 6717 * A pointer to tree item data or NULL on failure.
6686 */ 6718 */
6687 void * API dw_tree_item_get_data(HWND handle, HTREEITEM item) 6719 DW_FUNCTION_DEFINITION(dw_tree_item_get_data, void *, HWND handle, HTREEITEM item)
6688 { 6720 DW_FUNCTION_ADD_PARAM2(handle, item)
6689 /* TODO: Implement tree for iOS if possible */ 6721 DW_FUNCTION_RETURN(dw_tree_item_get_data, void *)
6690 return NULL; 6722 DW_FUNCTION_RESTORE_PARAM2(DW_UNUSED(handle), HWND, item, HTREEITEM)
6723 {
6724 DW_FUNCTION_INIT;
6725 void *result = NULL;
6726 DWTreeItem *treeitem = item;
6727 if(handle && treeitem)
6728 result = [treeitem data];
6729 DW_FUNCTION_RETURN_THIS(result);
6691 } 6730 }
6692 6731
6693 /* 6732 /*
6694 * Sets this item as the active selection. 6733 * Sets this item as the active selection.
6695 * Parameters: 6734 * Parameters:
6704 /* 6743 /*
6705 * Removes all nodes from a tree. 6744 * Removes all nodes from a tree.
6706 * Parameters: 6745 * Parameters:
6707 * handle: Handle to the window (widget) to be cleared. 6746 * handle: Handle to the window (widget) to be cleared.
6708 */ 6747 */
6709 void API dw_tree_clear(HWND handle) 6748 DW_FUNCTION_DEFINITION(dw_tree_clear, void, HWND handle)
6710 { 6749 DW_FUNCTION_ADD_PARAM1(handle)
6711 /* TODO: Implement tree for iOS if possible */ 6750 DW_FUNCTION_NO_RETURN(dw_tree_clear)
6751 DW_FUNCTION_RESTORE_PARAM1(handle, HWND)
6752 {
6753 DW_FUNCTION_INIT;
6754 DWTree *tree = handle;
6755 [tree clear];
6756 DW_FUNCTION_RETURN_NOTHING;
6712 } 6757 }
6713 6758
6714 /* 6759 /*
6715 * Expands a node on a tree. 6760 * Expands a node on a tree.
6716 * Parameters: 6761 * Parameters:
6717 * handle: Handle to the tree window (widget). 6762 * handle: Handle to the tree window (widget).
6718 * item: Handle to node to be expanded. 6763 * item: Handle to node to be expanded.
6719 */ 6764 */
6720 void API dw_tree_item_expand(HWND handle, HTREEITEM item) 6765 DW_FUNCTION_DEFINITION(dw_tree_item_expand, void, HWND handle, HTREEITEM item)
6721 { 6766 DW_FUNCTION_ADD_PARAM2(handle, item)
6722 /* TODO: Implement tree for iOS if possible */ 6767 DW_FUNCTION_NO_RETURN(dw_tree_item_expand)
6768 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, item, HTREEITEM)
6769 {
6770 DW_FUNCTION_INIT;
6771 DWTree *tree = handle;
6772 DWTreeItem *treeitem = item;
6773 if(![treeitem expanded])
6774 {
6775 [treeitem setExpanded:YES];
6776 [tree reloadData];
6777 [tree resetSelection:NO];
6778 }
6779 DW_FUNCTION_RETURN_NOTHING;
6723 } 6780 }
6724 6781
6725 /* 6782 /*
6726 * Collapses a node on a tree. 6783 * Collapses a node on a tree.
6727 * Parameters: 6784 * Parameters:
6728 * handle: Handle to the tree window (widget). 6785 * handle: Handle to the tree window (widget).
6729 * item: Handle to node to be collapsed. 6786 * item: Handle to node to be collapsed.
6730 */ 6787 */
6731 void API dw_tree_item_collapse(HWND handle, HTREEITEM item) 6788 DW_FUNCTION_DEFINITION(dw_tree_item_collapse, void, HWND handle, HTREEITEM item)
6732 { 6789 DW_FUNCTION_ADD_PARAM2(handle, item)
6733 /* TODO: Implement tree for iOS if possible */ 6790 DW_FUNCTION_NO_RETURN(dw_tree_item_collapse)
6791 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, item, HTREEITEM)
6792 {
6793 DW_FUNCTION_INIT;
6794 DWTree *tree = handle;
6795 DWTreeItem *treeitem = item;
6796 if([treeitem expanded])
6797 {
6798 [treeitem setExpanded:NO];
6799 [tree reloadData];
6800 [tree resetSelection:NO];
6801 }
6802 DW_FUNCTION_RETURN_NOTHING;
6734 } 6803 }
6735 6804
6736 /* 6805 /*
6737 * Removes a node from a tree. 6806 * Removes a node from a tree.
6738 * Parameters: 6807 * Parameters:
6739 * handle: Handle to the window (widget) to be cleared. 6808 * handle: Handle to the window (widget) to be cleared.
6740 * item: Handle to node to be deleted. 6809 * item: Handle to node to be deleted.
6741 */ 6810 */
6742 void API dw_tree_item_delete(HWND handle, HTREEITEM item) 6811 DW_FUNCTION_DEFINITION(dw_tree_item_delete, void, HWND handle, HTREEITEM item)
6743 { 6812 DW_FUNCTION_ADD_PARAM2(handle, item)
6744 /* TODO: Implement tree for iOS if possible */ 6813 DW_FUNCTION_NO_RETURN(dw_tree_item_delete)
6745 } 6814 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, item, HTREEITEM)
6815 {
6816 DW_FUNCTION_INIT;
6817 DWTree *tree = handle;
6818 DWTreeItem *treeitem = item;
6819 [treeitem removeFromParent];
6820 [tree reloadData];
6821 [tree resetSelection:NO];
6822 DW_FUNCTION_RETURN_NOTHING;
6823 }
6824
6746 6825
6747 /* 6826 /*
6748 * Create a container object to be packed. 6827 * Create a container object to be packed.
6749 * Parameters: 6828 * Parameters:
6750 * id: An ID to be used for getting the resource from the 6829 * id: An ID to be used for getting the resource from the