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