11#if !__has_feature(objc_arc)
12#error This file must be compiled with Arc. Use -fobjc-arc flag
15#import <QuartzCore/QuartzCore.h>
16#import <Metal/Metal.h>
17#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
19#import "IGraphicsIOS_view.h"
21#include "IGraphicsCoreText.h"
25extern StaticStorage<CoreTextFontDescriptor> sFontDescriptorCache;
27@implementation IGRAPHICS_UITABLEVC
29- (int) menuIndexFromIndexPath: (NSIndexPath*) indexPath
31 return [
self.items[indexPath.row][1] intValue];
37 self.tableView = [[UITableView alloc] initWithFrame:self.view.frame];
38 self.tableView.dataSource = self;
39 self.tableView.delegate = self;
40 self.tableView.scrollEnabled = YES;
41 self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
42 self.items = [[NSMutableArray alloc] init];
44 int numItems = mMenu->NItems();
46 NSMutableString* elementTitle;
48 for (
int i = 0; i < numItems; ++i)
52 elementTitle = [[NSMutableString alloc] initWithUTF8String: pMenuItem->GetText()];
54 if (mMenu->GetPrefix())
56 NSString* prefixString = nil;
58 switch (mMenu->GetPrefix())
60 case 1: prefixString = [NSString stringWithFormat:
@"%1d: ", i+1]; break;
61 case 2: prefixString = [NSString stringWithFormat:
@"%02d: ", i+1]; break;
62 case 3: prefixString = [NSString stringWithFormat:
@"%03d: ", i+1]; break;
65 prefixString = [NSString stringWithUTF8String:
""]; break;
68 [elementTitle insertString:prefixString atIndex:0];
71 [
self.items addObject: @[elementTitle, [NSNumber numberWithInt:i]]];
74 [
self.view addSubview:self.tableView];
81 mGraphics = pGraphics;
87- (NSInteger) tableView: (UITableView*) tableView numberOfRowsInSection : (NSInteger) section
89 return self.items.count;
92- (NSInteger) numberOfSectionsInTableView: (UITableView*) tableView
97- (UITableViewCell*) tableView: (UITableView*) tableView cellForRowAtIndexPath: (NSIndexPath*) indexPath
99 static NSString *identifer =
@"cell";
100 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifer];
104 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
107 cell.textLabel.text = [NSString stringWithFormat:@"%@", self.items[indexPath.row][0]];
109 IPopupMenu::Item* pItem = mMenu->GetItem([self menuIndexFromIndexPath:indexPath]);
111 if (pItem->GetChecked())
112 cell.accessoryType = UITableViewCellAccessoryCheckmark;
114 cell.accessoryType = pItem->GetSubmenu() ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
116 cell.textLabel.enabled = cell.userInteractionEnabled = pItem->GetEnabled();
121- (CGFloat) tableView:(UITableView*) tableView heightForRowAtIndexPath: (NSIndexPath*) indexPath
124 IPopupMenu::Item* pItem = mMenu->GetItem([self menuIndexFromIndexPath:indexPath]);
126 if (pItem->GetIsSeparator())
129 return self.tableView.rowHeight;
132- (CGFloat) tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
134 IPopupMenu::Item* pItem = mMenu->GetItem([self menuIndexFromIndexPath:indexPath]);
136 if (pItem->GetIsSeparator())
139 return self.tableView.rowHeight;
142- (void) tableView:(UITableView*) tableView didSelectRowAtIndexPath:(NSIndexPath*) indexPath
144 int menuIdx = [
self menuIndexFromIndexPath:indexPath];
151 IGRAPHICS_UITABLEVC* newViewController = [[IGRAPHICS_UITABLEVC alloc] initWithIPopupMenuAndIGraphics: pSubMenu : mGraphics];
152 [newViewController setTitle:[NSString stringWithUTF8String:CStringHasContents(pSubMenu->GetRootTitle()) ? pSubMenu->GetRootTitle() : pItem->GetText()]];
153 [
self.navigationController pushViewController:newViewController animated:YES];
158 if (pItem->GetIsChoosable())
160 [self dismissViewControllerAnimated:YES completion:nil];
162 mMenu->SetChosenItemIdx(menuIdx);
164 if (mMenu->GetFunction())
165 mMenu->ExecFunction();
167 mGraphics->SetControlValueAfterPopupMenu(mMenu);
171- (CGSize) preferredContentSize
173 if (self.presentingViewController && self.tableView != nil)
175 CGSize tempSize = self.presentingViewController.view.bounds.size;
176 tempSize.width = 300;
177 CGSize size = [self.tableView sizeThatFits:tempSize];
180 return [super preferredContentSize];
184- (void) setPreferredContentSize:(CGSize)preferredContentSize
186 super.preferredContentSize = preferredContentSize;
189- (void) tableView: (UITableView *) tableView commitEditingStyle: (UITableViewCellEditingStyle) editingStyle forRowAtIndexPath: (NSIndexPath*) indexPath
191 if (editingStyle == UITableViewCellEditingStyleDelete)
193 mGraphics->DeleteFromPopupMenu(mMenu, [self menuIndexFromIndexPath:indexPath]);
194 [
self.items removeObjectAtIndex:indexPath.row];
195 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
199- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath*) indexPath
201 return mMenu->GetItem([self menuIndexFromIndexPath:indexPath])->GetIsDeletable();
206@implementation IGRAPHICS_VIEW
212 mGraphics = pGraphics;
213 CGRect r = CGRectMake(0.f, 0.f, (
float) pGraphics->WindowWidth(), (
float) pGraphics->WindowHeight());
214 self = [
super initWithFrame:r];
219 CGFloat scale = [UIScreen mainScreen].scale;
222 self.layer.frame = self.frame;
223 self.layer.opaque = YES;
224 self.layer.contentsScale = scale;
225 self.contentScaleFactor = scale;
227 CAMetalLayer* mtlLayer = (CAMetalLayer*) self.layer;
228 mtlLayer.framebufferOnly = YES;
229 mtlLayer.device = MTLCreateSystemDefaultDevice();
231#if defined IGRAPHICS_GL
232 EGLDisplay display = eglGetPlatformDisplay(EGLenum(EGL_PLATFORM_ANGLE_ANGLE), 0, 0);
235 DBGMSG(
"eglGetPlatformDisplay() returned error %i", eglGetError());
238 if (eglInitialize(display, nil, nil) == 0) {
239 DBGMSG(
"eglInitialize() returned error %i", eglGetError());
242 const EGLint configAttribs[9] = {
248 EGLint numConfigs = 0;
249 EGLConfig configs[1];
251 if (eglChooseConfig(display, configAttribs, configs, 1, &numConfigs) == 0) {
252 DBGMSG(
"eglChooseConfig() returned error %i", eglGetError());
256 DBGMSG(
"Empty config returned in eglChooseConfig()");
259#if defined IGRAPHICS_GLES2
260 const EGLint contextAttribs [5] = {
261 EGL_CONTEXT_MAJOR_VERSION, 2,
262 EGL_CONTEXT_MINOR_VERSION, 0,
265#elif defined IGRAPHICS_GLES3
266 const EGLint contextAttribs [5] = {
267 EGL_CONTEXT_MAJOR_VERSION, 3,
268 EGL_CONTEXT_MINOR_VERSION, 0,
273 EGLContext context = eglCreateContext(display, configs[0],
nullptr, contextAttribs);
276 DBGMSG(
"eglCreateContext() returned error %d", eglGetError());
279 EGLSurface surface = eglCreateWindowSurface(display, configs[0], (__bridge EGLNativeWindowType) [self layer],
nullptr);
282 DBGMSG(
"eglCreateWindowSurface() returned error %d", eglGetError());
285 mEGLSurface = surface;
286 mEGLDisplay = display;
287 mEGLContext = context;
290 self.multipleTouchEnabled = NO;
292 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackgroundNotification:) name:UIApplicationDidEnterBackgroundNotification object:nil];
293 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForegroundNotification:) name:UIApplicationWillEnterForegroundNotification object:nil];
294 mColorPickerHandlerFunc =
nullptr;
296 UIHoverGestureRecognizer* hoverGestureRecognizer =
297 [[UIHoverGestureRecognizer alloc] initWithTarget:self action:@selector(onHoverGesture:)];
298 [
self addGestureRecognizer: hoverGestureRecognizer];
303- (void) setFrame:(CGRect) frame
305 [
super setFrame:frame];
310 CGFloat scale = [UIScreen mainScreen].scale;
312 scale = self.window.screen.scale;
316 [CATransaction begin];
317 [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
318 [
self.layer setFrame:frame];
321 CAMetalLayer* mtlLayer = (CAMetalLayer*) self.layer;
322 CGSize drawableSize = self.bounds.size;
323 drawableSize.width *= scale;
324 drawableSize.height *= scale;
325 mtlLayer.drawableSize = drawableSize;
327 [CATransaction commit];
330- (void) onTouchEvent:(ETouchEvent) eventType withTouches:(NSSet*) touches withEvent:(UIEvent*) event
332 if(mGraphics ==
nullptr)
335 NSEnumerator* pEnumerator = [[event allTouches] objectEnumerator];
338 std::vector<IMouseInfo> points;
340 while ((pTouch = [pEnumerator nextObject]))
342 CGPoint pos = [pTouch locationInView:pTouch.view];
346 auto ds = mGraphics->GetDrawScale();
349 point.ms.touchID =
reinterpret_cast<ITouchID
>(pTouch);
350 point.ms.touchRadius = [pTouch majorRadius];
352 point.x = pos.x / ds;
353 point.y = pos.y / ds;
354 CGPoint posPrev = [pTouch previousLocationInView: self];
355 point.dX = (pos.x - posPrev.x) / ds;
356 point.dY = (pos.y - posPrev.y) / ds;
358 if([touches containsObject:pTouch])
362 points.push_back(point);
368 if(eventType == ETouchEvent::Began)
369 mGraphics->OnMouseDown(points);
371 if(eventType == ETouchEvent::Moved)
372 mGraphics->OnMouseDrag(points);
374 if(eventType == ETouchEvent::Ended)
375 mGraphics->OnMouseUp(points);
377 if(eventType == ETouchEvent::Cancelled)
378 mGraphics->OnTouchCancelled(points);
381- (void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*) event
383 [
self onTouchEvent:ETouchEvent::Began withTouches:touches withEvent:event];
386- (void) touchesMoved:(NSSet*) touches withEvent:(UIEvent*) event
388 [
self onTouchEvent:ETouchEvent::Moved withTouches:touches withEvent:event];
391- (void) touchesEnded:(NSSet*) touches withEvent:(UIEvent*) event
393 [
self onTouchEvent:ETouchEvent::Ended withTouches:touches withEvent:event];
396- (void) touchesCancelled:(NSSet*) touches withEvent:(UIEvent*) event
398 [
self onTouchEvent:ETouchEvent::Cancelled withTouches:touches withEvent:event];
403 return CAMetalLayer.class;
406- (void) didMoveToSuperview
408 [
super didMoveToSuperview];
411 self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(redraw:)];
412 [
self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
413 self.displayLink.preferredFramesPerSecond = mGraphics->FPS();
417 [
self.displayLink invalidate];
418 self.displayLink = nil;
422- (void) drawRect:(CGRect)rect
428 mGraphics->SetPlatformContext(UIGraphicsGetCurrentContext());
431 if (mGraphics->IsDirty(rects))
433 mGraphics->SetAllControlsClean();
434 mGraphics->Draw(rects);
440- (void) redraw:(CADisplayLink*) displayLink
443 [
self setNeedsDisplay];
445 [
self drawRect:CGRect()];
454- (BOOL) acceptsFirstResponder
459- (BOOL) canBecomeFirstResponder
464- (void) removeFromSuperview
466 [
self.displayLink invalidate];
467 self.displayLink = nil;
470 mMenuTableController = nil;
471 mMenuNavigationController = nil;
473#if defined IGRAPHICS_GL
474 if (mEGLDisplay != EGL_NO_DISPLAY)
476 eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
477 if (mEGLSurface != EGL_NO_SURFACE)
478 eglDestroySurface(mEGLDisplay, mEGLSurface);
479 if (mEGLContext != EGL_NO_CONTEXT)
480 eglDestroyContext(mEGLDisplay, mEGLContext);
481 eglTerminate(mEGLDisplay);
483 mEGLDisplay = EGL_NO_DISPLAY;
484 mEGLSurface = EGL_NO_SURFACE;
485 mEGLContext = EGL_NO_CONTEXT;
489- (BOOL) textFieldShouldReturn:(UITextField*) textField
491 if (textField == mTextField)
493 mGraphics->SetControlValueAfterTextEdit([[mTextField text] UTF8String]);
494 mGraphics->SetAllControlsDirty();
501- (BOOL) textField:(UITextField*) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*) string
507 NSString* proposedText = [mTextField.text stringByReplacingCharactersInRange:range withString:string];
509 if (proposedText.length > mTextFieldLength)
512 IControl* pInTextEntry = mGraphics->GetControlInTextEntry();
520 NSMutableCharacterSet *characterSet = [[NSMutableCharacterSet alloc] init];
522 switch ( pParam->
Type() )
524 case IParam::kTypeEnum:
525 case IParam::kTypeInt:
526 case IParam::kTypeBool:
527 [characterSet addCharactersInString:@"0123456789-+"];
529 case IParam::kTypeDouble:
530 [characterSet addCharactersInString:@"0123456789.-+"];
536 if ([
string rangeOfCharacterFromSet:characterSet.invertedSet].location != NSNotFound)
544- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController:(UIPresentationController*) controller
546 return UIModalPresentationNone;
549- (BOOL) presentationControllerShouldDismiss:(UIPopoverPresentationController*) popoverPresentationController
556 mMenuTableController = [[IGRAPHICS_UITABLEVC alloc] initWithIPopupMenuAndIGraphics:&menu : mGraphics];
557 [mMenuTableController setTitle: [NSString stringWithUTF8String:menu.GetRootTitle()]];
559 mMenuNavigationController = [[UINavigationController alloc] initWithRootViewController:mMenuTableController];
561 mMenuNavigationController.modalPresentationStyle = UIModalPresentationPopover;
562 mMenuNavigationController.popoverPresentationController.sourceView = self;
563 mMenuNavigationController.popoverPresentationController.sourceRect = bounds;
565 mMenuNavigationController.popoverPresentationController.delegate = self;
567 [
self.window.rootViewController presentViewController:mMenuNavigationController animated:YES completion:nil];
572- (void) createTextEntry: (
int) paramIdx : (const
IText&) text : (const
char*) str : (
int) length : (CGRect) areaRect
577 mAlertController = [UIAlertController alertControllerWithTitle:@"Input a value:" message:@"" preferredStyle:UIAlertControllerStyleAlert];
579 __weak IGRAPHICS_VIEW* weakSelf = self;
581 void (^cancelHandler)(UIAlertAction*) = ^(UIAlertAction *action)
583 __strong IGRAPHICS_VIEW* strongSelf = weakSelf;
584 strongSelf->mGraphics->SetAllControlsDirty();
585 [strongSelf endUserInput];
588 UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:cancelHandler];
589 [mAlertController addAction:cancelAction];
591 void (^okHandler)(UIAlertAction*) = ^(UIAlertAction *action)
593 __strong IGRAPHICS_VIEW* strongSelf = weakSelf;
594 strongSelf->mGraphics->SetControlValueAfterTextEdit([[strongSelf->mTextField text] UTF8String]);
595 strongSelf->mGraphics->SetAllControlsDirty();
596 [strongSelf endUserInput];
599 UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:okHandler];
600 [mAlertController addAction:okAction];
601 [mAlertController setPreferredAction:okAction];
603 [mAlertController addTextFieldWithConfigurationHandler:^(UITextField* aTextField) {
604 __strong IGRAPHICS_VIEW* strongSelf = weakSelf;
605 strongSelf->mTextField = aTextField;
606 strongSelf->mTextFieldLength = length;
607 aTextField.delegate = strongSelf;
608 [aTextField setText:[NSString stringWithUTF8String:str]];
610 [
self.window.rootViewController presentViewController:mAlertController animated:YES completion:nil];
615 [
self becomeFirstResponder];
616 [
self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
617 [mTextField setDelegate: nil];
618 mAlertController =
nullptr;
619 mTextField =
nullptr;
620 mGraphics->ClearInTextEntryControl();
623- (void) showMessageBox: (const
char*) str : (const
char*) title : (EMsgBoxType) type : (IMsgBoxCompletionHandlerFunc) completionHandler
627 NSString* message = [NSString stringWithUTF8String:str];
628 NSString* titleNs = [NSString stringWithUTF8String:title];
630 UIAlertController* alertController = [UIAlertController alertControllerWithTitle:titleNs message:message preferredStyle:UIAlertControllerStyleAlert];
632 void (^handlerBlock)(UIAlertAction*) =
633 ^(UIAlertAction* action) {
635 if (completionHandler !=
nullptr)
637 EMsgBoxResult result = EMsgBoxResult::kCANCEL;
639 if ([action.title isEqualToString:
@"OK"])
640 result = EMsgBoxResult::kOK;
641 if ([action.title isEqualToString:
@"Cancel"])
642 result = EMsgBoxResult::kCANCEL;
643 if ([action.title isEqualToString:
@"Yes"])
644 result = EMsgBoxResult::kYES;
645 if ([action.title isEqualToString:
@"No"])
646 result = EMsgBoxResult::kNO;
647 if ([action.title isEqualToString:
@"Retry"])
648 result = EMsgBoxResult::kRETRY;
650 completionHandler(result);
655 if (type == kMB_OK || type == kMB_OKCANCEL)
657 UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:handlerBlock];
658 [alertController addAction:okAction];
661 if (type == kMB_YESNO || type == kMB_YESNOCANCEL)
663 UIAlertAction* yesAction = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:handlerBlock];
664 [alertController addAction:yesAction];
666 UIAlertAction* noAction = [UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleDefault handler:handlerBlock];
667 [alertController addAction:noAction];
670 if (type == kMB_RETRYCANCEL)
672 UIAlertAction* retryAction = [UIAlertAction actionWithTitle:@"Retry" style:UIAlertActionStyleDefault handler:handlerBlock];
673 [alertController addAction:retryAction];
676 if (type == kMB_OKCANCEL || type == kMB_YESNOCANCEL || type == kMB_RETRYCANCEL)
678 UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:handlerBlock];
679 [alertController addAction:cancelAction];
682 [[NSOperationQueue mainQueue] addOperationWithBlock:^{
683 [
self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
687- (void) promptForFile: (NSString*) fileName : (NSString*) path : (EFileAction) action : (NSArray*) contentTypes : (IFileDialogCompletionHandlerFunc) completionHandler
691 mFileDialogFunc = completionHandler;
693 UIDocumentPickerViewController* vc = NULL;
694 NSURL* url = [[NSURL alloc] initFileURLWithPath:path];
696 if (action == EFileAction::Open)
698 vc = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:contentTypes asCopy:YES];
699 [vc setDirectoryURL:url];
703 vc = [[UIDocumentPickerViewController alloc] initForExportingURLs:@[url]];
706 [vc setDelegate:self];
708 [
self.window.rootViewController presentViewController:vc animated:YES completion:nil];
711- (void) promptForDirectory: (NSString*) path : (IFileDialogCompletionHandlerFunc) completionHandler
715 mFileDialogFunc = completionHandler;
717 UIDocumentPickerViewController* vc = NULL;
718 NSURL* url = [[NSURL alloc] initFileURLWithPath:path];
720 NSMutableArray* pFileTypes = [[NSMutableArray alloc] init];
721 UTType* directoryType = [UTType typeWithIdentifier:@"public.folder"];
722 [pFileTypes addObject:directoryType];
724 vc = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:pFileTypes];
725 [vc setDirectoryURL:url];
727 [vc setDelegate:self];
729 [
self.window.rootViewController presentViewController:vc animated:YES completion:nil];
732- (BOOL) promptForColor: (
IColor&) color : (const
char*) str : (IColorPickerHandlerFunc) func
736 UIColorPickerViewController* colorSelectionController = [[UIColorPickerViewController alloc] init];
738 colorSelectionController.modalPresentationStyle = UIModalPresentationPopover;
739 colorSelectionController.popoverPresentationController.delegate = self;
740 colorSelectionController.popoverPresentationController.sourceView = self;
743 mGraphics->GetMouseLocation(x, y);
744 colorSelectionController.popoverPresentationController.sourceRect = CGRectMake(x, y, 1, 1);
746 colorSelectionController.delegate = self;
747 colorSelectionController.selectedColor = ToUIColor(color);
748 colorSelectionController.supportsAlpha = YES;
750 mColorPickerHandlerFunc = func;
752 [
self.window.rootViewController presentViewController:colorSelectionController animated:YES completion:nil];
757- (void) attachGestureRecognizer: (EGestureType) type
759 UIGestureRecognizer* gestureRecognizer;
763 case EGestureType::DoubleTap:
764 case EGestureType::TripleTap:
766 gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapGesture:)];
767 [(UITapGestureRecognizer*) gestureRecognizer setNumberOfTapsRequired: type == EGestureType::DoubleTap ? 2 : 3];
768 [(UITapGestureRecognizer*) gestureRecognizer setNumberOfTouchesRequired:1];
771 case EGestureType::LongPress1:
772 case EGestureType::LongPress2:
774 gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPressGesture:)];
775 [(UILongPressGestureRecognizer*) gestureRecognizer setNumberOfTouchesRequired: type == EGestureType::LongPress1 ? 1 : 2];
778 case EGestureType::SwipeLeft:
780 gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
781 [(UISwipeGestureRecognizer*) gestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
784 case EGestureType::SwipeRight:
786 gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
787 [(UISwipeGestureRecognizer*) gestureRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
790 case EGestureType::SwipeUp:
792 gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
793 [(UISwipeGestureRecognizer*) gestureRecognizer setDirection:UISwipeGestureRecognizerDirectionUp];
796 case EGestureType::SwipeDown:
798 gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
799 [(UISwipeGestureRecognizer*) gestureRecognizer setDirection:UISwipeGestureRecognizerDirectionDown];
802 case EGestureType::Pinch:
804 gestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(onPinchGesture:)];
807 case EGestureType::Rotate:
809 gestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(onRotateGesture:)];
816 gestureRecognizer.delegate = self;
817 gestureRecognizer.cancelsTouchesInView = YES;
818 gestureRecognizer.delaysTouchesBegan = YES;
819 [
self addGestureRecognizer:gestureRecognizer];
822- (void) onTapGesture: (UITapGestureRecognizer*) recognizer
824 CGPoint p = [recognizer locationInView:self];
825 auto ds = mGraphics->GetDrawScale();
829 info.type = recognizer.numberOfTapsRequired == 2 ? EGestureType::DoubleTap : EGestureType::TripleTap;
831 mGraphics->OnGestureRecognized(info);
834- (void) onLongPressGesture: (UILongPressGestureRecognizer*) recognizer
836 CGPoint p = [recognizer locationInView:self];
837 auto ds = mGraphics->GetDrawScale();
841 if(recognizer.state == UIGestureRecognizerStateBegan)
842 info.state = EGestureState::Began;
843 else if(recognizer.state == UIGestureRecognizerStateChanged)
844 info.state = EGestureState::InProcess;
845 else if(recognizer.state == UIGestureRecognizerStateEnded)
846 info.state = EGestureState::Ended;
848 info.type = recognizer.numberOfTouchesRequired == 1 ? EGestureType::LongPress1 : EGestureType::LongPress2;
850 mGraphics->OnGestureRecognized(info);
853- (void) onSwipeGesture: (UISwipeGestureRecognizer*) recognizer
855 CGPoint p = [recognizer locationInView:self];
856 auto ds = mGraphics->GetDrawScale();
861 switch (recognizer.direction) {
862 case UISwipeGestureRecognizerDirectionLeft: info.type = EGestureType::SwipeLeft;
break;
863 case UISwipeGestureRecognizerDirectionRight: info.type = EGestureType::SwipeRight;
break;
864 case UISwipeGestureRecognizerDirectionUp: info.type = EGestureType::SwipeUp;
break;
865 case UISwipeGestureRecognizerDirectionDown: info.type = EGestureType::SwipeDown;
break;
870 mGraphics->OnGestureRecognized(info);
873- (void) onPinchGesture: (UIPinchGestureRecognizer*) recognizer
875 CGPoint p = [recognizer locationInView:self];
876 auto ds = mGraphics->GetDrawScale();
880 info.velocity = recognizer.velocity;
881 info.scale = recognizer.scale;
883 if(recognizer.state == UIGestureRecognizerStateBegan)
884 info.state = EGestureState::Began;
885 else if(recognizer.state == UIGestureRecognizerStateChanged)
886 info.state = EGestureState::InProcess;
887 else if(recognizer.state == UIGestureRecognizerStateEnded)
888 info.state = EGestureState::Ended;
890 info.type = EGestureType::Pinch;
892 mGraphics->OnGestureRecognized(info);
895- (void) onRotateGesture: (UIRotationGestureRecognizer*) recognizer
897 CGPoint p = [recognizer locationInView:self];
898 auto ds = mGraphics->GetDrawScale();
902 info.velocity = recognizer.velocity;
903 info.angle = RadToDeg(recognizer.rotation);
905 if(recognizer.state == UIGestureRecognizerStateBegan)
906 info.state = EGestureState::Began;
907 else if(recognizer.state == UIGestureRecognizerStateChanged)
908 info.state = EGestureState::InProcess;
909 else if(recognizer.state == UIGestureRecognizerStateEnded)
910 info.state = EGestureState::Ended;
912 info.type = EGestureType::Rotate;
914 mGraphics->OnGestureRecognized(info);
917- (void) onHoverGesture: (UIHoverGestureRecognizer*) recognizer
919 CGPoint pos = [recognizer locationInView:self];
923 auto ds = mGraphics->GetDrawScale();
928 mGraphics->OnMouseOver(info.x, info.y, info.ms);
931-(BOOL) gestureRecognizer:(UIGestureRecognizer*) gestureRecognizer shouldReceiveTouch:(UITouch*) touch
933 CGPoint pos = [touch locationInView:touch.view];
937 auto ds = mGraphics->GetDrawScale();
939 if (mGraphics->RespondsToGesture(pos.x / ds, pos.y / ds))
948- (void) applicationDidEnterBackgroundNotification:(NSNotification*) notification
950 [
self.displayLink setPaused:YES];
953- (void) applicationWillEnterForegroundNotification:(NSNotification*) notification
955 [
self.displayLink setPaused:NO];
958- (BOOL) delaysContentTouches
963- (void) presentationControllerDidDismiss: (UIPresentationController*) presentationController
965 mGraphics->SetControlValueAfterPopupMenu(
nullptr);
968- (void) documentPicker:(UIDocumentPickerViewController*) controller didPickDocumentsAtURLs:(NSArray <NSURL*>*) urls
970 WDL_String fileName, path;
974 NSURL* pSource = urls[0];
975 NSString* pFullPath = [pSource path];
976 fileName.Set([pFullPath UTF8String]);
978 NSString* pTruncatedPath = [pFullPath stringByDeletingLastPathComponent];
982 path.Set([pTruncatedPath UTF8String]);
987 mFileDialogFunc(fileName, path);
993 mFileDialogFunc(fileName, path);
997- (void) documentPickerWasCancelled:(UIDocumentPickerViewController*) controller
999 WDL_String fileName, path;
1001 if (mFileDialogFunc)
1002 mFileDialogFunc(fileName, path);
1005- (void) colorPickerViewControllerDidSelectColor:(UIColorPickerViewController*) viewController;
1007 if (mColorPickerHandlerFunc)
1009 IColor c = FromUIColor([viewController selectedColor]);
1010 mColorPickerHandlerFunc(c);
1014- (void) colorPickerViewControllerDidFinish:(UIColorPickerViewController*) viewController;
1016 mColorPickerHandlerFunc =
nullptr;
1019- (void) traitCollectionDidChange: (UITraitCollection*) previousTraitCollection
1021 [
super traitCollectionDidChange: previousTraitCollection];
1025 mGraphics->OnAppearanceChanged([self.traitCollection userInterfaceStyle] == UIUserInterfaceStyleDark ? EUIAppearance::Dark
1026 : EUIAppearance::Light);
1030- (void) getLastTouchLocation: (
float&) x : (
float&) y
1032 const float scale = mGraphics->GetDrawScale();
1037- (void) activateGLContext
1040 if (mEGLDisplay != EGL_NO_DISPLAY && mEGLContext != EGL_NO_CONTEXT)
1041 eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);
1045- (void) deactivateGLContext
1048 if (mEGLDisplay != EGL_NO_DISPLAY)
1049 eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1056 if (mEGLDisplay != EGL_NO_DISPLAY && mEGLSurface != EGL_NO_SURFACE)
1057 eglSwapBuffers(mEGLDisplay, mEGLSurface);
This file contains the base IControl implementation, along with some base classes for specific types ...
The lowest level base class of an IGraphics control.
const IParam * GetParam(int valIdx=0) const
Get a const pointer to the IParam object (owned by the editor delegate class), associated with this c...
IGraphics platform class for IOS.
EParamType Type() const
Get the parameter's type.
Used to manage a list of rectangular areas and optimize them for drawing to the screen.
Used to describe a particular gesture.
Used to group mouse coordinates with mouse modifier information.
Used to manage color data, independent of draw class/platform.
IText is used to manage font and text/text entry style for a piece of text on the UI,...