Mercurial > dwindows
comparison ios/dw.m @ 2380:93424ad710de
iOS: Remove printing and file browsing... more conversion.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sat, 20 Mar 2021 01:04:51 +0000 |
parents | e35887009bb5 |
children | 3777ea1cccdb |
comparison
equal
deleted
inserted
replaced
2379:e35887009bb5 | 2380:93424ad710de |
---|---|
18 #include <sys/un.h> | 18 #include <sys/un.h> |
19 #include <sys/mman.h> | 19 #include <sys/mman.h> |
20 #include <sys/time.h> | 20 #include <sys/time.h> |
21 #include <sys/stat.h> | 21 #include <sys/stat.h> |
22 #include <math.h> | 22 #include <math.h> |
23 | |
24 /* Macros to handle local auto-release pools */ | |
25 #define DW_LOCAL_POOL_IN NSAutoreleasePool *localpool = nil; \ | |
26 if(DWThread != (DWTID)-1 && pthread_self() != DWThread) \ | |
27 localpool = [[NSAutoreleasePool alloc] init]; | |
28 #define DW_LOCAL_POOL_OUT if(localpool) [localpool drain]; | |
23 | 29 |
24 /* Macros to encapsulate running functions on the main thread */ | 30 /* Macros to encapsulate running functions on the main thread */ |
25 #define DW_FUNCTION_INIT | 31 #define DW_FUNCTION_INIT |
26 #define DW_FUNCTION_DEFINITION(func, rettype, ...) void _##func(NSPointerArray *_args); \ | 32 #define DW_FUNCTION_DEFINITION(func, rettype, ...) void _##func(NSPointerArray *_args); \ |
27 rettype API func(__VA_ARGS__) { \ | 33 rettype API func(__VA_ARGS__) { \ |
758 -(void)setSize:(CGSize)input { | 764 -(void)setSize:(CGSize)input { |
759 size = input; | 765 size = input; |
760 if(cachedDrawingRep) | 766 if(cachedDrawingRep) |
761 { | 767 { |
762 UIImage *oldrep = cachedDrawingRep; | 768 UIImage *oldrep = cachedDrawingRep; |
763 cachedDrawingRep = [self bitmapImageRepForCachingDisplayInRect:self.bounds]; | 769 UIGraphicsBeginImageContext(self.frame.size); |
770 [[self layer] renderInContext:UIGraphicsGetCurrentContext()]; | |
771 cachedDrawingRep = UIGraphicsGetImageFromCurrentImageContext(); | |
772 UIGraphicsEndImageContext(); | |
764 [cachedDrawingRep retain]; | 773 [cachedDrawingRep retain]; |
765 [oldrep release]; | 774 [oldrep release]; |
766 } | 775 } |
767 } | 776 } |
768 -(CGSize)size { return size; } | 777 -(CGSize)size { return size; } |
769 -(UIImage *)cachedDrawingRep { | 778 -(UIImage *)cachedDrawingRep { |
770 if(!cachedDrawingRep) | 779 if(!cachedDrawingRep) |
771 { | 780 { |
772 cachedDrawingRep = [self bitmapImageRepForCachingDisplayInRect:self.bounds]; | 781 UIGraphicsBeginImageContext(self.frame.size); |
782 [[self layer] renderInContext:UIGraphicsGetCurrentContext()]; | |
783 cachedDrawingRep = UIGraphicsGetImageFromCurrentImageContext(); | |
784 UIGraphicsEndImageContext(); | |
773 [cachedDrawingRep retain]; | 785 [cachedDrawingRep retain]; |
774 } | 786 } |
775 /* Mark this render dirty if something is requesting it to draw */ | 787 /* Mark this render dirty if something is requesting it to draw */ |
776 if(![_DWDirtyDrawables containsObject:self]) | 788 if(![_DWDirtyDrawables containsObject:self]) |
777 [_DWDirtyDrawables addObject:self]; | 789 [_DWDirtyDrawables addObject:self]; |
829 UIAlertController* alert = [UIAlertController alertControllerWithTitle:[params objectAtIndex:0] | 841 UIAlertController* alert = [UIAlertController alertControllerWithTitle:[params objectAtIndex:0] |
830 message:[params objectAtIndex:1] | 842 message:[params objectAtIndex:1] |
831 preferredStyle:[[params objectAtIndex:2] integerValue]]; | 843 preferredStyle:[[params objectAtIndex:2] integerValue]]; |
832 | 844 |
833 UIAlertAction* action = [UIAlertAction actionWithTitle:[params objectAtIndex:3] style:UIAlertActionStyleDefault | 845 UIAlertAction* action = [UIAlertAction actionWithTitle:[params objectAtIndex:3] style:UIAlertActionStyleDefault |
834 handler:^(UIAlertAction * action) { iResponse = 0; }]; | 846 handler:^(UIAlertAction * action) { iResponse = 1; }]; |
835 [alert addAction:action]; | 847 [alert addAction:action]; |
836 if([params count] > 4) | 848 if([params count] > 4) |
837 action = [UIAlertAction actionWithTitle:[params objectAtIndex:4] style:UIAlertActionStyleDefault | 849 action = [UIAlertAction actionWithTitle:[params objectAtIndex:4] style:UIAlertActionStyleDefault |
838 handler:^(UIAlertAction * action) { iResponse = 1; }]; | 850 handler:^(UIAlertAction * action) { iResponse = 2; }]; |
839 if([params count] > 5) | 851 if([params count] > 5) |
840 action = [UIAlertAction actionWithTitle:[params objectAtIndex:5] style:UIAlertActionStyleDefault | 852 action = [UIAlertAction actionWithTitle:[params objectAtIndex:5] style:UIAlertActionStyleDefault |
841 handler:^(UIAlertAction * action) { iResponse = 2; }]; | 853 handler:^(UIAlertAction * action) { iResponse = 3; }]; |
842 | 854 |
843 [alert presentViewController:alert animated:YES completion:nil]; | 855 [alert presentViewController:alert animated:YES completion:nil]; |
844 [alert release]; | 856 [alert release]; |
845 [params addObject:[NSNumber numberWithInteger:iResponse]]; | 857 [params addObject:[NSNumber numberWithInteger:iResponse]]; |
846 } | 858 } |
974 } | 986 } |
975 -(BOOL)windowShouldClose:(id)sender; | 987 -(BOOL)windowShouldClose:(id)sender; |
976 -(void)setMenu:(UIMenu *)input; | 988 -(void)setMenu:(UIMenu *)input; |
977 -(void)windowDidBecomeMain:(id)sender; | 989 -(void)windowDidBecomeMain:(id)sender; |
978 -(void)menuHandler:(id)sender; | 990 -(void)menuHandler:(id)sender; |
979 -(void)mouseDragged:(UIEvent *)theEvent; | |
980 @end | 991 @end |
981 | 992 |
982 @implementation DWView | 993 @implementation DWView |
983 -(BOOL)windowShouldClose:(id)sender | 994 -(BOOL)windowShouldClose:(id)sender |
984 { | 995 { |
1368 int lastAddPoint, lastQueryPoint; | 1379 int lastAddPoint, lastQueryPoint; |
1369 id scrollview; | 1380 id scrollview; |
1370 int filesystem; | 1381 int filesystem; |
1371 } | 1382 } |
1372 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable; | 1383 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable; |
1384 #if 0 /* TODO: Switch to columnless versions */ | |
1373 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow; | 1385 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow; |
1374 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; | 1386 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; |
1387 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row; | |
1388 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row; | |
1389 #endif | |
1375 -(void *)userdata; | 1390 -(void *)userdata; |
1376 -(void)setUserdata:(void *)input; | 1391 -(void)setUserdata:(void *)input; |
1377 -(void)setFilesystem:(int)input; | 1392 -(void)setFilesystem:(int)input; |
1378 -(int)filesystem; | 1393 -(int)filesystem; |
1379 -(id)scrollview; | 1394 -(id)scrollview; |
1392 -(void)clear; | 1407 -(void)clear; |
1393 -(void)setup; | 1408 -(void)setup; |
1394 -(CGSize)getsize; | 1409 -(CGSize)getsize; |
1395 -(void)setForegroundColor:(UIColor *)input; | 1410 -(void)setForegroundColor:(UIColor *)input; |
1396 -(void)doubleClicked:(id)sender; | 1411 -(void)doubleClicked:(id)sender; |
1397 -(void)keyUp:(UIEvent *)theEvent; | |
1398 -(void)selectionChanged:(id)sender; | 1412 -(void)selectionChanged:(id)sender; |
1399 -(UIMenu *)menuForEvent:(UIEvent *)event; | 1413 -(UIMenu *)menuForEvent:(UIEvent *)event; |
1400 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row; | |
1401 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row; | |
1402 @end | 1414 @end |
1403 | 1415 |
1404 @implementation DWContainer | 1416 @implementation DWContainer |
1405 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable | 1417 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable |
1406 { | 1418 { |
1413 return total / cols; | 1425 return total / cols; |
1414 } | 1426 } |
1415 } | 1427 } |
1416 return 0; | 1428 return 0; |
1417 } | 1429 } |
1430 #if 0 /* TODO: Switch to columnless versions */ | |
1418 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow | 1431 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow |
1419 { | 1432 { |
1420 if(tvcols && data) | 1433 if(tvcols && data) |
1421 { | 1434 { |
1422 int z, col = -1; | 1435 int z, col = -1; |
1441 } | 1454 } |
1442 } | 1455 } |
1443 return nil; | 1456 return nil; |
1444 } | 1457 } |
1445 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { return NO; } | 1458 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { return NO; } |
1459 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row | |
1460 { | |
1461 /* Handle drawing alternating row colors if enabled */ | |
1462 if ((row % 2) == 0) | |
1463 { | |
1464 if(evencolor) | |
1465 [rowView setBackgroundColor:evencolor]; | |
1466 } | |
1467 else | |
1468 { | |
1469 if(oddcolor) | |
1470 [rowView setBackgroundColor:oddcolor]; | |
1471 } | |
1472 } | |
1473 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row; | |
1474 { | |
1475 /* Not reusing cell views, so get the cell from our array */ | |
1476 int index = (int)(row * [tvcols count]) + (int)[tvcols indexOfObject:tableColumn]; | |
1477 id celldata = [data objectAtIndex:index]; | |
1478 | |
1479 /* The data is already a NSTableCellView so just return that */ | |
1480 if([celldata isMemberOfClass:[UITableViewCell class]]) | |
1481 { | |
1482 UITableViewCell *result = celldata; | |
1483 | |
1484 /* Copy the alignment setting from the column, | |
1485 * and set the text color from the container. | |
1486 */ | |
1487 if(@available(iOS 14.0, *)) | |
1488 { | |
1489 UIListContentConfiguration *content = [result defaultContentConfiguration]; | |
1490 | |
1491 if(fgcolor) | |
1492 [[content textProperties] setColor:fgcolor]; | |
1493 } | |
1494 else | |
1495 { | |
1496 if(fgcolor) | |
1497 [result setTextColor:fgcolor]; | |
1498 } | |
1499 /* Return the result */ | |
1500 return result; | |
1501 } | |
1502 return nil; | |
1503 } | |
1504 -(void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn | |
1505 { | |
1506 NSUInteger index = [tvcols indexOfObject:tableColumn]; | |
1507 | |
1508 /* Handler for column click class */ | |
1509 _event_handler(self, (UIEvent *)index, 17); | |
1510 } | |
1511 #endif | |
1446 -(void *)userdata { return userdata; } | 1512 -(void *)userdata { return userdata; } |
1447 -(void)setUserdata:(void *)input { userdata = input; } | 1513 -(void)setUserdata:(void *)input { userdata = input; } |
1448 -(void)setFilesystem:(int)input { filesystem = input; } | 1514 -(void)setFilesystem:(int)input { filesystem = input; } |
1449 -(int)filesystem { return filesystem; } | 1515 -(int)filesystem { return filesystem; } |
1450 -(id)scrollview { return scrollview; } | 1516 -(id)scrollview { return scrollview; } |
1536 [rowdatas addPointer:NULL]; | 1602 [rowdatas addPointer:NULL]; |
1537 } | 1603 } |
1538 return (int)[titles count]; | 1604 return (int)[titles count]; |
1539 } | 1605 } |
1540 return 0; | 1606 return 0; |
1541 } | |
1542 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row | |
1543 { | |
1544 /* Handle drawing alternating row colors if enabled */ | |
1545 if ((row % 2) == 0) | |
1546 { | |
1547 if(evencolor) | |
1548 [rowView setBackgroundColor:evencolor]; | |
1549 } | |
1550 else | |
1551 { | |
1552 if(oddcolor) | |
1553 [rowView setBackgroundColor:oddcolor]; | |
1554 } | |
1555 } | |
1556 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row; | |
1557 { | |
1558 /* Not reusing cell views, so get the cell from our array */ | |
1559 int index = (int)(row * [tvcols count]) + (int)[tvcols indexOfObject:tableColumn]; | |
1560 id celldata = [data objectAtIndex:index]; | |
1561 | |
1562 /* The data is already a NSTableCellView so just return that */ | |
1563 if([celldata isMemberOfClass:[UITableViewCell class]]) | |
1564 { | |
1565 UITableViewCell *result = celldata; | |
1566 | |
1567 /* Copy the alignment setting from the column, | |
1568 * and set the text color from the container. | |
1569 */ | |
1570 if(@available(iOS 14.0, *)) | |
1571 { | |
1572 UIListContentConfiguration *content = [result defaultContentConfiguration]; | |
1573 | |
1574 if(fgcolor) | |
1575 [[content textProperties] setColor:fgcolor]; | |
1576 } | |
1577 else | |
1578 { | |
1579 if(fgcolor) | |
1580 [result setTextColor:fgcolor]; | |
1581 } | |
1582 /* Return the result */ | |
1583 return result; | |
1584 } | |
1585 return nil; | |
1586 } | 1607 } |
1587 -(void)editCell:(id)input at:(int)row and:(int)col | 1608 -(void)editCell:(id)input at:(int)row and:(int)col |
1588 { | 1609 { |
1589 if(tvcols) | 1610 if(tvcols) |
1590 { | 1611 { |
1742 cheight += 16; | 1763 cheight += 16; |
1743 return CGSizeMake(cwidth, cheight); | 1764 return CGSizeMake(cwidth, cheight); |
1744 } | 1765 } |
1745 -(void)setForegroundColor:(UIColor *)input | 1766 -(void)setForegroundColor:(UIColor *)input |
1746 { | 1767 { |
1768 #if 0 /* TODO: Fix this without columns */ | |
1747 int z, count = (int)[tvcols count]; | 1769 int z, count = (int)[tvcols count]; |
1748 | 1770 |
1749 fgcolor = input; | 1771 fgcolor = input; |
1750 [fgcolor retain]; | 1772 [fgcolor retain]; |
1751 | 1773 |
1753 { | 1775 { |
1754 NSTableColumn *tableColumn = [tvcols objectAtIndex:z]; | 1776 NSTableColumn *tableColumn = [tvcols objectAtIndex:z]; |
1755 UITextFieldCell *cell = [tableColumn dataCell]; | 1777 UITextFieldCell *cell = [tableColumn dataCell]; |
1756 [cell setTextColor:fgcolor]; | 1778 [cell setTextColor:fgcolor]; |
1757 } | 1779 } |
1780 #endif | |
1758 } | 1781 } |
1759 -(void)doubleClicked:(id)sender | 1782 -(void)doubleClicked:(id)sender |
1760 { | 1783 { |
1761 void *params[2]; | 1784 void *params[2]; |
1762 | 1785 |
1763 params[0] = (void *)[self getRowTitle:(int)[self selectedRow]]; | 1786 params[0] = (void *)[self getRowTitle:(int)[self indexPathForSelectedRow].row]; |
1764 params[1] = (void *)[self getRowData:(int)[self selectedRow]]; | 1787 params[1] = (void *)[self getRowData:(int)[self indexPathForSelectedRow].row]; |
1765 | 1788 |
1766 /* Handler for container class */ | 1789 /* Handler for container class */ |
1767 _event_handler(self, (UIEvent *)params, 9); | 1790 _event_handler(self, (UIEvent *)params, 9); |
1768 } | 1791 } |
1769 -(void)keyUp:(UIEvent *)theEvent | |
1770 { | |
1771 if([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN) | |
1772 { | |
1773 void *params[2]; | |
1774 | |
1775 params[0] = (void *)[self getRowTitle:(int)[self selectedRow]]; | |
1776 params[1] = (void *)[self getRowData:(int)[self selectedRow]]; | |
1777 | |
1778 _event_handler(self, (UIEvent *)params, 9); | |
1779 } | |
1780 [super keyUp:theEvent]; | |
1781 } | |
1782 | |
1783 -(void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn | |
1784 { | |
1785 NSUInteger index = [tvcols indexOfObject:tableColumn]; | |
1786 | |
1787 /* Handler for column click class */ | |
1788 _event_handler(self, (UIEvent *)index, 17); | |
1789 } | |
1790 -(void)selectionChanged:(id)sender | 1792 -(void)selectionChanged:(id)sender |
1791 { | 1793 { |
1792 void *params[2]; | 1794 void *params[2]; |
1793 | 1795 |
1794 params[0] = (void *)[self getRowTitle:(int)[self selectedRow]]; | 1796 params[0] = (void *)[self getRowTitle:(int)[self indexPathForSelectedRow].row]; |
1795 params[1] = (void *)[self getRowData:(int)[self selectedRow]]; | 1797 params[1] = (void *)[self getRowData:(int)[self indexPathForSelectedRow].row]; |
1796 | 1798 |
1797 /* Handler for container class */ | 1799 /* Handler for container class */ |
1798 _event_handler(self, (UIEvent *)params, 12); | 1800 _event_handler(self, (UIEvent *)params, 12); |
1799 /* Handler for listbox class */ | 1801 /* Handler for listbox class */ |
1800 _event_handler(self, DW_INT_TO_POINTER((int)[self selectedRow]), 11); | 1802 _event_handler(self, DW_INT_TO_POINTER((int)[self indexPathForSelectedRow].row), 11); |
1801 } | 1803 } |
1802 -(UIMenu *)menuForEvent:(UIEvent *)event | 1804 -(UIMenu *)menuForEvent:(UIEvent *)event |
1803 { | 1805 { |
1806 #if 0 /* TODO: Fix this */ | |
1804 int row; | 1807 int row; |
1805 CGPoint where = [self convertPoint:[event locationInWindow] fromView:nil]; | 1808 CGPoint where = [self convertPoint:[event locationInWindow] fromView:nil]; |
1806 row = (int)[self rowAtPoint:where]; | 1809 row = (int)[self rowAtPoint:where]; |
1807 _event_handler(self, (UIEvent *)[self getRowTitle:row], 10); | 1810 _event_handler(self, (UIEvent *)[self getRowTitle:row], 10); |
1811 #endif | |
1808 return nil; | 1812 return nil; |
1809 } | 1813 } |
1810 -(void)keyDown:(UIEvent *)theEvent | |
1811 { | |
1812 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; | |
1813 | |
1814 if(vk == NSTabCharacter || vk == NSBackTabCharacter) | |
1815 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; | |
1816 [super keyDown:theEvent]; | |
1817 } | |
1818 -(void)insertTab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectNextKeyView:self]; } | |
1819 -(void)insertBacktab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectPreviousKeyView:self]; } | |
1820 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } | 1814 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } |
1821 @end | 1815 @end |
1822 | 1816 |
1823 /* Dive into the tree freeing all desired child nodes */ | 1817 /* Dive into the tree freeing all desired child nodes */ |
1824 void _free_tree_recurse(NSMutableArray *node, NSMutableArray *item) | 1818 void _free_tree_recurse(NSMutableArray *node, NSMutableArray *item) |
1946 long val = [[textfield text] intValue]; | 1940 long val = [[textfield text] intValue]; |
1947 [stepper setValue:(float)val]; | 1941 [stepper setValue:(float)val]; |
1948 _event_handler(self, DW_INT_TO_POINTER(val), 14); | 1942 _event_handler(self, DW_INT_TO_POINTER(val), 14); |
1949 } | 1943 } |
1950 -(void)setClickDefault:(id)input { clickDefault = input; } | 1944 -(void)setClickDefault:(id)input { clickDefault = input; } |
1951 -(void)keyUp:(UIEvent *)theEvent | |
1952 { | |
1953 if(clickDefault && [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN) | |
1954 { | |
1955 [[self window] makeFirstResponder:clickDefault]; | |
1956 } | |
1957 else | |
1958 { | |
1959 [super keyUp:theEvent]; | |
1960 } | |
1961 } | |
1962 -(void)performClick:(id)sender { [textfield performClick:sender]; } | |
1963 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } | 1945 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } |
1964 @end | 1946 @end |
1965 | 1947 |
1966 API_AVAILABLE(ios(10.0)) | 1948 API_AVAILABLE(ios(10.0)) |
1967 @interface DWUserNotificationCenterDelegate : NSObject <UNUserNotificationCenterDelegate> | 1949 @interface DWUserNotificationCenterDelegate : NSObject <UNUserNotificationCenterDelegate> |
2323 */ | 2305 */ |
2324 else if([handle isMemberOfClass:[DWScrollBox class]]) | 2306 else if([handle isMemberOfClass:[DWScrollBox class]]) |
2325 { | 2307 { |
2326 int depth = 0; | 2308 int depth = 0; |
2327 DWScrollBox *scrollbox = (DWScrollBox *)handle; | 2309 DWScrollBox *scrollbox = (DWScrollBox *)handle; |
2328 DWBox *contentbox = [scrollbox documentView]; | 2310 DWBox *contentbox = [scrollbox contentView]; |
2329 Box *thisbox = [contentbox box]; | 2311 Box *thisbox = [contentbox box]; |
2330 CGSize contentsize = [scrollbox contentSize]; | 2312 CGSize contentsize = [scrollbox contentSize]; |
2331 | 2313 |
2332 /* Get the required space for the box */ | 2314 /* Get the required space for the box */ |
2333 _resize_box(thisbox, &depth, x, y, 1); | 2315 _resize_box(thisbox, &depth, x, y, 1); |
2350 else if([handle isMemberOfClass:[DWSpinButton class]]) | 2332 else if([handle isMemberOfClass:[DWSpinButton class]]) |
2351 { | 2333 { |
2352 DWSpinButton *spinbutton = (DWSpinButton *)handle; | 2334 DWSpinButton *spinbutton = (DWSpinButton *)handle; |
2353 UITextField *textfield = [spinbutton textfield]; | 2335 UITextField *textfield = [spinbutton textfield]; |
2354 UIStepper *stepper = [spinbutton stepper]; | 2336 UIStepper *stepper = [spinbutton stepper]; |
2355 [textfield setFrameOrigin:NSMakePoint(0,0)]; | 2337 [textfield setFrameOrigin:CGPointMake(0,0)]; |
2356 [textfield setFrameSize:NSMakeSize(size.width-20,size.height)]; | 2338 [textfield setFrameSize:CGSizeMake(size.width-20,size.height)]; |
2357 [stepper setFrameOrigin:NSMakePoint(size.width-20,0)]; | 2339 [stepper setFrameOrigin:CGPointMake(size.width-20,0)]; |
2358 [stepper setFrameSize:NSMakeSize(20,size.height)]; | 2340 [stepper setFrameSize:CGSizeMake(20,size.height)]; |
2359 } | 2341 } |
2360 else if([handle isMemberOfClass:[DWSplitBar class]]) | 2342 else if([handle isMemberOfClass:[DWSplitBar class]]) |
2361 { | 2343 { |
2362 DWSplitBar *split = (DWSplitBar *)handle; | 2344 DWSplitBar *split = (DWSplitBar *)handle; |
2363 DWWindow *window = (DWWindow *)[split window]; | 2345 DWWindow *window = (DWWindow *)[split window]; |
2417 * Causes running dw_main() to return. | 2399 * Causes running dw_main() to return. |
2418 */ | 2400 */ |
2419 void API dw_main_quit(void) | 2401 void API dw_main_quit(void) |
2420 { | 2402 { |
2421 [DWApp stop:nil]; | 2403 [DWApp stop:nil]; |
2422 _dw_wakeup_app(); | |
2423 } | 2404 } |
2424 | 2405 |
2425 /* | 2406 /* |
2426 * Runs a message loop for Dynamic Windows, for a period of milliseconds. | 2407 * Runs a message loop for Dynamic Windows, for a period of milliseconds. |
2427 * Parameters: | 2408 * Parameters: |
2457 } | 2438 } |
2458 | 2439 |
2459 /* Internal version that doesn't lock the run mutex */ | 2440 /* Internal version that doesn't lock the run mutex */ |
2460 int _dw_main_iteration(NSDate *date) | 2441 int _dw_main_iteration(NSDate *date) |
2461 { | 2442 { |
2462 UIEvent *event = [DWApp nextEventMatchingMask:DWEventMaskAny | 2443 UIEvent *event = [DWApp nextEventMatchingMask:UIEventMaskAny |
2463 untilDate:date | 2444 untilDate:date |
2464 inMode:NSDefaultRunLoopMode | 2445 inMode:NSDefaultRunLoopMode |
2465 dequeue:YES]; | 2446 dequeue:YES]; |
2466 if(event) | 2447 if(event) |
2467 { | 2448 { |
2468 [DWApp sendEvent:event]; | 2449 [DWApp sendEvent:event]; |
2469 [DWApp updateWindows]; | |
2470 return 1; | 2450 return 1; |
2471 } | 2451 } |
2472 return 0; | 2452 return 0; |
2473 } | 2453 } |
2474 | 2454 |
2606 NSString *button1 = @"OK"; | 2586 NSString *button1 = @"OK"; |
2607 NSString *button2 = nil; | 2587 NSString *button2 = nil; |
2608 NSString *button3 = nil; | 2588 NSString *button3 = nil; |
2609 NSString *mtitle = [NSString stringWithUTF8String:title]; | 2589 NSString *mtitle = [NSString stringWithUTF8String:title]; |
2610 NSString *mtext; | 2590 NSString *mtext; |
2611 NSAlertStyle mstyle = DWAlertStyleWarning; | 2591 UIAlertControllerStyle mstyle = UIAlertControllerStyleAlert; |
2612 NSArray *params; | 2592 NSArray *params; |
2613 va_list args; | 2593 va_list args; |
2614 | 2594 |
2615 if(flags & DW_MB_OKCANCEL) | 2595 if(flags & DW_MB_OKCANCEL) |
2616 { | 2596 { |
2630 | 2610 |
2631 va_start(args, format); | 2611 va_start(args, format); |
2632 mtext = [[[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:args] autorelease]; | 2612 mtext = [[[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:args] autorelease]; |
2633 va_end(args); | 2613 va_end(args); |
2634 | 2614 |
2635 if(flags & DW_MB_ERROR) | 2615 if(flags & DW_MB_INFORMATION) |
2636 mstyle = DWAlertStyleCritical; | 2616 mstyle = UIAlertControllerStyleActionSheet; |
2637 else if(flags & DW_MB_INFORMATION) | |
2638 mstyle = DWAlertStyleInformational; | |
2639 | 2617 |
2640 params = [NSMutableArray arrayWithObjects:mtitle, mtext, [NSNumber numberWithInteger:mstyle], button1, button2, button3, nil]; | 2618 params = [NSMutableArray arrayWithObjects:mtitle, mtext, [NSNumber numberWithInteger:mstyle], button1, button2, button3, nil]; |
2641 [DWObj safeCall:@selector(messageBox:) withObject:params]; | 2619 [DWObj safeCall:@selector(messageBox:) withObject:params]; |
2642 iResponse = [[params lastObject] integerValue]; | 2620 iResponse = [[params lastObject] integerValue]; |
2643 | 2621 |
2644 switch(iResponse) | 2622 switch(iResponse) |
2645 { | 2623 { |
2646 case NSAlertFirstButtonReturn: /* user pressed OK */ | 2624 case 1: /* user pressed OK */ |
2647 if(flags & DW_MB_YESNO || flags & DW_MB_YESNOCANCEL) | 2625 if(flags & DW_MB_YESNO || flags & DW_MB_YESNOCANCEL) |
2648 { | 2626 { |
2649 return DW_MB_RETURN_YES; | 2627 return DW_MB_RETURN_YES; |
2650 } | 2628 } |
2651 return DW_MB_RETURN_OK; | 2629 return DW_MB_RETURN_OK; |
2652 case NSAlertSecondButtonReturn: /* user pressed Cancel */ | 2630 case 2: /* user pressed Cancel */ |
2653 if(flags & DW_MB_OKCANCEL) | 2631 if(flags & DW_MB_OKCANCEL) |
2654 { | 2632 { |
2655 return DW_MB_RETURN_CANCEL; | 2633 return DW_MB_RETURN_CANCEL; |
2656 } | 2634 } |
2657 return DW_MB_RETURN_NO; | 2635 return DW_MB_RETURN_NO; |
2658 case NSAlertThirdButtonReturn: /* user pressed the third button */ | 2636 case 3: /* user pressed the third button */ |
2659 return DW_MB_RETURN_CANCEL; | 2637 return DW_MB_RETURN_CANCEL; |
2660 } | 2638 } |
2661 return 0; | 2639 return 0; |
2662 } | 2640 } |
2663 | 2641 |
2673 * the file path on success. | 2651 * the file path on success. |
2674 * | 2652 * |
2675 */ | 2653 */ |
2676 char * API dw_file_browse(const char *title, const char *defpath, const char *ext, int flags) | 2654 char * API dw_file_browse(const char *title, const char *defpath, const char *ext, int flags) |
2677 { | 2655 { |
2678 char temp[PATH_MAX+1]; | |
2679 char *file = NULL, *path = NULL; | |
2680 DW_LOCAL_POOL_IN; | |
2681 | |
2682 /* Figure out path information... | |
2683 * These functions are only support in Snow Leopard and later... | |
2684 */ | |
2685 if(defpath && *defpath && (DWOSMinor > 5 || DWOSMajor > 10)) | |
2686 { | |
2687 struct stat buf; | |
2688 | |
2689 /* Get an absolute path */ | |
2690 if(!realpath(defpath, temp)) | |
2691 strcpy(temp, defpath); | |
2692 | |
2693 /* Check if the defpath exists */ | |
2694 if(stat(temp, &buf) == 0) | |
2695 { | |
2696 /* Can be a directory or file */ | |
2697 if(buf.st_mode & S_IFDIR) | |
2698 path = temp; | |
2699 else | |
2700 file = temp; | |
2701 } | |
2702 /* If it wasn't a directory... check if there is a path */ | |
2703 if(!path && strchr(temp, '/')) | |
2704 { | |
2705 unsigned long x = strlen(temp) - 1; | |
2706 | |
2707 /* Trim off the filename */ | |
2708 while(x > 0 && temp[x] != '/') | |
2709 { | |
2710 x--; | |
2711 } | |
2712 if(temp[x] == '/') | |
2713 { | |
2714 temp[x] = 0; | |
2715 /* Check to make sure the trimmed piece is a directory */ | |
2716 if(stat(temp, &buf) == 0) | |
2717 { | |
2718 if(buf.st_mode & S_IFDIR) | |
2719 { | |
2720 /* We now have it split */ | |
2721 path = temp; | |
2722 file = &temp[x+1]; | |
2723 } | |
2724 } | |
2725 } | |
2726 } | |
2727 } | |
2728 | |
2729 if(flags == DW_FILE_OPEN || flags == DW_DIRECTORY_OPEN) | |
2730 { | |
2731 /* Create the File Open Dialog class. */ | |
2732 NSOpenPanel* openDlg = [NSOpenPanel openPanel]; | |
2733 | |
2734 if(path) | |
2735 { | |
2736 SEL ssdu = NSSelectorFromString(@"setDirectoryURL"); | |
2737 | |
2738 if([openDlg respondsToSelector:ssdu]) | |
2739 { | |
2740 DWIMP isdu = (DWIMP)[openDlg methodForSelector:ssdu]; | |
2741 isdu(openDlg, ssdu, [NSURL fileURLWithPath:[NSString stringWithUTF8String:path]]); | |
2742 } | |
2743 } | |
2744 | |
2745 /* Enable the selection of files in the dialog. */ | |
2746 if(flags == DW_FILE_OPEN) | |
2747 { | |
2748 [openDlg setCanChooseFiles:YES]; | |
2749 [openDlg setCanChooseDirectories:NO]; | |
2750 } | |
2751 else | |
2752 { | |
2753 [openDlg setCanChooseFiles:NO]; | |
2754 [openDlg setCanChooseDirectories:YES]; | |
2755 } | |
2756 | |
2757 /* Handle file types */ | |
2758 if(ext && *ext) | |
2759 { | |
2760 NSArray* fileTypes = [[[NSArray alloc] initWithObjects:[NSString stringWithUTF8String:ext], nil] autorelease]; | |
2761 [openDlg setAllowedFileTypes:fileTypes]; | |
2762 } | |
2763 | |
2764 /* Disable multiple selection */ | |
2765 [openDlg setAllowsMultipleSelection:NO]; | |
2766 | |
2767 /* Display the dialog. If the OK button was pressed, | |
2768 * process the files. | |
2769 */ | |
2770 if([openDlg runModal] == DWModalResponseOK) | |
2771 { | |
2772 /* Get an array containing the full filenames of all | |
2773 * files and directories selected. | |
2774 */ | |
2775 NSArray *files = [openDlg URLs]; | |
2776 NSString *fileName = [[files objectAtIndex:0] path]; | |
2777 if(fileName) | |
2778 { | |
2779 char *ret = strdup([ fileName UTF8String ]); | |
2780 DW_LOCAL_POOL_OUT; | |
2781 return ret; | |
2782 } | |
2783 } | |
2784 } | |
2785 else | |
2786 { | |
2787 /* Create the File Save Dialog class. */ | |
2788 NSSavePanel* saveDlg = [NSSavePanel savePanel]; | |
2789 | |
2790 if(path) | |
2791 { | |
2792 SEL ssdu = NSSelectorFromString(@"setDirectoryURL"); | |
2793 | |
2794 if([saveDlg respondsToSelector:ssdu]) | |
2795 { | |
2796 DWIMP isdu = (DWIMP)[saveDlg methodForSelector:ssdu]; | |
2797 isdu(saveDlg, ssdu, [NSURL fileURLWithPath:[NSString stringWithUTF8String:path]]); | |
2798 } | |
2799 } | |
2800 if(file) | |
2801 { | |
2802 SEL ssnfsv = NSSelectorFromString(@"setNameFieldStringValue"); | |
2803 | |
2804 if([saveDlg respondsToSelector:ssnfsv]) | |
2805 { | |
2806 DWIMP isnfsv = (DWIMP)[saveDlg methodForSelector:ssnfsv]; | |
2807 isnfsv(saveDlg, ssnfsv, [NSString stringWithUTF8String:file]); | |
2808 } | |
2809 } | |
2810 | |
2811 /* Enable the creation of directories in the dialog. */ | |
2812 [saveDlg setCanCreateDirectories:YES]; | |
2813 | |
2814 /* Handle file types */ | |
2815 if(ext && *ext) | |
2816 { | |
2817 NSArray* fileTypes = [[[NSArray alloc] initWithObjects:[NSString stringWithUTF8String:ext], nil] autorelease]; | |
2818 [saveDlg setAllowedFileTypes:fileTypes]; | |
2819 } | |
2820 | |
2821 /* Display the dialog. If the OK button was pressed, | |
2822 * process the files. | |
2823 */ | |
2824 if([saveDlg runModal] == DWModalResponseOK) | |
2825 { | |
2826 /* Get an array containing the full filenames of all | |
2827 * files and directories selected. | |
2828 */ | |
2829 NSString* fileName = [[saveDlg URL] path]; | |
2830 if(fileName) | |
2831 { | |
2832 char *ret = strdup([ fileName UTF8String ]); | |
2833 DW_LOCAL_POOL_OUT; | |
2834 return ret; | |
2835 } | |
2836 } | |
2837 } | |
2838 DW_LOCAL_POOL_OUT; | |
2839 return NULL; | 2656 return NULL; |
2840 } | 2657 } |
2841 | 2658 |
2842 /* | 2659 /* |
2843 * Gets the contents of the default clipboard as text. | 2660 * Gets the contents of the default clipboard as text. |
2847 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not | 2664 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not |
2848 * be converted to text. | 2665 * be converted to text. |
2849 */ | 2666 */ |
2850 char *dw_clipboard_get_text() | 2667 char *dw_clipboard_get_text() |
2851 { | 2668 { |
2852 NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; | 2669 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; |
2853 NSString *str = [pasteboard stringForType:DWPasteboardTypeString]; | 2670 NSString *str = [pasteboard string]; |
2854 if(str != nil) | 2671 if(str != nil) |
2855 { | 2672 return strdup([str UTF8String]); |
2856 return strdup([ str UTF8String ]); | |
2857 } | |
2858 return NULL; | 2673 return NULL; |
2859 } | 2674 } |
2860 | 2675 |
2861 /* | 2676 /* |
2862 * Sets the contents of the default clipboard to the supplied text. | 2677 * Sets the contents of the default clipboard to the supplied text. |
2863 * Parameters: | 2678 * Parameters: |
2864 * Text. | 2679 * Text. |
2865 */ | 2680 */ |
2866 void dw_clipboard_set_text(const char *str, int len) | 2681 void dw_clipboard_set_text(const char *str, int len) |
2867 { | 2682 { |
2868 NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; | 2683 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; |
2869 SEL scc = NSSelectorFromString(@"clearContents"); | 2684 |
2870 | 2685 [pasteboard setString:[NSString stringWithUTF8String:str]]; |
2871 if([pasteboard respondsToSelector:scc]) | |
2872 { | |
2873 DWIMP icc = (DWIMP)[pasteboard methodForSelector:scc]; | |
2874 icc(pasteboard, scc); | |
2875 } | |
2876 | |
2877 [pasteboard setString:[ NSString stringWithUTF8String:str ] forType:DWPasteboardTypeString]; | |
2878 } | 2686 } |
2879 | 2687 |
2880 | 2688 |
2881 /* | 2689 /* |
2882 * Allocates and initializes a dialog struct. | 2690 * Allocates and initializes a dialog struct. |
4315 int result = -1; | 4123 int result = -1; |
4316 | 4124 |
4317 if([object isMemberOfClass:[DWContainer class]]) | 4125 if([object isMemberOfClass:[DWContainer class]]) |
4318 { | 4126 { |
4319 DWContainer *cont = handle; | 4127 DWContainer *cont = handle; |
4320 result = (int)[cont selectedRow]; | 4128 result = (int)[cont indexPathForSelectedRow].row; |
4321 } | 4129 } |
4322 DW_FUNCTION_RETURN_THIS(result); | 4130 DW_FUNCTION_RETURN_THIS(result); |
4323 } | 4131 } |
4324 | 4132 |
4325 /* | 4133 /* |
4339 | 4147 |
4340 if([object isMemberOfClass:[DWContainer class]]) | 4148 if([object isMemberOfClass:[DWContainer class]]) |
4341 { | 4149 { |
4342 NSUInteger result; | 4150 NSUInteger result; |
4343 DWContainer *cont = handle; | 4151 DWContainer *cont = handle; |
4344 NSIndexSet *selected = [cont selectedRowIndexes]; | 4152 NSArray *selected = [cont indexPathsForSelectedRows]; |
4345 if( where == -1 ) | 4153 if(where == -1) |
4346 result = [selected indexGreaterThanOrEqualToIndex:0]; | 4154 result = [selected objectAtIndex:0]; |
4347 else | 4155 else |
4348 result = [selected indexGreaterThanIndex:where]; | 4156 result = [selected objectAtIndex:where]; |
4349 | 4157 |
4350 if(result != NSNotFound) | 4158 if(result) |
4351 { | 4159 { |
4352 retval = (int)result; | 4160 retval = (int)result; |
4353 } | 4161 } |
4354 } | 4162 } |
4355 DW_FUNCTION_RETURN_THIS(retval) | 4163 DW_FUNCTION_RETURN_THIS(retval) |
6141 DW_FUNCTION_RETURN(dw_container_query_start, char *) | 5949 DW_FUNCTION_RETURN(dw_container_query_start, char *) |
6142 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long) | 5950 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long) |
6143 { | 5951 { |
6144 DW_FUNCTION_INIT; | 5952 DW_FUNCTION_INIT; |
6145 DWContainer *cont = handle; | 5953 DWContainer *cont = handle; |
6146 NSIndexSet *selected = [cont selectedRowIndexes]; | 5954 NSArray *selected = [cont indexPathsForSelectedRows]; |
6147 NSUInteger result = [selected indexGreaterThanOrEqualToIndex:0]; | 5955 NSIndexPath *result = [selected objectAtIndex:0]; |
6148 void *retval = NULL; | 5956 void *retval = NULL; |
6149 | 5957 |
6150 if(result != NSNotFound) | 5958 if(result) |
6151 { | 5959 { |
6152 if(flags & DW_CR_RETDATA) | 5960 if(flags & DW_CR_RETDATA) |
6153 retval = [cont getRowData:(int)result]; | 5961 retval = [cont getRowData:(int)result.row]; |
6154 else | 5962 else |
6155 { | 5963 { |
6156 char *temp = [cont getRowTitle:(int)result]; | 5964 char *temp = [cont getRowTitle:(int)result.row]; |
6157 if(temp) | 5965 if(temp) |
6158 retval = strdup(temp); | 5966 retval = strdup(temp); |
6159 } | 5967 } |
6160 [cont setLastQueryPoint:(int)result]; | 5968 [cont setLastQueryPoint:1]; |
6161 } | 5969 } |
6162 DW_FUNCTION_RETURN_THIS(retval); | 5970 DW_FUNCTION_RETURN_THIS(retval); |
6163 } | 5971 } |
6164 | 5972 |
6165 /* | 5973 /* |
6176 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long) | 5984 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long) |
6177 { | 5985 { |
6178 DW_FUNCTION_INIT; | 5986 DW_FUNCTION_INIT; |
6179 DWContainer *cont = handle; | 5987 DWContainer *cont = handle; |
6180 int lastQueryPoint = [cont lastQueryPoint]; | 5988 int lastQueryPoint = [cont lastQueryPoint]; |
6181 NSIndexSet *selected = [cont selectedRowIndexes]; | 5989 NSArray *selected = [cont indexPathsForSelectedRows]; |
6182 NSUInteger result = [selected indexGreaterThanIndex:lastQueryPoint]; | 5990 NSIndexPath *result = [selected objectAtIndex:lastQueryPoint]; |
6183 void *retval = NULL; | 5991 void *retval = NULL; |
6184 | 5992 |
6185 if(result != NSNotFound) | 5993 if(result) |
6186 { | 5994 { |
6187 if(flags & DW_CR_RETDATA) | 5995 if(flags & DW_CR_RETDATA) |
6188 retval = [cont getRowData:(int)result]; | 5996 retval = [cont getRowData:(int)result.row]; |
6189 else | 5997 else |
6190 { | 5998 { |
6191 char *temp = [cont getRowTitle:(int)result]; | 5999 char *temp = [cont getRowTitle:(int)result.row]; |
6192 if(temp) | 6000 if(temp) |
6193 retval = strdup(temp); | 6001 retval = strdup(temp); |
6194 } | 6002 } |
6195 [cont setLastQueryPoint:(int)result]; | 6003 [cont setLastQueryPoint:(int)lastQueryPoint+1]; |
6196 } | 6004 } |
6197 DW_FUNCTION_RETURN_THIS(retval); | 6005 DW_FUNCTION_RETURN_THIS(retval); |
6198 } | 6006 } |
6199 | 6007 |
6200 /* | 6008 /* |
10241 pool = [[NSAutoreleasePool alloc] init]; | 10049 pool = [[NSAutoreleasePool alloc] init]; |
10242 pthread_setspecific(_dw_pool_key, pool); | 10050 pthread_setspecific(_dw_pool_key, pool); |
10243 pthread_key_create(&_dw_fg_color_key, NULL); | 10051 pthread_key_create(&_dw_fg_color_key, NULL); |
10244 pthread_key_create(&_dw_bg_color_key, NULL); | 10052 pthread_key_create(&_dw_bg_color_key, NULL); |
10245 _init_colors(); | 10053 _init_colors(); |
10246 /* Create a default main menu, with just the application menu */ | |
10247 DWMainMenu = _generate_main_menu(); | |
10248 [DWMainMenu retain]; | |
10249 [DWApp setMainMenu:DWMainMenu]; | |
10250 DWObj = [[DWObject alloc] init]; | 10054 DWObj = [[DWObject alloc] init]; |
10251 DWDefaultFont = nil; | 10055 DWDefaultFont = nil; |
10252 DWFontManager = [UIFontManager sharedFontManager]; | |
10253 if (@available(iOS 10.0, *)) | 10056 if (@available(iOS 10.0, *)) |
10254 { | 10057 { |
10255 if([[NSBundle mainBundle] bundleIdentifier] != nil) | 10058 if([[NSBundle mainBundle] bundleIdentifier] != nil) |
10256 { | 10059 { |
10257 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; | 10060 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; |
10426 DWTID dw_thread_id(void) | 10229 DWTID dw_thread_id(void) |
10427 { | 10230 { |
10428 return (DWTID)pthread_self(); | 10231 return (DWTID)pthread_self(); |
10429 } | 10232 } |
10430 | 10233 |
10431 NSURL *_dw_url_from_program(NSString *nsprogram, NSWorkspace *ws) | |
10432 { | |
10433 NSURL *retval = [ws URLForApplicationWithBundleIdentifier:nsprogram]; | |
10434 return retval; | |
10435 } | |
10436 | |
10437 /* | 10234 /* |
10438 * Execute and external program in a seperate session. | 10235 * Execute and external program in a seperate session. |
10439 * Parameters: | 10236 * Parameters: |
10440 * program: Program name with optional path. | 10237 * program: Program name with optional path. |
10441 * type: Either DW_EXEC_CON or DW_EXEC_GUI. | 10238 * type: Either DW_EXEC_CON or DW_EXEC_GUI. |
10445 */ | 10242 */ |
10446 int dw_exec(const char *program, int type, char **params) | 10243 int dw_exec(const char *program, int type, char **params) |
10447 { | 10244 { |
10448 int ret = DW_ERROR_UNKNOWN; | 10245 int ret = DW_ERROR_UNKNOWN; |
10449 | 10246 |
10247 #if 0 /* TODO: Figure out how to do this on iOS */ | |
10450 if(type == DW_EXEC_GUI) | 10248 if(type == DW_EXEC_GUI) |
10451 { | 10249 { |
10452 NSString *nsprogram = [NSString stringWithUTF8String:program]; | 10250 NSString *nsprogram = [NSString stringWithUTF8String:program]; |
10453 NSWorkspace *ws = [NSWorkspace sharedWorkspace]; | 10251 NSWorkspace *ws = [NSWorkspace sharedWorkspace]; |
10454 | 10252 |
10498 dw_dialog_dismiss(dialog, DW_INT_TO_POINTER(pid)); | 10296 dw_dialog_dismiss(dialog, DW_INT_TO_POINTER(pid)); |
10499 }]; | 10297 }]; |
10500 ret = DW_POINTER_TO_INT(dw_dialog_wait(dialog)); | 10298 ret = DW_POINTER_TO_INT(dw_dialog_wait(dialog)); |
10501 } | 10299 } |
10502 } | 10300 } |
10301 #endif | |
10503 return ret; | 10302 return ret; |
10504 } | 10303 } |
10505 | 10304 |
10506 /* | 10305 /* |
10507 * Loads a web browser pointed at the given URL. | 10306 * Loads a web browser pointed at the given URL. |
10509 * url: Uniform resource locator. | 10308 * url: Uniform resource locator. |
10510 */ | 10309 */ |
10511 int dw_browse(const char *url) | 10310 int dw_browse(const char *url) |
10512 { | 10311 { |
10513 NSURL *myurl = [NSURL URLWithString:[NSString stringWithUTF8String:url]]; | 10312 NSURL *myurl = [NSURL URLWithString:[NSString stringWithUTF8String:url]]; |
10514 [[NSWorkspace sharedWorkspace] openURL:myurl]; | 10313 [DWApp openURL:myurl options:@{} |
10314 completionHandler:^(BOOL success) {}]; | |
10515 return DW_ERROR_NONE; | 10315 return DW_ERROR_NONE; |
10516 } | 10316 } |
10517 | |
10518 typedef struct _dwprint | |
10519 { | |
10520 NSPrintInfo *pi; | |
10521 int (*drawfunc)(HPRINT, HPIXMAP, int, void *); | |
10522 void *drawdata; | |
10523 unsigned long flags; | |
10524 } DWPrint; | |
10525 | 10317 |
10526 /* | 10318 /* |
10527 * Creates a new print object. | 10319 * Creates a new print object. |
10528 * Parameters: | 10320 * Parameters: |
10529 * jobname: Name of the print job to show in the queue. | 10321 * jobname: Name of the print job to show in the queue. |
10534 * Returns: | 10326 * Returns: |
10535 * A handle to the print object or NULL on failure. | 10327 * A handle to the print object or NULL on failure. |
10536 */ | 10328 */ |
10537 HPRINT API dw_print_new(const char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata) | 10329 HPRINT API dw_print_new(const char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata) |
10538 { | 10330 { |
10539 DWPrint *print; | 10331 return NULL; |
10540 NSPrintPanel *panel; | |
10541 PMPrintSettings settings; | |
10542 NSPrintInfo *pi; | |
10543 | |
10544 if(!drawfunc || !(print = calloc(1, sizeof(DWPrint)))) | |
10545 { | |
10546 return NULL; | |
10547 } | |
10548 | |
10549 if(!jobname) | |
10550 jobname = "Dynamic Windows Print Job"; | |
10551 | |
10552 print->drawfunc = drawfunc; | |
10553 print->drawdata = drawdata; | |
10554 print->flags = flags; | |
10555 | |
10556 /* Get the page range */ | |
10557 pi = [NSPrintInfo sharedPrintInfo]; | |
10558 [pi setHorizontalPagination:DWPrintingPaginationModeFit]; | |
10559 [pi setHorizontallyCentered:YES]; | |
10560 [pi setVerticalPagination:DWPrintingPaginationModeFit]; | |
10561 [pi setVerticallyCentered:YES]; | |
10562 [pi setOrientation:DWPaperOrientationPortrait]; | |
10563 [pi setLeftMargin:0.0]; | |
10564 [pi setRightMargin:0.0]; | |
10565 [pi setTopMargin:0.0]; | |
10566 [pi setBottomMargin:0.0]; | |
10567 | |
10568 settings = [pi PMPrintSettings]; | |
10569 PMSetPageRange(settings, 1, pages); | |
10570 PMSetFirstPage(settings, 1, true); | |
10571 PMSetLastPage(settings, pages, true); | |
10572 PMPrintSettingsSetJobName(settings, (CFStringRef)[NSString stringWithUTF8String:jobname]); | |
10573 [pi updateFromPMPrintSettings]; | |
10574 | |
10575 /* Create and show the print panel */ | |
10576 panel = [NSPrintPanel printPanel]; | |
10577 if(!panel || [panel runModalWithPrintInfo:pi] == DWModalResponseCancel) | |
10578 { | |
10579 free(print); | |
10580 return NULL; | |
10581 } | |
10582 /* Put the print info from the panel into the operation */ | |
10583 print->pi = pi; | |
10584 | |
10585 return print; | |
10586 } | 10332 } |
10587 | 10333 |
10588 /* | 10334 /* |
10589 * Runs the print job, causing the draw page callbacks to fire. | 10335 * Runs the print job, causing the draw page callbacks to fire. |
10590 * Parameters: | 10336 * Parameters: |
10593 * Returns: | 10339 * Returns: |
10594 * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success. | 10340 * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success. |
10595 */ | 10341 */ |
10596 int API dw_print_run(HPRINT print, unsigned long flags) | 10342 int API dw_print_run(HPRINT print, unsigned long flags) |
10597 { | 10343 { |
10598 DWPrint *p = print; | 10344 return DW_ERROR_UNKNOWN; |
10599 UIImage *rep, *rep2; | |
10600 NSPrintInfo *pi; | |
10601 NSPrintOperation *po; | |
10602 HPIXMAP pixmap, pixmap2; | |
10603 UIImage *image, *flipped; | |
10604 UIImageView *iv; | |
10605 CGSize size; | |
10606 PMPrintSettings settings; | |
10607 int x, result = DW_ERROR_UNKNOWN; | |
10608 UInt32 start, end; | |
10609 | |
10610 if(!p) | |
10611 return result; | |
10612 | |
10613 DW_LOCAL_POOL_IN; | |
10614 | |
10615 /* Figure out the printer/paper size */ | |
10616 pi = p->pi; | |
10617 size = [pi paperSize]; | |
10618 | |
10619 /* Get the page range */ | |
10620 settings = [pi PMPrintSettings]; | |
10621 PMGetFirstPage(settings, &start); | |
10622 if(start > 0) | |
10623 start--; | |
10624 PMGetLastPage(settings, &end); | |
10625 PMSetPageRange(settings, 1, 1); | |
10626 PMSetFirstPage(settings, 1, true); | |
10627 PMSetLastPage(settings, 1, true); | |
10628 [pi updateFromPMPrintSettings]; | |
10629 | |
10630 /* Create an image view to print and a pixmap to draw into */ | |
10631 iv = [[UIImageView alloc] init]; | |
10632 pixmap = dw_pixmap_new(iv, (int)size.width, (int)size.height, 8); | |
10633 rep = pixmap->image; | |
10634 pixmap2 = dw_pixmap_new(iv, (int)size.width, (int)size.height, 8); | |
10635 rep2 = pixmap2->image; | |
10636 | |
10637 /* Create an image with the data from the pixmap | |
10638 * to go into the image view. | |
10639 */ | |
10640 image = [[UIImage alloc] initWithSize:[rep size]]; | |
10641 flipped = [[UIImage alloc] initWithSize:[rep size]]; | |
10642 [image addRepresentation:rep]; | |
10643 [flipped addRepresentation:rep2]; | |
10644 [iv setImage:flipped]; | |
10645 [iv setImageScaling:UIImageScaleProportionallyDown]; | |
10646 [iv setFrameOrigin:NSMakePoint(0,0)]; | |
10647 [iv setFrameSize:size]; | |
10648 | |
10649 /* Create the print operation using the image view and | |
10650 * print info obtained from the panel in the last call. | |
10651 */ | |
10652 po = [NSPrintOperation printOperationWithView:iv printInfo:pi]; | |
10653 [po setShowsPrintPanel:NO]; | |
10654 | |
10655 /* Cycle through each page */ | |
10656 for(x=start; x<end && p->drawfunc; x++) | |
10657 { | |
10658 /* Call the application's draw function */ | |
10659 p->drawfunc(print, pixmap, x, p->drawdata); | |
10660 if(p->drawfunc) | |
10661 { | |
10662 /* Internal representation is flipped... so flip again so we can print */ | |
10663 _flip_image(image, rep2, size); | |
10664 #ifdef DEBUG_PRINT | |
10665 /* Save it to file to see what we have */ | |
10666 NSData *data = [rep2 representationUsingType: NSPNGFileType properties: nil]; | |
10667 [data writeToFile: @"print.png" atomically: NO]; | |
10668 #endif | |
10669 /* Print the image view */ | |
10670 [po runOperation]; | |
10671 /* Fill the pixmap with white in case we are printing more pages */ | |
10672 dw_color_foreground_set(DW_CLR_WHITE); | |
10673 dw_draw_rect(0, pixmap, TRUE, 0, 0, (int)size.width, (int)size.height); | |
10674 } | |
10675 } | |
10676 if(p->drawfunc) | |
10677 result = DW_ERROR_NONE; | |
10678 /* Free memory */ | |
10679 [image release]; | |
10680 [flipped release]; | |
10681 dw_pixmap_destroy(pixmap); | |
10682 dw_pixmap_destroy(pixmap2); | |
10683 free(p); | |
10684 [iv release]; | |
10685 DW_LOCAL_POOL_OUT; | |
10686 return result; | |
10687 } | 10345 } |
10688 | 10346 |
10689 /* | 10347 /* |
10690 * Cancels the print job, typically called from a draw page callback. | 10348 * Cancels the print job, typically called from a draw page callback. |
10691 * Parameters: | 10349 * Parameters: |
10692 * print: Handle to the print object returned by dw_print_new(). | 10350 * print: Handle to the print object returned by dw_print_new(). |
10693 */ | 10351 */ |
10694 void API dw_print_cancel(HPRINT print) | 10352 void API dw_print_cancel(HPRINT print) |
10695 { | 10353 { |
10696 DWPrint *p = print; | |
10697 | |
10698 if(p) | |
10699 p->drawfunc = NULL; | |
10700 } | 10354 } |
10701 | 10355 |
10702 /* | 10356 /* |
10703 * Converts a UTF-8 encoded string into a wide string. | 10357 * Converts a UTF-8 encoded string into a wide string. |
10704 * Parameters: | 10358 * Parameters: |