+View m_view;
+camera_t m_Camera;
+RadiantCameraView m_cameraview;
+
+guint m_freemove_handle_focusout;
+
+static Shader* m_state_select1;
+static Shader* m_state_select2;
+
+FreezePointer m_freezePointer;
+
+public:
+GtkWidget* m_gl_widget;
+GtkWindow* m_parent;
+
+SelectionSystemWindowObserver* m_window_observer;
+XORRectangle m_XORRectangle;
+
+DeferredDraw m_deferredDraw;
+DeferredMotion m_deferred_motion;
+
+guint m_selection_button_press_handler;
+guint m_selection_button_release_handler;
+guint m_selection_motion_handler;
+
+guint m_freelook_button_press_handler;
+
+guint m_sizeHandler;
+guint m_exposeHandler;
+
+CamWnd();
+~CamWnd();
+
+bool m_drawing;
+void queue_draw(){
+ if ( m_drawing ) {
+ return;
+ }
+ m_deferredDraw.draw();
+}
+void draw();
+
+static void captureStates(){
+ m_state_select1 = GlobalShaderCache().capture( "$CAM_HIGHLIGHT" );
+ m_state_select2 = GlobalShaderCache().capture( "$CAM_OVERLAY" );
+}
+static void releaseStates(){
+ GlobalShaderCache().release( "$CAM_HIGHLIGHT" );
+ GlobalShaderCache().release( "$CAM_OVERLAY" );
+}
+
+camera_t& getCamera(){
+ return m_Camera;
+};
+
+void BenchMark();
+void Cam_ChangeFloor( bool up );
+
+void DisableFreeMove();
+void EnableFreeMove();
+bool m_bFreeMove;
+
+CameraView& getCameraView(){
+ return m_cameraview;
+}
+
+private:
+void Cam_Draw();
+};
+
+typedef MemberCaller<CamWnd, &CamWnd::queue_draw> CamWndQueueDraw;
+
+Shader* CamWnd::m_state_select1 = 0;
+Shader* CamWnd::m_state_select2 = 0;
+
+CamWnd* NewCamWnd(){
+ return new CamWnd;
+}
+void DeleteCamWnd( CamWnd* camwnd ){
+ delete camwnd;
+}
+
+void CamWnd_constructStatic(){
+ CamWnd::captureStates();
+}
+
+void CamWnd_destroyStatic(){
+ CamWnd::releaseStates();
+}
+
+static CamWnd* g_camwnd = 0;
+
+void GlobalCamera_setCamWnd( CamWnd& camwnd ){
+ g_camwnd = &camwnd;
+}
+
+
+GtkWidget* CamWnd_getWidget( CamWnd& camwnd ){
+ return camwnd.m_gl_widget;
+}
+
+GtkWindow* CamWnd_getParent( CamWnd& camwnd ){
+ return camwnd.m_parent;
+}
+
+ToggleShown g_camera_shown( true );
+
+void CamWnd_setParent( CamWnd& camwnd, GtkWindow* parent ){
+ camwnd.m_parent = parent;
+ g_camera_shown.connect( GTK_WIDGET( camwnd.m_parent ) );
+}
+
+void CamWnd_Update( CamWnd& camwnd ){
+ camwnd.queue_draw();
+}
+
+
+
+camwindow_globals_t g_camwindow_globals;
+
+const Vector3& Camera_getOrigin( CamWnd& camwnd ){
+ return Camera_getOrigin( camwnd.getCamera() );
+}
+
+void Camera_setOrigin( CamWnd& camwnd, const Vector3& origin ){
+ Camera_setOrigin( camwnd.getCamera(), origin );
+}
+
+const Vector3& Camera_getAngles( CamWnd& camwnd ){
+ return Camera_getAngles( camwnd.getCamera() );
+}
+
+void Camera_setAngles( CamWnd& camwnd, const Vector3& angles ){
+ Camera_setAngles( camwnd.getCamera(), angles );
+}
+
+
+// =============================================================================
+// CamWnd class
+
+gboolean enable_freelook_button_press( GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd ){
+ if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) {
+ camwnd->EnableFreeMove();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean disable_freelook_button_press( GtkWidget* widget, GdkEventButton* event, CamWnd* camwnd ){
+ if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) {
+ camwnd->DisableFreeMove();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void camwnd_update_xor_rectangle( CamWnd& self, rect_t area ){
+ if ( GTK_WIDGET_VISIBLE( self.m_gl_widget ) ) {
+ self.m_XORRectangle.set( rectangle_from_area( area.min, area.max, self.getCamera().width, self.getCamera().height ) );
+ }
+}
+
+
+gboolean selection_button_press( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){
+ if ( event->type == GDK_BUTTON_PRESS ) {
+ observer->onMouseDown( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) );
+ }
+ return FALSE;
+}
+
+gboolean selection_button_release( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){
+ if ( event->type == GDK_BUTTON_RELEASE ) {
+ observer->onMouseUp( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) );
+ }
+ return FALSE;
+}
+
+void selection_motion( gdouble x, gdouble y, guint state, void* data ){
+ //globalOutputStream() << "motion... ";
+ reinterpret_cast<WindowObserver*>( data )->onMouseMotion( WindowVector_forDouble( x, y ), modifiers_for_state( state ) );
+}
+
+inline WindowVector windowvector_for_widget_centre( GtkWidget* widget ){
+ return WindowVector( static_cast<float>( widget->allocation.width / 2 ), static_cast<float>( widget->allocation.height / 2 ) );
+}
+
+gboolean selection_button_press_freemove( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){
+ if ( event->type == GDK_BUTTON_PRESS ) {
+ observer->onMouseDown( windowvector_for_widget_centre( widget ), button_for_button( event->button ), modifiers_for_state( event->state ) );
+ }
+ return FALSE;
+}
+
+gboolean selection_button_release_freemove( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){
+ if ( event->type == GDK_BUTTON_RELEASE ) {
+ observer->onMouseUp( windowvector_for_widget_centre( widget ), button_for_button( event->button ), modifiers_for_state( event->state ) );
+ }
+ return FALSE;
+}
+
+gboolean selection_motion_freemove( GtkWidget *widget, GdkEventMotion *event, WindowObserver* observer ){
+ observer->onMouseMotion( windowvector_for_widget_centre( widget ), modifiers_for_state( event->state ) );
+ return FALSE;
+}
+
+gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){
+ if ( event->direction == GDK_SCROLL_UP ) {
+ Camera_Freemove_updateAxes( camwnd->getCamera() );
+ Camera_setOrigin( *camwnd, vector3_added( Camera_getOrigin( *camwnd ), vector3_scaled( camwnd->getCamera().forward, static_cast<float>( g_camwindow_globals_private.m_nMoveSpeed ) ) ) );
+ }
+ else if ( event->direction == GDK_SCROLL_DOWN ) {
+ Camera_Freemove_updateAxes( camwnd->getCamera() );
+ Camera_setOrigin( *camwnd, vector3_added( Camera_getOrigin( *camwnd ), vector3_scaled( camwnd->getCamera().forward, -static_cast<float>( g_camwindow_globals_private.m_nMoveSpeed ) ) ) );
+ }
+
+ return FALSE;
+}
+
+gboolean camera_size_allocate( GtkWidget* widget, GtkAllocation* allocation, CamWnd* camwnd ){
+ camwnd->getCamera().width = allocation->width;
+ camwnd->getCamera().height = allocation->height;
+ Camera_updateProjection( camwnd->getCamera() );
+ camwnd->m_window_observer->onSizeChanged( camwnd->getCamera().width, camwnd->getCamera().height );
+ camwnd->queue_draw();
+ return FALSE;
+}
+
+gboolean camera_expose( GtkWidget* widget, GdkEventExpose* event, gpointer data ){
+ reinterpret_cast<CamWnd*>( data )->draw();
+ return FALSE;
+}
+
+void KeyEvent_connect( const char* name ){
+ const KeyEvent& keyEvent = GlobalKeyEvents_find( name );
+ keydown_accelerators_add( keyEvent.m_accelerator, keyEvent.m_keyDown );
+ keyup_accelerators_add( keyEvent.m_accelerator, keyEvent.m_keyUp );
+}
+
+void KeyEvent_disconnect( const char* name ){
+ const KeyEvent& keyEvent = GlobalKeyEvents_find( name );
+ keydown_accelerators_remove( keyEvent.m_accelerator );
+ keyup_accelerators_remove( keyEvent.m_accelerator );
+}
+
+void CamWnd_registerCommands( CamWnd& camwnd ){
+ GlobalKeyEvents_insert( "CameraForward", Accelerator( GDK_Up ),
+ ReferenceCaller<camera_t, Camera_MoveForward_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveForward_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraBack", Accelerator( GDK_Down ),
+ ReferenceCaller<camera_t, Camera_MoveBack_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveBack_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraLeft", Accelerator( GDK_Left ),
+ ReferenceCaller<camera_t, Camera_RotateLeft_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_RotateLeft_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraRight", Accelerator( GDK_Right ),
+ ReferenceCaller<camera_t, Camera_RotateRight_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_RotateRight_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraStrafeRight", Accelerator( GDK_period ),
+ ReferenceCaller<camera_t, Camera_MoveRight_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveRight_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraStrafeLeft", Accelerator( GDK_comma ),
+ ReferenceCaller<camera_t, Camera_MoveLeft_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveLeft_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraUp", Accelerator( 'D' ),
+ ReferenceCaller<camera_t, Camera_MoveUp_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveUp_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraDown", Accelerator( 'C' ),
+ ReferenceCaller<camera_t, Camera_MoveDown_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveDown_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraAngleDown", Accelerator( 'A' ),
+ ReferenceCaller<camera_t, Camera_PitchDown_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_PitchDown_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraAngleUp", Accelerator( 'Z' ),
+ ReferenceCaller<camera_t, Camera_PitchUp_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_PitchUp_KeyUp>( camwnd.getCamera() )
+ );
+
+ GlobalKeyEvents_insert( "CameraFreeMoveForward", Accelerator( GDK_Up ),
+ FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveBack", Accelerator( GDK_Down ),
+ FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveLeft", Accelerator( GDK_Left ),
+ FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveRight", Accelerator( GDK_Right ),
+ FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveUp", Accelerator( 'D' ),
+ FreeMoveCameraMoveUpKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveUpKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveDown", Accelerator( 'C' ),
+ FreeMoveCameraMoveDownKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveDownKeyUpCaller( camwnd.getCamera() )
+ );
+
+ GlobalCommands_insert( "CameraForward", ReferenceCaller<camera_t, Camera_MoveForward_Discrete>( camwnd.getCamera() ), Accelerator( GDK_Up ) );
+ GlobalCommands_insert( "CameraBack", ReferenceCaller<camera_t, Camera_MoveBack_Discrete>( camwnd.getCamera() ), Accelerator( GDK_Down ) );
+ GlobalCommands_insert( "CameraLeft", ReferenceCaller<camera_t, Camera_RotateLeft_Discrete>( camwnd.getCamera() ), Accelerator( GDK_Left ) );
+ GlobalCommands_insert( "CameraRight", ReferenceCaller<camera_t, Camera_RotateRight_Discrete>( camwnd.getCamera() ), Accelerator( GDK_Right ) );
+ GlobalCommands_insert( "CameraStrafeRight", ReferenceCaller<camera_t, Camera_MoveRight_Discrete>( camwnd.getCamera() ), Accelerator( GDK_period ) );
+ GlobalCommands_insert( "CameraStrafeLeft", ReferenceCaller<camera_t, Camera_MoveLeft_Discrete>( camwnd.getCamera() ), Accelerator( GDK_comma ) );
+
+ GlobalCommands_insert( "CameraUp", ReferenceCaller<camera_t, Camera_MoveUp_Discrete>( camwnd.getCamera() ), Accelerator( 'D' ) );
+ GlobalCommands_insert( "CameraDown", ReferenceCaller<camera_t, Camera_MoveDown_Discrete>( camwnd.getCamera() ), Accelerator( 'C' ) );
+ GlobalCommands_insert( "CameraAngleUp", ReferenceCaller<camera_t, Camera_PitchUp_Discrete>( camwnd.getCamera() ), Accelerator( 'A' ) );
+ GlobalCommands_insert( "CameraAngleDown", ReferenceCaller<camera_t, Camera_PitchDown_Discrete>( camwnd.getCamera() ), Accelerator( 'Z' ) );
+}
+
+void CamWnd_Move_Enable( CamWnd& camwnd ){
+ KeyEvent_connect( "CameraForward" );
+ KeyEvent_connect( "CameraBack" );
+ KeyEvent_connect( "CameraLeft" );
+ KeyEvent_connect( "CameraRight" );
+ KeyEvent_connect( "CameraStrafeRight" );
+ KeyEvent_connect( "CameraStrafeLeft" );
+ KeyEvent_connect( "CameraUp" );
+ KeyEvent_connect( "CameraDown" );
+ KeyEvent_connect( "CameraAngleUp" );
+ KeyEvent_connect( "CameraAngleDown" );
+}