comparison ios/dw.m @ 2378:cc858be0cb81

iOS: More work on conversion from Mac... going to be a few more of these type commits before I actually get a building source.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 19 Mar 2021 18:19:47 +0000
parents 6393d8c10569
children e35887009bb5
comparison
equal deleted inserted replaced
2377:6393d8c10569 2378:cc858be0cb81
965 } 965 }
966 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 966 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
967 @end 967 @end
968 968
969 /* Subclass for a top-level window */ 969 /* Subclass for a top-level window */
970 @interface DWView : DWBox <UIWindowDelegate> 970 @interface DWView : DWBox /* <UIWindowDelegate> */
971 { 971 {
972 UIMenu *windowmenu; 972 UIMenu *windowmenu;
973 CGSize oldsize; 973 CGSize oldsize;
974 } 974 }
975 -(BOOL)windowShouldClose:(id)sender; 975 -(BOOL)windowShouldClose:(id)sender;
986 return NO; 986 return NO;
987 return YES; 987 return YES;
988 } 988 }
989 -(void)viewDidMoveToWindow 989 -(void)viewDidMoveToWindow
990 { 990 {
991 #if 0 /* TODO */
991 [[UINotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:UIWindowDidResizeNotification object:[self window]]; 992 [[UINotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:UIWindowDidResizeNotification object:[self window]];
992 [[UINotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeMain:) name:UIWindowDidBecomeMainNotification object:[self window]]; 993 [[UINotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeMain:) name:UIWindowDidBecomeMainNotification object:[self window]];
994 #endif
993 } 995 }
994 -(void)dealloc 996 -(void)dealloc
995 { 997 {
996 if(windowmenu) 998 if(windowmenu)
997 { 999 {
1030 _event_handler([self window], nil, 13); 1032 _event_handler([self window], nil, 13);
1031 } 1033 }
1032 -(void)setMenu:(UIMenu *)input { windowmenu = input; [windowmenu retain]; } 1034 -(void)setMenu:(UIMenu *)input { windowmenu = input; [windowmenu retain]; }
1033 -(void)menuHandler:(id)sender 1035 -(void)menuHandler:(id)sender
1034 { 1036 {
1035 id menu = [sender menu]; 1037 [DWObj menuHandler:sender];
1036
1037 /* Find the highest menu for this item */
1038 while([menu supermenu])
1039 {
1040 menu = [menu supermenu];
1041 }
1042
1043 /* Only perform the delay if this item is a child of the main menu */
1044 if([DWApp mainMenu] == menu)
1045 [DWObj performSelector:@selector(menuHandler:) withObject:sender afterDelay:0];
1046 else
1047 [DWObj menuHandler:sender];
1048 }
1049 -(void)mouseDragged:(UIEvent *)theEvent { _event_handler(self, theEvent, 5); }
1050 -(void)mouseMoved:(UIEvent *)theEvent
1051 {
1052 id hit = [self hitTest:[theEvent locationInWindow]];
1053
1054 if([hit isMemberOfClass:[DWRender class]])
1055 {
1056 _event_handler(hit, theEvent, 5);
1057 }
1058 } 1038 }
1059 @end 1039 @end
1060 1040
1061 /* Subclass for a button type */ 1041 /* Subclass for a button type */
1062 @interface DWButton : UIButton 1042 @interface DWButton : UIButton
1066 DWBox *parent; 1046 DWBox *parent;
1067 } 1047 }
1068 -(void *)userdata; 1048 -(void *)userdata;
1069 -(void)setUserdata:(void *)input; 1049 -(void)setUserdata:(void *)input;
1070 -(void)buttonClicked:(id)sender; 1050 -(void)buttonClicked:(id)sender;
1071 -(void)setButtonType:(UIButtonType)input;
1072 -(UIButtonType)buttonType; 1051 -(UIButtonType)buttonType;
1073 -(void)setParent:(DWBox *)input; 1052 -(void)setParent:(DWBox *)input;
1074 -(DWBox *)parent; 1053 -(DWBox *)parent;
1075 -(UIColor *)textColor;
1076 -(void)setTextColor:(UIColor *)textColor;
1077 @end 1054 @end
1078 1055
1079 @implementation DWButton 1056 @implementation DWButton
1080 -(void *)userdata { return userdata; } 1057 -(void *)userdata { return userdata; }
1081 -(void)setUserdata:(void *)input { userdata = input; } 1058 -(void)setUserdata:(void *)input { userdata = input; }
1082 -(void)buttonClicked:(id)sender 1059 -(void)buttonClicked:(id)sender
1083 { 1060 {
1084 _event_handler(self, nil, 8); 1061 _event_handler(self, nil, 8);
1085 if([self buttonType] == DWButtonTypeRadio) 1062 }
1086 {
1087 DWBox *viewbox = [self parent];
1088 Box *thisbox = [viewbox box];
1089 int z;
1090
1091 for(z=0;z<thisbox->count;z++)
1092 {
1093 if(thisbox->items[z].type != TYPEBOX)
1094 {
1095 id object = thisbox->items[z].hwnd;
1096
1097 if([object isMemberOfClass:[DWButton class]])
1098 {
1099 DWButton *button = object;
1100
1101 if(button != self && [button buttonType] == DWButtonTypeRadio)
1102 {
1103 [button setState:DWControlStateValueOff];
1104 }
1105 }
1106 }
1107 }
1108 }
1109 }
1110 -(void)setButtonType:(UIButtonType)input { buttonType = input; [super setButtonType:input]; }
1111 -(UIButtonType)buttonType { return buttonType; } 1063 -(UIButtonType)buttonType { return buttonType; }
1112 -(void)setParent:(DWBox *)input { parent = input; } 1064 -(void)setParent:(DWBox *)input { parent = input; }
1113 -(DWBox *)parent { return parent; } 1065 -(DWBox *)parent { return parent; }
1114 -(UIColor *)textColor
1115 {
1116 NSAttributedString *attrTitle = [self attributedTitle];
1117 NSUInteger len = [attrTitle length];
1118 NSRange range = NSMakeRange(0, MIN(len, 1));
1119 NSDictionary *attrs = [attrTitle fontAttributesInRange:range];
1120 UIColor *textColor = [UIColor controlTextColor];
1121 if (attrs) {
1122 textColor = [attrs objectForKey:NSForegroundColorAttributeName];
1123 }
1124 return textColor;
1125 }
1126 -(void)setTextColor:(UIColor *)textColor
1127 {
1128 NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc]
1129 initWithAttributedString:[self attributedTitle]];
1130 NSUInteger len = [attrTitle length];
1131 NSRange range = NSMakeRange(0, len);
1132 [attrTitle addAttribute:NSForegroundColorAttributeName
1133 value:textColor
1134 range:range];
1135 [attrTitle fixAttributesInRange:range];
1136 [self setAttributedTitle:attrTitle];
1137 [attrTitle release];
1138 }
1139 -(void)keyDown:(UIEvent *)theEvent
1140 {
1141 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
1142 if(vk == VK_RETURN || vk == VK_SPACE)
1143 {
1144 if(buttonType == DWButtonTypeSwitch)
1145 [self setState:([self state] ? DWControlStateValueOff : DWControlStateValueOn)];
1146 else if(buttonType == DWButtonTypeRadio)
1147 [self setState:DWControlStateValueOn];
1148 [self buttonClicked:self];
1149 }
1150 else
1151 {
1152 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
1153 [super keyDown:theEvent];
1154 }
1155 }
1156 -(void)insertTab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectNextKeyView:self]; }
1157 -(void)insertBacktab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectPreviousKeyView:self]; }
1158 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1066 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1159 @end 1067 @end
1160 1068
1161 /* Subclass for a progress type */ 1069 /* Subclass for a progress type */
1162 @interface DWPercent : NSProgressIndicator 1070 @interface DWPercent : UIProgressView
1163 { 1071 {
1164 void *userdata; 1072 void *userdata;
1165 } 1073 }
1166 -(void *)userdata; 1074 -(void *)userdata;
1167 -(void)setUserdata:(void *)input; 1075 -(void)setUserdata:(void *)input;
1196 -(void *)userdata { return userdata; } 1104 -(void *)userdata { return userdata; }
1197 -(void)setUserdata:(void *)input { userdata = input; } 1105 -(void)setUserdata:(void *)input { userdata = input; }
1198 -(void)setBox:(void *)input { box = input; } 1106 -(void)setBox:(void *)input { box = input; }
1199 -(id)box { return box; } 1107 -(id)box { return box; }
1200 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1108 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1201 @end
1202
1203 /* Subclass for a textfield that supports vertical centering */
1204 @interface DWTextFieldCell : UITextFieldCell
1205 {
1206 BOOL vcenter;
1207 }
1208 -(CGRect)drawingRectForBounds:(CGRect)theRect;
1209 -(void)setVCenter:(BOOL)input;
1210 @end
1211
1212 @implementation DWTextFieldCell
1213 -(CGRect)drawingRectForBounds:(CGRect)theRect
1214 {
1215 /* Get the parent's idea of where we should draw */
1216 CGRect newRect = [super drawingRectForBounds:theRect];
1217
1218 /* If we are being vertically centered */
1219 if(vcenter)
1220 {
1221 /* Get our ideal size for current text */
1222 CGSize textSize = [self cellSizeForBounds:theRect];
1223
1224 /* Center that in the proposed rect */
1225 float heightDelta = newRect.size.height - textSize.height;
1226 if (heightDelta > 0)
1227 {
1228 newRect.size.height -= heightDelta;
1229 newRect.origin.y += (heightDelta / 2);
1230 }
1231 }
1232
1233 return newRect;
1234 }
1235 -(void)setVCenter:(BOOL)input { vcenter = input; }
1236 @end 1109 @end
1237 1110
1238 @interface DWEntryFieldFormatter : NSFormatter 1111 @interface DWEntryFieldFormatter : NSFormatter
1239 { 1112 {
1240 int maxLength; 1113 int maxLength;
1285 1158
1286 @implementation DWEntryField 1159 @implementation DWEntryField
1287 -(void *)userdata { return userdata; } 1160 -(void *)userdata { return userdata; }
1288 -(void)setUserdata:(void *)input { userdata = input; } 1161 -(void)setUserdata:(void *)input { userdata = input; }
1289 -(void)setClickDefault:(id)input { clickDefault = input; } 1162 -(void)setClickDefault:(id)input { clickDefault = input; }
1290 -(void)keyUp:(UIEvent *)theEvent
1291 {
1292 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
1293 if(clickDefault && vk == VK_RETURN)
1294 {
1295 if([clickDefault isKindOfClass:[UIButton class]])
1296 [clickDefault buttonClicked:self];
1297 else
1298 [[self window] makeFirstResponder:clickDefault];
1299 } else
1300 {
1301 [super keyUp:theEvent];
1302 }
1303 }
1304 -(BOOL)performKeyEquivalent:(UIEvent *)theEvent
1305 {
1306 if(([theEvent modifierFlags] & DWEventModifierFlagDeviceIndependentFlagsMask) == DWEventModifierFlagCommand)
1307 {
1308 if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"x"])
1309 return [NSApp sendAction:@selector(cut:) to:[[self window] firstResponder] from:self];
1310 else if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"c"])
1311 return [NSApp sendAction:@selector(copy:) to:[[self window] firstResponder] from:self];
1312 else if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"v"])
1313 return [NSApp sendAction:@selector(paste:) to:[[self window] firstResponder] from:self];
1314 else if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"a"])
1315 return [NSApp sendAction:@selector(selectAll:) to:[[self window] firstResponder] from:self];
1316 }
1317 return [super performKeyEquivalent:theEvent];
1318 }
1319 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1163 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1320 @end 1164 @end
1321 1165
1322 /* Subclass for a text and status text type */ 1166 /* Subclass for a text and status text type */
1323 @interface DWText : UITextField 1167 @interface DWText : UILabel
1324 { 1168 {
1325 void *userdata; 1169 void *userdata;
1326 id clickDefault; 1170 id clickDefault;
1327 } 1171 }
1328 -(void *)userdata; 1172 -(void *)userdata;
1334 -(void)setUserdata:(void *)input { userdata = input; } 1178 -(void)setUserdata:(void *)input { userdata = input; }
1335 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; } 1179 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1336 @end 1180 @end
1337 1181
1338 1182
1339 /* Subclass for a entryfield password type */
1340 @interface DWEntryFieldPassword : NSSecureTextField
1341 {
1342 void *userdata;
1343 id clickDefault;
1344 }
1345 -(void *)userdata;
1346 -(void)setUserdata:(void *)input;
1347 -(void)setClickDefault:(id)input;
1348 @end
1349
1350 @implementation DWEntryFieldPassword
1351 -(void *)userdata { return userdata; }
1352 -(void)setUserdata:(void *)input { userdata = input; }
1353 -(void)setClickDefault:(id)input { clickDefault = input; }
1354 -(void)keyUp:(UIEvent *)theEvent
1355 {
1356 if(clickDefault && [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN)
1357 {
1358 if([clickDefault isKindOfClass:[UIButton class]])
1359 [clickDefault buttonClicked:self];
1360 else
1361 [[self window] makeFirstResponder:clickDefault];
1362 }
1363 else
1364 {
1365 [super keyUp:theEvent];
1366 }
1367 }
1368 -(BOOL)performKeyEquivalent:(UIEvent *)theEvent
1369 {
1370 if(([theEvent modifierFlags] & DWEventModifierFlagDeviceIndependentFlagsMask) == DWEventModifierFlagCommand)
1371 {
1372 if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"x"])
1373 return [NSApp sendAction:@selector(cut:) to:[[self window] firstResponder] from:self];
1374 else if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"c"])
1375 return [NSApp sendAction:@selector(copy:) to:[[self window] firstResponder] from:self];
1376 else if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"v"])
1377 return [NSApp sendAction:@selector(paste:) to:[[self window] firstResponder] from:self];
1378 else if ([[theEvent charactersIgnoringModifiers] isEqualToString:@"a"])
1379 return [NSApp sendAction:@selector(selectAll:) to:[[self window] firstResponder] from:self];
1380 }
1381 return [super performKeyEquivalent:theEvent];
1382 }
1383 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1384 @end
1385
1386 /* Subclass for a Notebook control type */ 1183 /* Subclass for a Notebook control type */
1387 @interface DWNotebook : NSTabView <NSTabViewDelegate> 1184 @interface DWNotebook : UISegmentedControl
1388 { 1185 {
1389 void *userdata; 1186 void *userdata;
1390 int pageid; 1187 int pageid;
1391 } 1188 }
1392 -(void *)userdata; 1189 -(void *)userdata;
1393 -(void)setUserdata:(void *)input; 1190 -(void)setUserdata:(void *)input;
1394 -(int)pageid; 1191 -(int)pageid;
1395 -(void)setPageid:(int)input; 1192 -(void)setPageid:(int)input;
1396 -(void)tabView:(NSTabView *)notebook didSelectTabViewItem:(NSTabViewItem *)notepage; 1193 -(void)pageChanged;
1397 @end 1194 @end
1398 1195
1399 /* Subclass for a Notebook page type */ 1196 /* Subclass for a Notebook page type */
1400 @interface DWNotebookPage : NSTabViewItem 1197 @interface DWNotebookPage : UISegmentedControl
1401 { 1198 {
1402 void *userdata; 1199 void *userdata;
1403 int pageid; 1200 int pageid;
1404 } 1201 }
1405 -(void *)userdata; 1202 -(void *)userdata;
1411 @implementation DWNotebook 1208 @implementation DWNotebook
1412 -(void *)userdata { return userdata; } 1209 -(void *)userdata { return userdata; }
1413 -(void)setUserdata:(void *)input { userdata = input; } 1210 -(void)setUserdata:(void *)input { userdata = input; }
1414 -(int)pageid { return pageid; } 1211 -(int)pageid { return pageid; }
1415 -(void)setPageid:(int)input { pageid = input; } 1212 -(void)setPageid:(int)input { pageid = input; }
1416 -(void)tabView:(NSTabView *)notebook didSelectTabViewItem:(NSTabViewItem *)notepage 1213 -(void)pageChanged
1417 { 1214 {
1215 #if 0 /* TODO: Implement page/segment changed handler */
1418 id object = [notepage view]; 1216 id object = [notepage view];
1419 DWNotebookPage *page = (DWNotebookPage *)notepage; 1217 DWNotebookPage *page = (DWNotebookPage *)notepage;
1420 1218
1421 if([object isMemberOfClass:[DWBox class]]) 1219 if([object isMemberOfClass:[DWBox class]])
1422 { 1220 {
1425 CGSize size = [view frame].size; 1223 CGSize size = [view frame].size;
1426 _do_resize(box, size.width, size.height); 1224 _do_resize(box, size.width, size.height);
1427 _handle_resize_events(box); 1225 _handle_resize_events(box);
1428 } 1226 }
1429 _event_handler(self, DW_INT_TO_POINTER([page pageid]), 15); 1227 _event_handler(self, DW_INT_TO_POINTER([page pageid]), 15);
1430 } 1228 #endif
1431 -(void)keyDown:(UIEvent *)theEvent 1229 }
1432 {
1433 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
1434
1435 if(vk == NSTabCharacter || vk == NSBackTabCharacter)
1436 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
1437 else if(vk == NSLeftArrowFunctionKey)
1438 {
1439 NSArray *pages = [self tabViewItems];
1440 DWNotebookPage *page = (DWNotebookPage *)[self selectedTabViewItem];
1441 NSUInteger index = [pages indexOfObject:page];
1442
1443 if(index != NSNotFound)
1444 {
1445 if(index > 0)
1446 [self selectTabViewItem:[pages objectAtIndex:(index-1)]];
1447 else
1448 [self selectTabViewItem:[pages objectAtIndex:0]];
1449
1450 }
1451 }
1452 else if(vk == NSRightArrowFunctionKey)
1453 {
1454 NSArray *pages = [self tabViewItems];
1455 DWNotebookPage *page = (DWNotebookPage *)[self selectedTabViewItem];
1456 NSUInteger index = [pages indexOfObject:page];
1457 NSUInteger count = [pages count];
1458
1459 if(index != NSNotFound)
1460 {
1461 if(index + 1 < count)
1462 [self selectTabViewItem:[pages objectAtIndex:(index+1)]];
1463 else
1464 [self selectTabViewItem:[pages objectAtIndex:(count-1)]];
1465
1466 }
1467 }
1468 [super keyDown:theEvent];
1469 }
1470 -(void)insertTab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectNextKeyView:self]; }
1471 -(void)insertBacktab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectPreviousKeyView:self]; }
1472 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1230 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1473 @end 1231 @end
1474 1232
1475 @implementation DWNotebookPage 1233 @implementation DWNotebookPage
1476 -(void *)userdata { return userdata; } 1234 -(void *)userdata { return userdata; }
1479 -(void)setPageid:(int)input { pageid = input; } 1237 -(void)setPageid:(int)input { pageid = input; }
1480 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1238 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1481 @end 1239 @end
1482 1240
1483 /* Subclass for a splitbar type */ 1241 /* Subclass for a splitbar type */
1484 @interface DWSplitBar : NSSplitView <NSSplitViewDelegate> 1242 @interface DWSplitBar : UISplitViewController
1485 { 1243 {
1486 void *userdata; 1244 void *userdata;
1487 float percent; 1245 float percent;
1488 NSInteger Tag; 1246 NSInteger Tag;
1489 } 1247 }
1496 @end 1254 @end
1497 1255
1498 @implementation DWSplitBar 1256 @implementation DWSplitBar
1499 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification 1257 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification
1500 { 1258 {
1501 NSArray *views = [self subviews]; 1259 NSArray *views = [self.view subviews];
1502 id object; 1260 id object;
1503 1261
1504 for(object in views) 1262 for(object in views)
1505 { 1263 {
1506 if([object isMemberOfClass:[DWBox class]]) 1264 if([object isMemberOfClass:[DWBox class]])
1532 @end 1290 @end
1533 1291
1534 @implementation DWSlider 1292 @implementation DWSlider
1535 -(void *)userdata { return userdata; } 1293 -(void *)userdata { return userdata; }
1536 -(void)setUserdata:(void *)input { userdata = input; } 1294 -(void)setUserdata:(void *)input { userdata = input; }
1537 -(void)sliderChanged:(id)sender { _event_handler(self, (void *)[self integerValue], 14); } 1295 -(void)sliderChanged:(id)sender { int intVal = (int)[self value]; _event_handler(self, DW_INT_TO_POINTER(intVal), 14); }
1538 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1539 @end
1540
1541 /* Subclass for a slider type */
1542 @interface DWScrollbar : NSScroller
1543 {
1544 void *userdata;
1545 double range;
1546 double visible;
1547 int vertical;
1548 }
1549 -(void *)userdata;
1550 -(void)setUserdata:(void *)input;
1551 -(float)range;
1552 -(float)visible;
1553 -(int)vertical;
1554 -(void)setVertical:(int)value;
1555 -(void)setRange:(double)input1 andVisible:(double)input2;
1556 -(void)scrollerChanged:(id)sender;
1557 @end
1558
1559 @implementation DWScrollbar
1560 -(void *)userdata { return userdata; }
1561 -(void)setUserdata:(void *)input { userdata = input; }
1562 -(float)range { return range; }
1563 -(float)visible { return visible; }
1564 -(int)vertical { return vertical; }
1565 -(void)setVertical:(int)value { vertical = value; }
1566 -(void)setRange:(double)input1 andVisible:(double)input2 { range = input1; visible = input2; }
1567 -(void)scrollerChanged:(id)sender
1568 {
1569 double max = (range - visible);
1570 double result = ([self doubleValue] * max);
1571 double newpos = result;
1572
1573 switch ([sender hitPart])
1574 {
1575 case NSScrollerDecrementPage:
1576 newpos -= visible;
1577 if(newpos < 0)
1578 {
1579 newpos = 0;
1580 }
1581 break;
1582
1583 case NSScrollerIncrementPage:
1584 newpos += visible;
1585 if(newpos > max)
1586 {
1587 newpos = max;
1588 }
1589 break;
1590
1591 default:
1592 ; /* do nothing */
1593 }
1594 int newposi = (int)newpos;
1595 newpos = (newpos - (double)newposi) > 0.5 ? (double)(newposi + 1) : (double)newposi;
1596 if(newpos != result)
1597 {
1598 [self setDoubleValue:(newpos/max)];
1599 }
1600 _event_handler(self, DW_INT_TO_POINTER((int)newpos), 14);
1601 }
1602 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1296 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1603 @end 1297 @end
1604 1298
1605 /* Subclass for a MLE type */ 1299 /* Subclass for a MLE type */
1606 @interface DWMLE : UITextView 1300 @interface DWMLE : UITextView
1620 -(id)scrollview { return scrollview; } 1314 -(id)scrollview { return scrollview; }
1621 -(void)setScrollview:(id)input { scrollview = input; } 1315 -(void)setScrollview:(id)input { scrollview = input; }
1622 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1316 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1623 @end 1317 @end
1624 1318
1625 NSTableCellView *_dw_table_cell_view_new(UIImage *icon, NSString *text) 1319 UITableViewCell *_dw_table_cell_view_new(UIImage *icon, NSString *text)
1626 { 1320 {
1627 NSTableCellView *browsercell = [[[NSTableCellView alloc] init] autorelease]; 1321 UITableViewCell *browsercell = [[[UITableViewCell alloc] init] autorelease];
1628 [browsercell setAutoresizesSubviews:YES]; 1322 [browsercell setAutoresizesSubviews:YES];
1629 if(icon) 1323 if(icon)
1630 { 1324 {
1631 UIImageView *iv = [[[UIImageView alloc] init] autorelease]; 1325 UIImageView *iv = [[[UIImageView alloc] init] autorelease];
1632 [iv setAutoresizingMask:UIViewHeightSizable|(text ? 0 :UIViewWidthSizable)]; 1326 [iv setAutoresizingMask:UIViewAutoresizingFlexibleHeight|(text ? 0 :UIViewAutoresizingFlexibleWidth)];
1633 [iv setImage:icon]; 1327 [iv setImage:icon];
1634 [browsercell setImageView:iv]; 1328 [browsercell setImageView:iv];
1635 [browsercell addSubview:iv]; 1329 [browsercell addSubview:iv];
1636 } 1330 }
1637 if(text) 1331 if(text)
1638 { 1332 {
1639 UITextField *tf = [[[UITextField alloc] init] autorelease]; 1333 /* Might switch to UITextFieldView in the future if they need to be editable */
1640 [tf setAutoresizingMask:UIViewHeightSizable|UIViewWidthSizable]; 1334 UILabel *label = [[[UILabel alloc] init] autorelease];
1641 [tf setStringValue:text]; 1335 [label setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];
1642 [tf setEditable:NO]; 1336 [label setText:text];
1643 [tf setBezeled:NO]; 1337 [browsercell setTextField:label];
1644 [tf setBordered:NO]; 1338 [browsercell addSubview:label];
1645 [tf setDrawsBackground:NO];
1646 [[tf cell] setVCenter:YES];
1647 [browsercell setTextField:tf];
1648 [browsercell addSubview:tf];
1649 } 1339 }
1650 return browsercell; 1340 return browsercell;
1651 } 1341 }
1652 1342
1653 void _dw_table_cell_view_layout(NSTableCellView *result) 1343 void _dw_table_cell_view_layout(NSTableCellView *result)
1659 UIImage *icon = [iv image]; 1349 UIImage *icon = [iv image];
1660 UITextField *tf = [result textField]; 1350 UITextField *tf = [result textField];
1661 CGRect rect = result.frame; 1351 CGRect rect = result.frame;
1662 int width =[icon size].width; 1352 int width =[icon size].width;
1663 1353
1664 [iv setFrame:NSMakeRect(0,0,width,rect.size.height)]; 1354 [iv setFrame:CGRectMake(0,0,width,rect.size.height)];
1665 1355
1666 /* Adjust the rect to allow space for the image */ 1356 /* Adjust the rect to allow space for the image */
1667 rect.origin.x += width; 1357 rect.origin.x += width;
1668 rect.size.width -= width; 1358 rect.size.width -= width;
1669 [tf setFrame:rect]; 1359 [tf setFrame:rect];
1670 } 1360 }
1671 } 1361 }
1672
1673 @interface DWFocusRingScrollView : UIScrollView
1674 {
1675 BOOL shouldDrawFocusRing;
1676 NSResponder* lastResp;
1677 }
1678 @end
1679
1680 @implementation DWFocusRingScrollView
1681 -(BOOL)needsDisplay;
1682 {
1683 NSResponder* resp = nil;
1684
1685 if([[self window] isKeyWindow])
1686 {
1687 resp = [[self window] firstResponder];
1688 if (resp == lastResp)
1689 return [super needsDisplay];
1690 }
1691 else if (lastResp == nil)
1692 {
1693 return [super needsDisplay];
1694 }
1695 shouldDrawFocusRing = (resp != nil && [resp isKindOfClass:[UIView class]] && [(UIView*)resp isDescendantOf:self]);
1696 lastResp = resp;
1697 [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]];
1698 return YES;
1699 }
1700 -(void)drawRect:(CGRect)rect
1701 {
1702 [super drawRect:rect];
1703
1704 if(shouldDrawFocusRing)
1705 {
1706 NSSetFocusRingStyle(NSFocusRingOnly);
1707 UIRectFill(rect);
1708 }
1709 }
1710 @end
1711 1362
1712 /* Subclass for a Container/List type */ 1363 /* Subclass for a Container/List type */
1713 @interface DWContainer : NSTableView <NSTableViewDataSource,NSTableViewDelegate> 1364 @interface DWContainer : NSTableView <NSTableViewDataSource,NSTableViewDelegate>
1714 { 1365 {
1715 void *userdata; 1366 void *userdata;
3846 [ object isMemberOfClass:[DWSlider class] ]) 3497 [ object isMemberOfClass:[DWSlider class] ])
3847 { 3498 {
3848 thiswidth = 100; 3499 thiswidth = 100;
3849 thisheight = 20; 3500 thisheight = 20;
3850 } 3501 }
3851 /* Handle the ranged widgets */
3852 else if([ object isMemberOfClass:[DWScrollbar class] ])
3853 {
3854 if([object vertical])
3855 {
3856 thiswidth = 14;
3857 thisheight = 100;
3858 }
3859 else
3860 {
3861 thiswidth = 100;
3862 thisheight = 14;
3863 }
3864 }
3865 /* Handle bitmap size */ 3502 /* Handle bitmap size */
3866 else if([ object isMemberOfClass:[UIImageView class] ]) 3503 else if([ object isMemberOfClass:[UIImageView class] ])
3867 { 3504 {
3868 UIImage *image = [object image]; 3505 UIImage *image = [object image];
3869 3506
4326 [button setTitle:[ NSString stringWithUTF8String:text ]]; 3963 [button setTitle:[ NSString stringWithUTF8String:text ]];
4327 } 3964 }
4328 [button setTarget:button]; 3965 [button setTarget:button];
4329 [button setAction:@selector(buttonClicked:)]; 3966 [button setAction:@selector(buttonClicked:)];
4330 [button setTag:cid]; 3967 [button setTag:cid];
4331 [button setButtonType:DWButtonTypeMomentaryPushIn];
4332 [button setBezelStyle:DWBezelStyleRegularSquare];
4333 /* TODO: Reenable scaling in the future if it is possible on other platforms.
4334 [[button cell] setImageScaling:UIImageScaleProportionallyDown]; */
4335 if(DWDefaultFont) 3968 if(DWDefaultFont)
4336 { 3969 {
4337 [[button cell] setFont:DWDefaultFont]; 3970 [[button cell] setFont:DWDefaultFont];
4338 } 3971 }
4339 return button; 3972 return button;
4346 * id: An ID to be used with dw_window_from_id() or 0L. 3979 * id: An ID to be used with dw_window_from_id() or 0L.
4347 */ 3980 */
4348 HWND API dw_button_new(const char *text, ULONG cid) 3981 HWND API dw_button_new(const char *text, ULONG cid)
4349 { 3982 {
4350 DWButton *button = _dw_button_new(text, cid); 3983 DWButton *button = _dw_button_new(text, cid);
4351 [button setButtonType:DWButtonTypeMomentaryPushIn];
4352 [button setBezelStyle:DWBezelStyleRounded];
4353 [button setImagePosition:NSNoImage]; 3984 [button setImagePosition:NSNoImage];
4354 [button setAlignment:DWTextAlignmentCenter]; 3985 [button setAlignment:DWTextAlignmentCenter];
4355 [[button cell] setControlTint:NSBlueControlTint]; 3986 [[button cell] setControlTint:NSBlueControlTint];
4356 return button; 3987 return button;
4357 } 3988 }
4365 HWND API dw_entryfield_new(const char *text, ULONG cid) 3996 HWND API dw_entryfield_new(const char *text, ULONG cid)
4366 { 3997 {
4367 DWEntryField *entry = [[DWEntryField alloc] init]; 3998 DWEntryField *entry = [[DWEntryField alloc] init];
4368 [entry setStringValue:[ NSString stringWithUTF8String:text ]]; 3999 [entry setStringValue:[ NSString stringWithUTF8String:text ]];
4369 [entry setTag:cid]; 4000 [entry setTag:cid];
4370 [[entry cell] setScrollable:YES];
4371 [[entry cell] setWraps:NO];
4372 return entry; 4001 return entry;
4373 } 4002 }
4374 4003
4375 /* 4004 /*
4376 * Create a new Entryfield (password) window (widget) to be packed. 4005 * Create a new Entryfield (password) window (widget) to be packed.
4378 * text: The default text to be in the entryfield widget. 4007 * text: The default text to be in the entryfield widget.
4379 * id: An ID to be used with dw_window_from_id() or 0L. 4008 * id: An ID to be used with dw_window_from_id() or 0L.
4380 */ 4009 */
4381 HWND API dw_entryfield_password_new(const char *text, ULONG cid) 4010 HWND API dw_entryfield_password_new(const char *text, ULONG cid)
4382 { 4011 {
4383 DWEntryFieldPassword *entry = [[DWEntryFieldPassword alloc] init]; 4012 DWEntryField *entry = dw_entryfield_new(text, cid);
4384 [entry setStringValue:[ NSString stringWithUTF8String:text ]]; 4013 [entry setSecureTextEntry:YES];
4385 [entry setTag:cid];
4386 [[entry cell] setScrollable:YES];
4387 [[entry cell] setWraps:NO];
4388 return entry; 4014 return entry;
4389 } 4015 }
4390 4016
4391 /* 4017 /*
4392 * Sets the entryfield character limit. 4018 * Sets the entryfield character limit.
4551 * id: An ID to be used with dw_window_from_id() or 0L. 4177 * id: An ID to be used with dw_window_from_id() or 0L.
4552 */ 4178 */
4553 HWND API dw_radiobutton_new(const char *text, ULONG cid) 4179 HWND API dw_radiobutton_new(const char *text, ULONG cid)
4554 { 4180 {
4555 DWButton *button = _dw_button_new(text, cid); 4181 DWButton *button = _dw_button_new(text, cid);
4556 [button setButtonType:DWButtonTypeRadio]; 4182 /* TODO: Customize to be a radio button */
4557 return button; 4183 return button;
4558 } 4184 }
4559 4185
4560 /* 4186 /*
4561 * Create a new slider window (widget) to be packed. 4187 * Create a new slider window (widget) to be packed.
4607 * increments: Number of increments available. 4233 * increments: Number of increments available.
4608 * id: An ID to be used with dw_window_from_id() or 0L. 4234 * id: An ID to be used with dw_window_from_id() or 0L.
4609 */ 4235 */
4610 HWND API dw_scrollbar_new(int vertical, ULONG cid) 4236 HWND API dw_scrollbar_new(int vertical, ULONG cid)
4611 { 4237 {
4612 DWScrollbar *scrollbar; 4238 /*TODO: Implement scrollbars if possible */
4613 if(vertical) 4239 return 0;
4614 {
4615 scrollbar = [[DWScrollbar alloc] init];
4616 [scrollbar setVertical:YES];
4617 }
4618 else
4619 {
4620 scrollbar = [[DWScrollbar alloc] initWithFrame:NSMakeRect(0,0,100,5)];
4621 }
4622 [scrollbar setRange:0.0 andVisible:0.0];
4623 [scrollbar setKnobProportion:1.0];
4624 [scrollbar setTarget:scrollbar];
4625 [scrollbar setAction:@selector(scrollerChanged:)];
4626 [scrollbar setTag:cid];
4627 [scrollbar setEnabled:YES];
4628 return scrollbar;
4629 } 4240 }
4630 4241
4631 /* 4242 /*
4632 * Returns the position of the scrollbar. 4243 * Returns the position of the scrollbar.
4633 * Parameters: 4244 * Parameters:
4634 * handle: Handle to the scrollbar to be queried. 4245 * handle: Handle to the scrollbar to be queried.
4635 */ 4246 */
4636 unsigned int API dw_scrollbar_get_pos(HWND handle) 4247 unsigned int API dw_scrollbar_get_pos(HWND handle)
4637 { 4248 {
4638 DWScrollbar *scrollbar = handle; 4249 /*TODO: Implement scrollbars if possible */
4639 float range = [scrollbar range]; 4250 return 0;
4640 float fresult = [scrollbar doubleValue] * range;
4641 return (int)fresult;
4642 } 4251 }
4643 4252
4644 /* 4253 /*
4645 * Sets the scrollbar position. 4254 * Sets the scrollbar position.
4646 * Parameters: 4255 * Parameters:
4647 * handle: Handle to the scrollbar to be set. 4256 * handle: Handle to the scrollbar to be set.
4648 * position: Position of the scrollbar withing the range. 4257 * position: Position of the scrollbar withing the range.
4649 */ 4258 */
4650 void API dw_scrollbar_set_pos(HWND handle, unsigned int position) 4259 void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
4651 { 4260 {
4652 DWScrollbar *scrollbar = handle; 4261 /*TODO: Implement scrollbars if possible */
4653 double range = [scrollbar range];
4654 double visible = [scrollbar visible];
4655 double newpos = (double)position/(range-visible);
4656 [scrollbar setDoubleValue:newpos];
4657 } 4262 }
4658 4263
4659 /* 4264 /*
4660 * Sets the scrollbar range. 4265 * Sets the scrollbar range.
4661 * Parameters: 4266 * Parameters:
4663 * range: Maximum range value. 4268 * range: Maximum range value.
4664 * visible: Visible area relative to the range. 4269 * visible: Visible area relative to the range.
4665 */ 4270 */
4666 void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible) 4271 void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible)
4667 { 4272 {
4668 DWScrollbar *scrollbar = handle; 4273 /*TODO: Implement scrollbars if possible */
4669 double knob = (double)visible/(double)range;
4670 [scrollbar setRange:(double)range andVisible:(double)visible];
4671 [scrollbar setKnobProportion:knob];
4672 } 4274 }
4673 4275
4674 /* 4276 /*
4675 * Create a new percent bar window (widget) to be packed. 4277 * Create a new percent bar window (widget) to be packed.
4676 * Parameters: 4278 * Parameters:
4730 * id: An ID to be used with dw_window_from_id() or 0L. 4332 * id: An ID to be used with dw_window_from_id() or 0L.
4731 */ 4333 */
4732 HWND API dw_checkbox_new(const char *text, ULONG cid) 4334 HWND API dw_checkbox_new(const char *text, ULONG cid)
4733 { 4335 {
4734 DWButton *button = _dw_button_new(text, cid); 4336 DWButton *button = _dw_button_new(text, cid);
4735 [button setButtonType:DWButtonTypeSwitch]; 4337 /* TODO: Switch to UISwitch control with text */
4736 [button setBezelStyle:DWBezelStyleRegularSquare];
4737 return button; 4338 return button;
4738 } 4339 }
4739 4340
4740 /* 4341 /*
4741 * Returns the state of the checkbox. 4342 * Returns the state of the checkbox.
8714 [object setTextColor:(fg ? fg : [UIColor controlTextColor])]; 8315 [object setTextColor:(fg ? fg : [UIColor controlTextColor])];
8715 [cell setTextColor:(fg ? fg : [UIColor controlTextColor])]; 8316 [cell setTextColor:(fg ? fg : [UIColor controlTextColor])];
8716 } 8317 }
8717 if([object isMemberOfClass:[DWButton class]]) 8318 if([object isMemberOfClass:[DWButton class]])
8718 { 8319 {
8719 [object setTextColor:(fg ? fg : [UIColor controlTextColor])]; 8320 [object setTitleColor:(fg ? fg : [UIColor controlTextColor])];
8720 } 8321 }
8721 if([object isKindOfClass:[UITextField class]] || [object isKindOfClass:[UIButton class]]) 8322 if([object isKindOfClass:[UITextField class]] || [object isKindOfClass:[UIButton class]])
8722 { 8323 {
8723 id cell = [object cell]; 8324 id cell = [object cell];
8724 8325
8785 tmp |= style; 8386 tmp |= style;
8786 8387
8787 issm(window, sssm, tmp); 8388 issm(window, sssm, tmp);
8788 } 8389 }
8789 } 8390 }
8790 else if([object isKindOfClass:[UITextField class]]) 8391 else if([object isKindOfClass:[UILabel class]])
8791 { 8392 {
8792 UITextField *tf = object; 8393 UILabel *label = object;
8793 DWTextFieldCell *cell = [tf cell]; 8394
8794 8395 [label setTextAlignment:(style & 0xF)];
8795 [cell setAlignment:(style & 0xF)]; 8396 #if 0 /* TODO: Implement vertical centering */
8796 if(mask & DW_DT_VCENTER && [cell isMemberOfClass:[DWTextFieldCell class]]) 8397 if(mask & DW_DT_VCENTER)
8797 { 8398 {
8798 [cell setVCenter:(style & DW_DT_VCENTER ? YES : NO)]; 8399 [cell setVCenter:(style & DW_DT_VCENTER ? YES : NO)];
8799 } 8400 }
8800 if(mask & DW_DT_WORDBREAK && [cell isMemberOfClass:[DWTextFieldCell class]]) 8401 #endif
8801 { 8402 if(mask & DW_DT_WORDBREAK)
8802 [cell setWraps:(style & DW_DT_WORDBREAK ? YES : NO)]; 8403 {
8404 if(style & DW_DT_WORDBREAK)
8405 [label setLineBreakMode:NSLineBreakByWordWrapping];
8406 else
8407 [label setLineBreakMode:NSLineBreakByTruncatingTail];
8803 } 8408 }
8804 } 8409 }
8805 else if([object isMemberOfClass:[UITextView class]]) 8410 else if([object isMemberOfClass:[UITextView class]])
8806 { 8411 {
8807 UITextView *tv = handle; 8412 UITextView *tv = handle;