mirror of
https://github.com/ocornut/imgui.git
synced 2026-04-02 21:47:38 -05:00
Introduced a new Metal renderer implementation and a new example illustrating usage of Metal on macOS and iOS (partially addresses #1873)
This commit is contained in:
130
examples/example_apple_metal/Shared/ViewController.mm
Normal file
130
examples/example_apple_metal/Shared/ViewController.mm
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
#import "ViewController.h"
|
||||
#import "Renderer.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
#include "imgui_impl_osx.h"
|
||||
#endif
|
||||
|
||||
@interface ViewController ()
|
||||
@property (nonatomic, readonly) MTKView *mtkView;
|
||||
@property (nonatomic, strong) Renderer *renderer;
|
||||
@end
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (MTKView *)mtkView {
|
||||
return (MTKView *)self.view;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.mtkView.device = MTLCreateSystemDefaultDevice();
|
||||
|
||||
if (!self.mtkView.device) {
|
||||
NSLog(@"Metal is not supported");
|
||||
abort();
|
||||
}
|
||||
|
||||
self.renderer = [[Renderer alloc] initWithView:self.mtkView];
|
||||
|
||||
[self.renderer mtkView:self.mtkView drawableSizeWillChange:self.mtkView.bounds.size];
|
||||
|
||||
self.mtkView.delegate = self.renderer;
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
// Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view
|
||||
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
|
||||
options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self.view addTrackingArea:trackingArea];
|
||||
|
||||
// If we want to receive key events, we either need to be in the responder chain of the key view,
|
||||
// or else we can install a local monitor. The consequence of this heavy-handed approach is that
|
||||
// we receive events for all controls, not just ImGui widgets. If we had native controls in our
|
||||
// window, we'd want to be much more careful than just ingesting the complete event stream, though
|
||||
// we do make an effort to be good citizens by passing along events when ImGui doesn't want to capture.
|
||||
NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel;
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) {
|
||||
BOOL wantsCapture = ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
if (event.type == NSEventTypeKeyDown && wantsCapture) {
|
||||
return nil;
|
||||
} else {
|
||||
return event;
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
ImGui_ImplOSX_Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)event {
|
||||
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event {
|
||||
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent *)event {
|
||||
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)event {
|
||||
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)event {
|
||||
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
}
|
||||
|
||||
#elif TARGET_OS_IOS
|
||||
|
||||
// This touch mapping is super cheesy/hacky. We treat any touch on the screen
|
||||
// as if it were a depressed left mouse button, and we don't bother handling
|
||||
// multitouch correctly at all. This causes the "cursor" to behave very erratically
|
||||
// when there are multiple active touches. But for demo purposes, single-touch
|
||||
// interaction actually works surprisingly well.
|
||||
- (void)updateIOWithTouchEvent:(UIEvent *)event {
|
||||
UITouch *anyTouch = event.allTouches.anyObject;
|
||||
CGPoint touchLocation = [anyTouch locationInView:self.view];
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2(touchLocation.x, touchLocation.y);
|
||||
|
||||
BOOL hasActiveTouch = NO;
|
||||
for (UITouch *touch in event.allTouches) {
|
||||
if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) {
|
||||
hasActiveTouch = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
io.MouseDown[0] = hasActiveTouch;
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||
[self updateIOWithTouchEvent:event];
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||
[self updateIOWithTouchEvent:event];
|
||||
}
|
||||
|
||||
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||
[self updateIOWithTouchEvent:event];
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||
[self updateIOWithTouchEvent:event];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user