+gboolean selection_button_press( ui::Widget 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( ui::Widget 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( ui::Widget widget ){
+ auto allocation = widget.dimensions();
+ return WindowVector( static_cast<float>( allocation.width / 2 ), static_cast<float>(allocation.height / 2 ) );
+}
+
+gboolean selection_button_press_freemove( ui::Widget 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( ui::Widget 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( ui::Widget widget, GdkEventMotion *event, WindowObserver* observer ){
+ observer->onMouseMotion( windowvector_for_widget_centre( widget ), modifiers_for_state( event->state ) );
+ return FALSE;
+}
+
+gboolean wheelmove_scroll( ui::Widget 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( ui::Widget 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( ui::Widget 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_KEY_Up ),
+ ReferenceCaller<camera_t, Camera_MoveForward_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveForward_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraBack", Accelerator( GDK_KEY_Down ),
+ ReferenceCaller<camera_t, Camera_MoveBack_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveBack_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraLeft", Accelerator( GDK_KEY_Left ),
+ ReferenceCaller<camera_t, Camera_RotateLeft_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_RotateLeft_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraRight", Accelerator( GDK_KEY_Right ),
+ ReferenceCaller<camera_t, Camera_RotateRight_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_RotateRight_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraStrafeRight", Accelerator( GDK_KEY_period ),
+ ReferenceCaller<camera_t, Camera_MoveRight_KeyDown>( camwnd.getCamera() ),
+ ReferenceCaller<camera_t, Camera_MoveRight_KeyUp>( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraStrafeLeft", Accelerator( GDK_KEY_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_KEY_Up ),
+ FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveBack", Accelerator( GDK_KEY_Down ),
+ FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveLeft", Accelerator( GDK_KEY_Left ),
+ FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ),
+ FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() )
+ );
+ GlobalKeyEvents_insert( "CameraFreeMoveRight", Accelerator( GDK_KEY_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_KEY_Up ) );
+ GlobalCommands_insert( "CameraBack", ReferenceCaller<camera_t, Camera_MoveBack_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Down ) );
+ GlobalCommands_insert( "CameraLeft", ReferenceCaller<camera_t, Camera_RotateLeft_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Left ) );
+ GlobalCommands_insert( "CameraRight", ReferenceCaller<camera_t, Camera_RotateRight_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Right ) );
+ GlobalCommands_insert( "CameraStrafeRight", ReferenceCaller<camera_t, Camera_MoveRight_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_period ) );
+ GlobalCommands_insert( "CameraStrafeLeft", ReferenceCaller<camera_t, Camera_MoveLeft_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_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" );
+}
+
+void CamWnd_Move_Disable( CamWnd& camwnd ){
+ KeyEvent_disconnect( "CameraForward" );
+ KeyEvent_disconnect( "CameraBack" );
+ KeyEvent_disconnect( "CameraLeft" );
+ KeyEvent_disconnect( "CameraRight" );
+ KeyEvent_disconnect( "CameraStrafeRight" );
+ KeyEvent_disconnect( "CameraStrafeLeft" );
+ KeyEvent_disconnect( "CameraUp" );
+ KeyEvent_disconnect( "CameraDown" );
+ KeyEvent_disconnect( "CameraAngleUp" );
+ KeyEvent_disconnect( "CameraAngleDown" );
+}
+
+void CamWnd_Move_Discrete_Enable( CamWnd& camwnd ){
+ command_connect_accelerator( "CameraForward" );
+ command_connect_accelerator( "CameraBack" );
+ command_connect_accelerator( "CameraLeft" );
+ command_connect_accelerator( "CameraRight" );
+ command_connect_accelerator( "CameraStrafeRight" );
+ command_connect_accelerator( "CameraStrafeLeft" );
+ command_connect_accelerator( "CameraUp" );
+ command_connect_accelerator( "CameraDown" );
+ command_connect_accelerator( "CameraAngleUp" );
+ command_connect_accelerator( "CameraAngleDown" );
+}
+
+void CamWnd_Move_Discrete_Disable( CamWnd& camwnd ){
+ command_disconnect_accelerator( "CameraForward" );
+ command_disconnect_accelerator( "CameraBack" );
+ command_disconnect_accelerator( "CameraLeft" );
+ command_disconnect_accelerator( "CameraRight" );
+ command_disconnect_accelerator( "CameraStrafeRight" );
+ command_disconnect_accelerator( "CameraStrafeLeft" );
+ command_disconnect_accelerator( "CameraUp" );
+ command_disconnect_accelerator( "CameraDown" );
+ command_disconnect_accelerator( "CameraAngleUp" );
+ command_disconnect_accelerator( "CameraAngleDown" );
+}
+
+void CamWnd_Move_Discrete_Import( CamWnd& camwnd, bool value ){
+ if ( g_camwindow_globals_private.m_bCamDiscrete ) {
+ CamWnd_Move_Discrete_Disable( camwnd );
+ }
+ else