comparison ios/dw.m @ 2646:42bc7ddd6751

iOS: Reimplement DWSplitBar as a UIView subclass. Can't currently move the splitbar, but it displays and can be programatically moved/resized.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 30 Aug 2021 23:35:30 +0000
parents 608598b9fed9
children 34c4cb84834a
comparison
equal deleted inserted replaced
2645:cb984fab3a17 2646:42bc7ddd6751
1961 -(void)setPageid:(int)input { pageid = input; } 1961 -(void)setPageid:(int)input { pageid = input; }
1962 -(void)dealloc { UserData *root = userdata; _dw_remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1962 -(void)dealloc { UserData *root = userdata; _dw_remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1963 @end 1963 @end
1964 1964
1965 /* Subclass for a splitbar type */ 1965 /* Subclass for a splitbar type */
1966 @interface DWSplitBar : UISplitViewController <UISplitViewControllerDelegate> 1966 @interface DWSplitBar : UIView
1967 { 1967 {
1968 void *userdata; 1968 void *userdata;
1969 float percent; 1969 float percent;
1970 NSInteger Tag; 1970 NSInteger Tag;
1971 } 1971 id topleft;
1972 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification; 1972 id bottomright;
1973 int splittype;
1974 }
1973 -(void)setTag:(NSInteger)tag; 1975 -(void)setTag:(NSInteger)tag;
1974 -(void *)userdata; 1976 -(void *)userdata;
1975 -(void)setUserdata:(void *)input; 1977 -(void)setUserdata:(void *)input;
1976 -(float)percent; 1978 -(float)percent;
1977 -(void)setPercent:(float)input; 1979 -(void)setPercent:(float)input;
1980 -(id)topLeft;
1981 -(void)setTopLeft:(id)input;
1982 -(id)bottomRight;
1983 -(void)setBottomRight:(id)input;
1984 -(int)type;
1985 -(void)setType:(int)input;
1986 -(void)resize;
1978 @end 1987 @end
1979 1988
1980 @implementation DWSplitBar 1989 @implementation DWSplitBar
1981 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification
1982 {
1983 NSArray *views = [self.view subviews];
1984 id object;
1985
1986 for(object in views)
1987 {
1988 if([object isMemberOfClass:[DWBox class]])
1989 {
1990 DWBox *view = object;
1991 Box *box = [view box];
1992 CGSize size = [view frame].size;
1993 _dw_do_resize(box, size.width, size.height);
1994 _dw_handle_resize_events(box);
1995 }
1996 }
1997 }
1998 -(void)setTag:(NSInteger)tag { Tag = tag; } 1990 -(void)setTag:(NSInteger)tag { Tag = tag; }
1999 -(void *)userdata { return userdata; } 1991 -(void *)userdata { return userdata; }
2000 -(void)setUserdata:(void *)input { userdata = input; } 1992 -(void)setUserdata:(void *)input { userdata = input; }
2001 -(float)percent { return percent; } 1993 -(float)percent { return percent; }
2002 -(void)setPercent:(float)input { percent = input; } 1994 -(void)setPercent:(float)input { percent = input; [self resize]; }
1995 -(id)topLeft { return topleft; }
1996 -(void)setTopLeft:(id)input
1997 {
1998 topleft = input;
1999 [self addSubview:topleft];
2000 [topleft autorelease];
2001 }
2002 -(id)bottomRight { return bottomright; }
2003 -(void)setBottomRight:(id)input
2004 {
2005 bottomright = input;
2006 [self addSubview:bottomright];
2007 [bottomright autorelease];
2008
2009 }
2010 -(int)type { return splittype; }
2011 -(void)setType:(int)input { splittype = input; }
2012 -(void)resize
2013 {
2014 CGRect rect = self.frame;
2015 CGRect half = rect;
2016
2017 half.origin.x = half.origin.y = 0;
2018
2019 if(splittype == DW_HORZ)
2020 half.size.width = (100.0/percent) * rect.size.width;
2021 else
2022 half.size.height = (100.0/percent) * rect.size.height;
2023 if(topleft)
2024 {
2025 DWBox *view = topleft;
2026 Box *box = [view box];
2027 [topleft setFrame:half];
2028 _dw_do_resize(box, half.size.width, half.size.height);
2029 _dw_handle_resize_events(box);
2030 }
2031 if(splittype == DW_HORZ)
2032 half.origin.x = half.size.width;
2033 else
2034 half.origin.y = half.size.height;
2035 if(bottomright)
2036 {
2037 DWBox *view = bottomright;
2038 Box *box = [view box];
2039 [bottomright setFrame:half];
2040 _dw_do_resize(box, half.size.width, half.size.height);
2041 _dw_handle_resize_events(box);
2042 }
2043 }
2003 -(void)dealloc { UserData *root = userdata; _dw_remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 2044 -(void)dealloc { UserData *root = userdata; _dw_remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
2004 @end 2045 @end
2005 2046
2006 /* Subclass for a slider type */ 2047 /* Subclass for a slider type */
2007 @interface DWSlider : UISlider 2048 @interface DWSlider : UISlider
3114 [stepper setFrame:CGRectMake(rect.size.width-stepperwidth,0,stepperwidth,rect.size.height)]; 3155 [stepper setFrame:CGRectMake(rect.size.width-stepperwidth,0,stepperwidth,rect.size.height)];
3115 } 3156 }
3116 else if([handle isMemberOfClass:[DWSplitBar class]]) 3157 else if([handle isMemberOfClass:[DWSplitBar class]])
3117 { 3158 {
3118 DWSplitBar *split = (DWSplitBar *)handle; 3159 DWSplitBar *split = (DWSplitBar *)handle;
3119 float percent = [split percent]; 3160 [split resize];
3120
3121 if(percent > 0 && rect.size.width > 20 && rect.size.height > 20)
3122 {
3123 dw_splitbar_set(handle, percent);
3124 [split setPercent:0];
3125 }
3126 [split splitViewDidResizeSubviews:nil];
3127 } 3161 }
3128 3162
3129 /* Advance the current position in the box */ 3163 /* Advance the current position in the box */
3130 if(thisbox->type == DW_HORZ) 3164 if(thisbox->type == DW_HORZ)
3131 currentx += width + (pad * 2); 3165 currentx += width + (pad * 2);
6952 DW_FUNCTION_ADD_PARAM4(type, topleft, bottomright, cid) 6986 DW_FUNCTION_ADD_PARAM4(type, topleft, bottomright, cid)
6953 DW_FUNCTION_RETURN(dw_splitbar_new, HWND) 6987 DW_FUNCTION_RETURN(dw_splitbar_new, HWND)
6954 DW_FUNCTION_RESTORE_PARAM4(type, int, topleft, HWND, bottomright, HWND, cid, unsigned long) 6988 DW_FUNCTION_RESTORE_PARAM4(type, int, topleft, HWND, bottomright, HWND, cid, unsigned long)
6955 { 6989 {
6956 DW_FUNCTION_INIT; 6990 DW_FUNCTION_INIT;
6957 #ifdef _DW_USE_SPLITBAR
6958 id tmpbox = dw_box_new(DW_VERT, 0); 6991 id tmpbox = dw_box_new(DW_VERT, 0);
6959 DWSplitBar *split = [[DWSplitBar alloc] init]; 6992 DWSplitBar *split = [[DWSplitBar alloc] init];
6960 UIViewController *vc = [[[UIViewController alloc] init] retain];
6961 [split setDelegate:split];
6962 dw_box_pack_start(tmpbox, topleft, 0, 0, TRUE, TRUE, 0); 6993 dw_box_pack_start(tmpbox, topleft, 0, 0, TRUE, TRUE, 0);
6963 if (@available(iOS 14.0, *)) { 6994 [split setTopLeft:tmpbox];
6964 [split setViewController:vc forColumn:UISplitViewControllerColumnPrimary];
6965 } else {
6966 [split addChildViewController:vc];
6967 }
6968 [[vc view] addSubview:tmpbox];
6969 [tmpbox autorelease];
6970 tmpbox = dw_box_new(DW_VERT, 0); 6995 tmpbox = dw_box_new(DW_VERT, 0);
6971 dw_box_pack_start(tmpbox, bottomright, 0, 0, TRUE, TRUE, 0); 6996 dw_box_pack_start(tmpbox, bottomright, 0, 0, TRUE, TRUE, 0);
6972 vc = [[UIViewController alloc] init]; 6997 [split setBottomRight:tmpbox];
6973 if (@available(iOS 14.0, *)) {
6974 [split setViewController:vc forColumn:UISplitViewControllerColumnSecondary];
6975 } else {
6976 [split addChildViewController:vc];
6977 }
6978 [[vc view] addSubview:tmpbox];
6979 [tmpbox autorelease];
6980 [vc autorelease];
6981 /* TODO: All iOS splitbars are vertical
6982 * [split setVertical:(type == DW_VERT ? YES : NO)];
6983 */
6984 /* Set the default percent to 50% split */
6985 [split setPercent:50.0]; 6998 [split setPercent:50.0];
6999 [split setType:type];
6986 [split setTag:cid]; 7000 [split setTag:cid];
6987 #else
6988 id split = dw_box_new(type, 0);
6989 dw_box_pack_start(split, topleft, 0, 0, TRUE, TRUE, 0);
6990 dw_box_pack_start(split, bottomright, 0, 0, TRUE, TRUE, 0);
6991 [split setTag:cid];
6992 #endif
6993 DW_FUNCTION_RETURN_THIS(split); 7001 DW_FUNCTION_RETURN_THIS(split);
6994 } 7002 }
6995 7003
6996 #ifdef _DW_USE_SPLITBAR
6997 /* 7004 /*
6998 * Sets the position of a splitbar (pecentage). 7005 * Sets the position of a splitbar (pecentage).
6999 * Parameters: 7006 * Parameters:
7000 * handle: The handle to the splitbar returned by dw_splitbar_new(). 7007 * handle: The handle to the splitbar returned by dw_splitbar_new().
7001 * percent: The position of the splitbar. 7008 * percent: The position of the splitbar.
7005 DW_FUNCTION_NO_RETURN(dw_splitbar_set) 7012 DW_FUNCTION_NO_RETURN(dw_splitbar_set)
7006 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, percent, float) 7013 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, percent, float)
7007 { 7014 {
7008 DW_FUNCTION_INIT; 7015 DW_FUNCTION_INIT;
7009 DWSplitBar *split = handle; 7016 DWSplitBar *split = handle;
7010 CGSize size = [split preferredContentSize]; 7017 [split setPercent:percent];
7011 float pos;
7012 /* Calculate the position based on the size */
7013 /* TODO: iOS split views are always vertical
7014 if(![split isVertical])
7015 pos = size.height * (percent / 100.0);
7016 else */
7017 pos = size.width * (percent / 100.0);
7018 if(pos > 0)
7019 {
7020 if (@available(iOS 14.0, *)) {
7021 [split setPreferredPrimaryColumnWidth:pos];
7022 } else {
7023 /* TODO: Is this possible on earlier versions? */
7024 }
7025 }
7026 else
7027 {
7028 /* If we have no size.. wait until the resize
7029 * event when we get an actual size to try
7030 * to set the splitbar again.
7031 */
7032 [split setPercent:percent];
7033 }
7034 DW_FUNCTION_RETURN_NOTHING; 7018 DW_FUNCTION_RETURN_NOTHING;
7035 } 7019 }
7036 7020
7037 /* 7021 /*
7038 * Gets the position of a splitbar (pecentage). 7022 * Gets the position of a splitbar (pecentage).
7042 float API dw_splitbar_get(HWND handle) 7026 float API dw_splitbar_get(HWND handle)
7043 { 7027 {
7044 DWSplitBar *split = handle; 7028 DWSplitBar *split = handle;
7045 float retval = 50.0; 7029 float retval = 50.0;
7046 7030
7047 if (@available(iOS 14.0, *)) { 7031 if(split)
7048 float primary = [split primaryColumnWidth]; 7032 retval = [split percent];
7049 float supplementary = [split supplementaryColumnWidth];
7050 retval = (primary / (primary + supplementary)) * 100.0;
7051 } else {
7052 /* TODO: If possible*/
7053 }
7054 return retval; 7033 return retval;
7055 } 7034 }
7056 #else
7057 /*
7058 * Sets the position of a splitbar (pecentage).
7059 * Parameters:
7060 * handle: The handle to the splitbar returned by dw_splitbar_new().
7061 * percent: The position of the splitbar.
7062 */
7063 void API dw_splitbar_set(HWND handle, float percent)
7064 {
7065 }
7066
7067 /*
7068 * Gets the position of a splitbar (pecentage).
7069 * Parameters:
7070 * handle: The handle to the splitbar returned by dw_splitbar_new().
7071 */
7072 float API dw_splitbar_get(HWND handle)
7073 {
7074 return 50.0;
7075 }
7076 #endif
7077 7035
7078 /* Internal function to convert fontname to UIFont */ 7036 /* Internal function to convert fontname to UIFont */
7079 UIFont *_dw_font_by_name(const char *fontname) 7037 UIFont *_dw_font_by_name(const char *fontname)
7080 { 7038 {
7081 UIFont *font = DWDefaultFont; 7039 UIFont *font = DWDefaultFont;