Mercurial > dwindows
comparison ios/dw.m @ 2422:4a353a83b2e4
iOS: Initial attempt at implementing check and radio boxes using SF Symbols.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 04 Apr 2021 01:23:56 +0000 |
parents | d88928a85436 |
children | b4cb136b5222 |
comparison
equal
deleted
inserted
replaced
2421:d88928a85436 | 2422:4a353a83b2e4 |
---|---|
3 * A GTK like implementation of the iOS GUI | 3 * A GTK like implementation of the iOS GUI |
4 * | 4 * |
5 * (C) 2011-2021 Brian Smith <brian@dbsoft.org> | 5 * (C) 2011-2021 Brian Smith <brian@dbsoft.org> |
6 * (C) 2011-2018 Mark Hessling <mark@rexx.org> | 6 * (C) 2011-2018 Mark Hessling <mark@rexx.org> |
7 * | 7 * |
8 * Requires 10.0 or later. | 8 * Requires 13.0 or later. |
9 * clang -g -o dwtest -D__IOS__ -I. dwtest.c ios/dw.m -framework UIKit -framework WebKit -framework Foundation -framework UserNotifications | 9 * clang -g -o dwtest -D__IOS__ -I. dwtest.c ios/dw.m -framework UIKit -framework WebKit -framework Foundation -framework UserNotifications |
10 */ | 10 */ |
11 #import <Foundation/Foundation.h> | 11 #import <Foundation/Foundation.h> |
12 #import <UIKit/UIKit.h> | 12 #import <UIKit/UIKit.h> |
13 #import <WebKit/WebKit.h> | 13 #import <WebKit/WebKit.h> |
1325 [view setFrame:frame]; | 1325 [view setFrame:frame]; |
1326 [view windowResized:frame.size]; | 1326 [view windowResized:frame.size]; |
1327 } | 1327 } |
1328 @end | 1328 @end |
1329 | 1329 |
1330 #define _DW_BUTTON_TYPE_NORMAL 0 | |
1331 #define _DW_BUTTON_TYPE_CHECK 1 | |
1332 #define _DW_BUTTON_TYPE_RADIO 2 | |
1333 | |
1330 /* Subclass for a button type */ | 1334 /* Subclass for a button type */ |
1331 @interface DWButton : UIButton | 1335 @interface DWButton : UIButton |
1332 { | 1336 { |
1333 void *userdata; | 1337 void *userdata; |
1334 UIButtonType buttonType; | |
1335 DWBox *parent; | 1338 DWBox *parent; |
1339 int type, state; | |
1336 } | 1340 } |
1337 -(void *)userdata; | 1341 -(void *)userdata; |
1338 -(void)setUserdata:(void *)input; | 1342 -(void)setUserdata:(void *)input; |
1339 -(void)buttonClicked:(id)sender; | 1343 -(void)buttonClicked:(id)sender; |
1340 -(UIButtonType)buttonType; | |
1341 -(void)setParent:(DWBox *)input; | 1344 -(void)setParent:(DWBox *)input; |
1342 -(DWBox *)parent; | 1345 -(DWBox *)parent; |
1346 -(int)type; | |
1347 -(void)setType:(int)input; | |
1348 -(int)state; | |
1349 -(void)setState:(int)input; | |
1343 @end | 1350 @end |
1344 | 1351 |
1345 @implementation DWButton | 1352 @implementation DWButton |
1346 -(void *)userdata { return userdata; } | 1353 -(void *)userdata { return userdata; } |
1347 -(void)setUserdata:(void *)input { userdata = input; } | 1354 -(void)setUserdata:(void *)input { userdata = input; } |
1348 -(void)buttonClicked:(id)sender | 1355 -(void)buttonClicked:(id)sender |
1349 { | 1356 { |
1357 /* Toggle the button */ | |
1358 if(type == _DW_BUTTON_TYPE_CHECK) | |
1359 [self setState:(state ? FALSE : TRUE)]; | |
1360 else if(type == _DW_BUTTON_TYPE_RADIO) | |
1361 [self setState:TRUE]; | |
1362 | |
1350 _dw_event_handler(self, nil, 8); | 1363 _dw_event_handler(self, nil, 8); |
1351 } | 1364 |
1352 -(UIButtonType)buttonType { return buttonType; } | 1365 /* If it is a radio button, uncheck all the other radio buttons in the box */ |
1366 if(type == _DW_BUTTON_TYPE_RADIO) | |
1367 { | |
1368 DWBox *viewbox = [self parent]; | |
1369 Box *thisbox = [viewbox box]; | |
1370 int z; | |
1371 | |
1372 for(z=0;z<thisbox->count;z++) | |
1373 { | |
1374 if(thisbox->items[z].type != TYPEBOX) | |
1375 { | |
1376 id object = thisbox->items[z].hwnd; | |
1377 | |
1378 if([object isMemberOfClass:[DWButton class]]) | |
1379 { | |
1380 DWButton *button = object; | |
1381 | |
1382 if(button != self && [button type] == _DW_BUTTON_TYPE_RADIO) | |
1383 { | |
1384 [button setState:FALSE]; | |
1385 } | |
1386 } | |
1387 } | |
1388 } | |
1389 } | |
1390 } | |
1353 -(void)setParent:(DWBox *)input { parent = input; } | 1391 -(void)setParent:(DWBox *)input { parent = input; } |
1354 -(DWBox *)parent { return parent; } | 1392 -(DWBox *)parent { return parent; } |
1393 -(int)type { return type; } | |
1394 -(void)setType:(int)input { type = input; [self updateImage]; } | |
1395 -(void)updateImage | |
1396 { | |
1397 UIImage *image = nil; | |
1398 | |
1399 switch(type) | |
1400 { | |
1401 case _DW_BUTTON_TYPE_CHECK: | |
1402 { | |
1403 | |
1404 if(state) | |
1405 image = [UIImage systemImageNamed:@"checkbox.square"]; | |
1406 else | |
1407 image = [UIImage systemImageNamed:@"square"]; | |
1408 } | |
1409 break; | |
1410 case _DW_BUTTON_TYPE_RADIO: | |
1411 { | |
1412 if(state) | |
1413 image = [UIImage systemImageNamed:@"largecircle.fill.circle"]; | |
1414 else | |
1415 image = [UIImage systemImageNamed:@"circle"]; | |
1416 } | |
1417 break; | |
1418 } | |
1419 if(image) | |
1420 { | |
1421 CGSize size = [image size]; | |
1422 [self setImage:image forState:UIControlStateNormal]; | |
1423 [self setTitleEdgeInsets:UIEdgeInsetsMake(0,size.width,0,0)]; | |
1424 } | |
1425 } | |
1426 -(int)state { return state; } | |
1427 -(void)setState:(int)input { state = input; [self updateImage]; } | |
1355 -(void)dealloc { UserData *root = userdata; _dw_remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } | 1428 -(void)dealloc { UserData *root = userdata; _dw_remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } |
1356 @end | 1429 @end |
1357 | 1430 |
1358 /* Subclass for a progress type */ | 1431 /* Subclass for a progress type */ |
1359 @interface DWPercent : UIProgressView | 1432 @interface DWPercent : UIProgressView |
3141 int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0; | 3214 int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0; |
3142 NSString *nsstr = nil; | 3215 NSString *nsstr = nil; |
3143 id object = _dw_text_handle(handle); | 3216 id object = _dw_text_handle(handle); |
3144 | 3217 |
3145 /* Handle all the different button types */ | 3218 /* Handle all the different button types */ |
3146 if([ object isKindOfClass:[ UIButton class ] ]) | 3219 if([ object isMemberOfClass:[ DWButton class ] ]) |
3147 { | 3220 { |
3148 switch([object buttonType]) | 3221 UIImage *image = (UIImage *)[object image]; |
3149 { | 3222 |
3150 default: | 3223 if(image) |
3151 { | 3224 { |
3152 UIImage *image = (UIImage *)[object image]; | 3225 /* Image button */ |
3153 | 3226 CGSize size = [image size]; |
3154 if(image) | 3227 extrawidth = (int)size.width; |
3155 { | 3228 extraheight = (int)size.height; |
3156 /* Image button */ | 3229 } |
3157 CGSize size = [image size]; | 3230 /* Text button */ |
3158 thiswidth = (int)size.width; | 3231 nsstr = [[object titleLabel] text]; |
3159 thisheight = (int)size.height; | 3232 |
3160 } | 3233 if(nsstr && [nsstr length] > 0) |
3161 else | 3234 { |
3162 { | 3235 extrawidth += 8; |
3163 /* Text button */ | 3236 extraheight += 4; |
3164 nsstr = [[object titleLabel] text]; | |
3165 | |
3166 extrawidth = 8; | |
3167 extraheight = 4; | |
3168 } | |
3169 break; | |
3170 } | |
3171 } | 3237 } |
3172 } | 3238 } |
3173 /* If the control is an entryfield set width to 150 */ | 3239 /* If the control is an entryfield set width to 150 */ |
3174 else if([object isKindOfClass:[ UITextField class ]]) | 3240 else if([object isKindOfClass:[ UITextField class ]]) |
3175 { | 3241 { |
3842 DW_FUNCTION_ADD_PARAM2(text, cid) | 3908 DW_FUNCTION_ADD_PARAM2(text, cid) |
3843 DW_FUNCTION_RETURN(dw_radiobutton_new, HWND) | 3909 DW_FUNCTION_RETURN(dw_radiobutton_new, HWND) |
3844 DW_FUNCTION_RESTORE_PARAM2(text, const char *, cid, ULONG) | 3910 DW_FUNCTION_RESTORE_PARAM2(text, const char *, cid, ULONG) |
3845 { | 3911 { |
3846 DWButton *button = _dw_internal_button_new(text, cid); | 3912 DWButton *button = _dw_internal_button_new(text, cid); |
3847 /* TODO: Customize to be a radio button https://github.com/DavydLiu/DLRadioButton */ | 3913 [button setType:_DW_BUTTON_TYPE_RADIO]; |
3848 DW_FUNCTION_RETURN_THIS(button); | 3914 DW_FUNCTION_RETURN_THIS(button); |
3849 } | 3915 } |
3850 | 3916 |
3851 /* | 3917 /* |
3852 * Create a new slider window (widget) to be packed. | 3918 * Create a new slider window (widget) to be packed. |
3994 DW_FUNCTION_ADD_PARAM2(text, cid) | 4060 DW_FUNCTION_ADD_PARAM2(text, cid) |
3995 DW_FUNCTION_RETURN(dw_checkbox_new, HWND) | 4061 DW_FUNCTION_RETURN(dw_checkbox_new, HWND) |
3996 DW_FUNCTION_RESTORE_PARAM2(text, const char *, cid, ULONG) | 4062 DW_FUNCTION_RESTORE_PARAM2(text, const char *, cid, ULONG) |
3997 { | 4063 { |
3998 DWButton *button = _dw_internal_button_new(text, cid); | 4064 DWButton *button = _dw_internal_button_new(text, cid); |
3999 /* TODO: Switch to UISwitch control with text */ | 4065 [button setType:_DW_BUTTON_TYPE_CHECK]; |
4000 DW_FUNCTION_RETURN_THIS(button); | 4066 DW_FUNCTION_RETURN_THIS(button); |
4001 } | 4067 } |
4002 | 4068 |
4003 /* | 4069 /* |
4004 * Returns the state of the checkbox. | 4070 * Returns the state of the checkbox. |
4005 * Parameters: | 4071 * Parameters: |
4006 * handle: Handle to the checkbox to be queried. | 4072 * handle: Handle to the checkbox to be queried. |
4007 */ | 4073 */ |
4008 int API dw_checkbox_get(HWND handle) | 4074 DW_FUNCTION_DEFINITION(dw_checkbox_get, int, HWND handle) |
4075 DW_FUNCTION_ADD_PARAM1(handle) | |
4076 DW_FUNCTION_RETURN(dw_checkbox_get, int) | |
4077 DW_FUNCTION_RESTORE_PARAM1(handle, HWND) | |
4009 { | 4078 { |
4010 DWButton *button = handle; | 4079 DWButton *button = handle; |
4080 int retval = FALSE; | |
4081 | |
4011 if([button state]) | 4082 if([button state]) |
4012 { | 4083 retval = TRUE; |
4013 return TRUE; | 4084 DW_FUNCTION_RETURN_THIS(retval); |
4014 } | |
4015 return FALSE; | |
4016 } | 4085 } |
4017 | 4086 |
4018 /* | 4087 /* |
4019 * Sets the state of the checkbox. | 4088 * Sets the state of the checkbox. |
4020 * Parameters: | 4089 * Parameters: |
4021 * handle: Handle to the checkbox to be queried. | 4090 * handle: Handle to the checkbox to be queried. |
4022 * value: TRUE for checked, FALSE for unchecked. | 4091 * value: TRUE for checked, FALSE for unchecked. |
4023 */ | 4092 */ |
4024 void API dw_checkbox_set(HWND handle, int value) | 4093 DW_FUNCTION_DEFINITION(dw_checkbox_set, void, HWND handle, int value) |
4025 { | 4094 DW_FUNCTION_ADD_PARAM2(handle, value) |
4026 #if 0 /* TODO: Convert to UISwitch */ | 4095 DW_FUNCTION_NO_RETURN(dw_checkbox_set) |
4096 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, value, int) | |
4097 { | |
4027 DWButton *button = handle; | 4098 DWButton *button = handle; |
4028 if(value) | 4099 [button setState:value]; |
4029 { | 4100 DW_FUNCTION_RETURN_NOTHING; |
4030 [button setState:DWControlStateValueOn]; | |
4031 } | |
4032 else | |
4033 { | |
4034 [button setState:DWControlStateValueOff]; | |
4035 } | |
4036 #endif | |
4037 } | 4101 } |
4038 | 4102 |
4039 /* Internal common function to create containers and listboxes */ | 4103 /* Internal common function to create containers and listboxes */ |
4040 HWND _dw_cont_new(ULONG cid, int multi) | 4104 HWND _dw_cont_new(ULONG cid, int multi) |
4041 { | 4105 { |