Mercurial > dwindows
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; |