diff options
Diffstat (limited to 'platform/osx/os_osx.mm')
| -rw-r--r-- | platform/osx/os_osx.mm | 153 |
1 files changed, 114 insertions, 39 deletions
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index eaf89f7d0f..4ece1e0325 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -541,7 +541,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } - (void)cursorUpdate:(NSEvent *)event { - //setModeCursor(window, window->cursorMode); + OS::CursorShape p_shape = OS_OSX::singleton->cursor_shape; + OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX; + OS_OSX::singleton->set_cursor_shape(p_shape); } static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { @@ -656,11 +658,12 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { return; if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED) OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); - if (OS_OSX::singleton->input) { + if (OS_OSX::singleton->input) OS_OSX::singleton->input->set_mouse_in_window(true); - OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX; - OS_OSX::singleton->set_cursor_shape(OS::CURSOR_ARROW); - } + + OS::CursorShape p_shape = OS_OSX::singleton->cursor_shape; + OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX; + OS_OSX::singleton->set_cursor_shape(p_shape); } - (void)magnifyWithEvent:(NSEvent *)event { @@ -847,16 +850,16 @@ struct _KeyCodeMap { static const _KeyCodeMap _keycodes[55] = { { '`', KEY_QUOTELEFT }, { '~', KEY_ASCIITILDE }, - { '0', KEY_KP_0 }, - { '1', KEY_KP_1 }, - { '2', KEY_KP_2 }, - { '3', KEY_KP_3 }, - { '4', KEY_KP_4 }, - { '5', KEY_KP_5 }, - { '6', KEY_KP_6 }, - { '7', KEY_KP_7 }, - { '8', KEY_KP_8 }, - { '9', KEY_KP_9 }, + { '0', KEY_0 }, + { '1', KEY_1 }, + { '2', KEY_2 }, + { '3', KEY_3 }, + { '4', KEY_4 }, + { '5', KEY_5 }, + { '6', KEY_6 }, + { '7', KEY_7 }, + { '8', KEY_8 }, + { '9', KEY_9 }, { '-', KEY_MINUS }, { '_', KEY_UNDERSCORE }, { '=', KEY_EQUAL }, @@ -910,7 +913,7 @@ static int remapKey(unsigned int key) { CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); if (!layoutData) - return nil; + return 0; const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); @@ -956,7 +959,7 @@ static int remapKey(unsigned int key) { push_to_key_event_buffer(ke); } - if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0)) + if (OS_OSX::singleton->im_active == true) [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } @@ -1126,6 +1129,10 @@ String OS_OSX::get_unique_id() const { return serial_number; } +void OS_OSX::set_ime_active(const bool p_active) { + im_active = p_active; +} + void OS_OSX::set_ime_position(const Point2 &p_pos) { im_position = p_pos; } @@ -1181,6 +1188,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (p_desired.borderless_window) { styleMask = NSWindowStyleMaskBorderless; } else { + resizable = p_desired.resizable; styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (p_desired.resizable ? NSWindowStyleMaskResizable : 0); } @@ -1477,7 +1485,7 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) { if (cursor_shape == p_shape) return; - if (mouse_mode != MOUSE_MODE_VISIBLE) { + if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) { cursor_shape = p_shape; return; } @@ -1513,48 +1521,98 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) { void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (p_cursor.is_valid()) { Ref<Texture> texture = p_cursor; - Ref<Image> image = texture->get_data(); + Ref<AtlasTexture> atlas_texture = p_cursor; + Ref<Image> image; + Size2 texture_size; + Rect2 atlas_rect; + + if (texture.is_valid()) { + image = texture->get_data(); + } - ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256); + if (!image.is_valid() && atlas_texture.is_valid()) { + texture = atlas_texture->get_atlas(); - NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc] + atlas_rect.size.width = texture->get_width(); + atlas_rect.size.height = texture->get_height(); + atlas_rect.position.x = atlas_texture->get_region().position.x; + atlas_rect.position.y = atlas_texture->get_region().position.y; + + texture_size.width = atlas_texture->get_region().size.x; + texture_size.height = atlas_texture->get_region().size.y; + } else if (image.is_valid()) { + texture_size.width = texture->get_width(); + texture_size.height = texture->get_height(); + } + + ERR_FAIL_COND(!texture.is_valid()); + ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); + + image = texture->get_data(); + + ERR_FAIL_COND(!image.is_valid()); + + NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:image->get_width() - pixelsHigh:image->get_height() + pixelsWide:int(texture_size.width) + pixelsHigh:int(texture_size.height) bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:image->get_width() * 4 - bitsPerPixel:32] autorelease]; + bytesPerRow:int(texture_size.width) * 4 + bitsPerPixel:32]; ERR_FAIL_COND(imgrep == nil); uint8_t *pixels = [imgrep bitmapData]; - int len = image->get_width() * image->get_height(); + int len = int(texture_size.width * texture_size.height); PoolVector<uint8_t> data = image->get_data(); PoolVector<uint8_t>::Read r = data.read(); + image->lock(); + /* Premultiply the alpha channel */ for (int i = 0; i < len; i++) { - uint8_t alpha = r[i * 4 + 3]; - pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255); - pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255); - pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255); + int row_index = floor(i / texture_size.width) + atlas_rect.position.y; + int column_index = (i % int(texture_size.width)) + atlas_rect.position.x; + + if (atlas_texture.is_valid()) { + column_index = MIN(column_index, atlas_rect.size.width - 1); + row_index = MIN(row_index, atlas_rect.size.height - 1); + } + + uint32_t color = image->get_pixel(column_index, row_index).to_argb32(); + + uint8_t alpha = (color >> 24) & 0xFF; + pixels[i * 4 + 0] = ((color >> 16) & 0xFF) * alpha / 255; + pixels[i * 4 + 1] = ((color >> 8) & 0xFF) * alpha / 255; + pixels[i * 4 + 2] = ((color)&0xFF) * alpha / 255; pixels[i * 4 + 3] = alpha; } - NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(image->get_width(), image->get_height())] autorelease]; + image->unlock(); + + NSImage *nsimage = [[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)]; [nsimage addRepresentation:imgrep]; NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)]; + [cursors[p_shape] release]; cursors[p_shape] = cursor; if (p_shape == CURSOR_ARROW) { [cursor set]; } + + [imgrep release]; + [nsimage release]; + } else { + // Reset to default system cursor + cursors[p_shape] = NULL; + cursor_shape = CURSOR_MAX; + set_cursor_shape(p_shape); } } @@ -1693,7 +1751,8 @@ String OS_OSX::get_godot_dir_name() const { String OS_OSX::get_system_dir(SystemDir p_dir) const { - NSSearchPathDirectory id = 0; + NSSearchPathDirectory id; + bool found = true; switch (p_dir) { case SYSTEM_DIR_DESKTOP: { @@ -1714,10 +1773,13 @@ String OS_OSX::get_system_dir(SystemDir p_dir) const { case SYSTEM_DIR_PICTURES: { id = NSPicturesDirectory; } break; + default: { + found = false; + } } String ret; - if (id) { + if (found) { NSArray *paths = NSSearchPathForDirectoriesInDomains(id, NSUserDomainMask, YES); if (paths && [paths count] >= 1) { @@ -2063,6 +2125,8 @@ void OS_OSX::set_window_resizable(bool p_enabled) { [window_object setStyleMask:[window_object styleMask] | NSWindowStyleMaskResizable]; else [window_object setStyleMask:[window_object styleMask] & ~NSWindowStyleMaskResizable]; + + resizable = p_enabled; }; bool OS_OSX::is_window_resizable() const { @@ -2172,7 +2236,7 @@ void OS_OSX::set_borderless_window(bool p_borderless) { if (layered_window) set_window_per_pixel_transparency_enabled(false); - [window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable]; + [window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (resizable ? NSWindowStyleMaskResizable : 0)]; // Force update of the window styles NSRect frameRect = [window_object frame]; @@ -2380,12 +2444,21 @@ void OS_OSX::run() { //int frames=0; //uint64_t frame=0; - while (!force_quit) { + bool quit = false; - process_events(); // get rid of pending events - joypad_osx->process_joypads(); - if (Main::iteration() == true) - break; + while (!force_quit && !quit) { + + @try { + + process_events(); // get rid of pending events + joypad_osx->process_joypads(); + + if (Main::iteration() == true) { + quit = true; + } + } @catch (NSException *exception) { + ERR_PRINTS("NSException: " + String([exception reason].UTF8String)); + } }; main_loop->finish(); @@ -2473,6 +2546,7 @@ OS_OSX::OS_OSX() { mouse_mode = OS::MOUSE_MODE_VISIBLE; main_loop = NULL; singleton = this; + im_active = false; im_position = Point2(); im_callback = NULL; im_target = NULL; @@ -2559,6 +2633,7 @@ OS_OSX::OS_OSX() { minimized = false; window_size = Vector2(1024, 600); zoomed = false; + resizable = false; Vector<Logger *> loggers; loggers.push_back(memnew(OSXTerminalLogger)); |