src/osx/native_window.mm in reflexion-0.1.12 vs src/osx/native_window.mm in reflexion-0.1.13

- old
+ new

@@ -2,100 +2,118 @@ #import "native_window.h" #include <assert.h> #import <Cocoa/Cocoa.h> -#include "reflex/bounds.h" -#include "reflex/window.h" +#include "rays/bounds.h" #include "reflex/exception.h" +#include "../view.h" #include "event.h" -#include "window_data.h" +#include "window.h" #import "opengl_view.h" -#define REF (*pref) - - -namespace Reflex -{ - - void update_view_tree (View* v, const UpdateEvent& e); - - void draw_view_tree (View* v, const DrawEvent& e, const Point& offset, const Bounds& clip); - -}// Reflex - - static const NSUInteger WINDOW_STYLE_MASK = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask | 0;//NSTexturedBackgroundWindowMask @implementation NativeWindow + { + Reflex::Window *pwindow, *ptr_for_rebind; + OpenGLView* view; + NSTimer* timer; + } + - (id) init { self = [super initWithContentRect: NSMakeRect(0, 0, 0, 0) styleMask: WINDOW_STYLE_MASK backing: NSBackingStoreBuffered defer: NO]; if (!self) return nil; - pref = new Reflex::Window::Ref; - view = nil; - timer = nil; + pwindow = ptr_for_rebind = NULL; + view = nil; + timer = nil; [self setDelegate: self]; [self setupContentView]; [self startTimer: 60]; return self; } - (void) dealloc { - assert(pref && !REF); + assert(!pwindow); if (view) [view release]; - delete pref; - [super dealloc]; } - - (void) bind: (Reflex::Window*) instance + - (void) bind: (Reflex::Window*) window { - assert(pref); - - if (instance && instance->self->native) + if (!window) Reflex::argument_error(__FILE__, __LINE__); - if (REF) + Reflex::WindowData& data = Window_get_data(window); + if (data.native) Reflex::invalid_state_error(__FILE__, __LINE__); - REF = instance; - if (REF) REF->self->native = [self retain]; + data.native = [self retain]; + + // Reflex::Window is not constructed completely, + // so can not call ClassWrapper::retain(). + window->Xot::template RefCountable<>::retain(); + + // defer calling ClassWrapper::retain() to rebind. + ptr_for_rebind = window; } - - (void) unbind: (Reflex::Window*) instance + - (void) rebind { - assert(pref); + if (!pwindow && ptr_for_rebind) + { + pwindow = ptr_for_rebind; + pwindow->retain(); - if (!REF) return; + ptr_for_rebind->Xot::template RefCountable<>::release(); + ptr_for_rebind = NULL; + } - if (instance && instance != REF.get()) - Reflex::invalid_state_error(__FILE__, __LINE__); + assert(pwindow && !ptr_for_rebind); + } - if (REF->self->native) [REF->self->native release]; - REF->self->native = nil; - REF.reset(); + - (void) unbind + { + [self rebind]; + if (!pwindow) return; + + Reflex::WindowData& data = Window_get_data(pwindow); + if (data.native) + { + [data.native release]; + data.native = nil; + } + + pwindow->release(); + pwindow = NULL; } + - (Reflex::Window*) window + { + [self rebind]; + return pwindow; + } + - (void) setupContentView { NSRect rect = [self contentRectForFrameRect: [self frame]]; rect.origin.x = rect.origin.y = 0; view = [[OpenGLView alloc] initWithFrame: rect]; @@ -114,13 +132,13 @@ selector: @selector(update:) userInfo: nil repeats: YES] retain]; if (!timer) return; - [[NSRunLoop currentRunLoop] + [[NSRunLoop mainRunLoop] addTimer: timer forMode: NSDefaultRunLoopMode]; - [[NSRunLoop currentRunLoop] + [[NSRunLoop mainRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode]; } - (void) stopTimer { @@ -130,203 +148,201 @@ timer = nil; } - (void) update: (NSTimer*) t { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - double now = Xot::time(); - Reflex::UpdateEvent e(now - REF->self->prev_time_update); - REF->self->prev_time_update = now; + Reflex::UpdateEvent e(now, now - win->self->prev_time_update); + win->self->prev_time_update = now; - REF->on_update(&e); + win->on_update(&e); if (!e.is_blocked()) - Reflex::update_view_tree(REF->root(), e); + Reflex::View_update_tree(win->root(), e); - if (REF->self->redraw) + if (win->self->redraw) { - [self display]; - REF->self->redraw = false; + view.needsDisplay = YES; + win->self->redraw = false; } } - (void) draw { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - double now = Xot::time(); - double dt = now - REF->self->prev_time_draw; + double dt = now - win->self->prev_time_draw; double fps = 1. / dt; - fps = REF->self->prev_fps * 0.9 + fps * 0.1;// LPF - REF->self->prev_time_draw = now; - REF->self->prev_fps = fps; + fps = win->self->prev_fps * 0.9 + fps * 0.1;// LPF + win->self->prev_time_draw = now; + win->self->prev_fps = fps; + Reflex::DrawEvent e(dt, fps); - e.painter = REF->painter(); + e.painter = win->painter(); if (!e.painter) Xot::invalid_state_error(__FILE__, __LINE__); - Rays::Bounds b = REF->frame(); - e.bounds.reset(0, 0, b.width, b.height); + Rays::Bounds frame = win->frame(); + e.bounds.reset(0, 0, frame.width, frame.height); e.painter->begin(); e.painter->clear(); - REF->on_draw(&e); + win->on_draw(&e); if (!e.is_blocked()) - draw_view_tree(REF->root(), e, 0, REF->frame().dup().move_to(0)); + Reflex::View_draw_tree(win->root(), e, 0, frame.move_to(0)); e.painter->end(); } - (BOOL) windowShouldClose: (id) sender { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return YES; - if (!REF) return YES; - - REF->close(); + win->close(); return NO; } - (void) windowWillClose: (NSNotification*) notification { [self stopTimer]; - [self unbind: NULL]; + [self unbind]; [self setDelegate: nil]; } - (void) windowWillMove: (NSNotification*) notification { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - - REF->self->prev_position = REF->frame().position(); + win->self->prev_position = win->frame().position(); } - (void) windowDidMove: (NSNotification*) notification { [self frameChanged]; } - (NSSize) windowWillResize: (NSWindow*) sender toSize: (NSSize) frameSize { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return frameSize; - if (!REF) return frameSize; + win->self->prev_size = win->frame().size(); - REF->self->prev_size = REF->frame().size(); - return frameSize; } - (void) windowDidResize: (NSNotification*) notification { [self frameChanged]; } - (void) frameChanged { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; + Rays::Bounds b = win->frame(); + Rays::Point dpos = b.position() - win->self->prev_position; + Rays::Point dsize = b.size() - win->self->prev_size; + win->self->prev_position = b.position(); + win->self->prev_size = b.size(); - Rays::Bounds b = REF->frame(); - Rays::Point dpos = b.position() - REF->self->prev_position; - Rays::Point dsize = b.size() - REF->self->prev_size; - REF->self->prev_position = b.position(); - REF->self->prev_size = b.size(); - if (dpos != 0 || dsize != 0) { Reflex::FrameEvent e(b, dpos.x, dpos.y, dsize.x, dsize.y); - if (dpos != 0) REF->on_move(&e); + if (dpos != 0) win->on_move(&e); if (dsize != 0) { - Rays::Bounds b = REF->frame(); + Rays::Bounds b = win->frame(); b.move_to(0, 0); - if (REF->painter()) REF->painter()->canvas(b); - if (REF->root()) REF->root()->set_frame(b); - REF->on_resize(&e); + + if (win->painter()) + win->painter()->canvas(b, self.backingScaleFactor); + + if (win->root()) + View_set_frame(win->root(), b); + + win->on_resize(&e); } } } - (void) keyDown: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativeKeyEvent e(event, Reflex::KeyEvent::DOWN); - REF->on_key(&e); + win->on_key(&e); } - (void) keyUp: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativeKeyEvent e(event, Reflex::KeyEvent::UP); - REF->on_key(&e); + win->on_key(&e); } + - (void) flagsChanged: (NSEvent*) event + { + // TODO: implement later. + } + - (void) mouseDown: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativePointerEvent e(event, view, Reflex::PointerEvent::DOWN); - REF->on_pointer(&e); + win->on_pointer(&e); } - (void) mouseUp: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativePointerEvent e(event, view, Reflex::PointerEvent::UP); - REF->on_pointer(&e); + win->on_pointer(&e); } - (void) mouseDragged: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativePointerEvent e(event, view, Reflex::PointerEvent::MOVE); - REF->on_pointer(&e); + win->on_pointer(&e); } - (void) mouseMoved: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativePointerEvent e(event, view, Reflex::PointerEvent::MOVE); - REF->on_pointer(&e); + win->on_pointer(&e); } - (void) scrollWheel: (NSEvent*) event { - assert(pref); + Reflex::Window* win = self.window; + if (!win) return; - if (!REF) return; - Reflex::NativeWheelEvent e(event, view); - REF->on_wheel(&e); + win->on_wheel(&e); } + (NSRect) frameRectForContentRect: (NSRect) contentRect { return [NSWindow