Browse Source

iphone touches

David Rose 16 years ago
parent
commit
09f8d67a8a

+ 37 - 0
panda/src/iphone/eaglView.mm

@@ -64,6 +64,8 @@
     viewFramebuffer = 0;
     viewRenderbuffer = 0;
     depthRenderbuffer = 0;
+
+    self.multipleTouchEnabled = YES;
   }
   return self;
 }
@@ -73,6 +75,41 @@
   [context presentRenderbuffer:GL_RENDERBUFFER_OES];
 }
 
+- (void)touchesBegan: (NSSet *)touches 
+           withEvent: (UIEvent *)event
+{
+  // Pass the multi-touch input to the _window for processing.
+  _window->touches_began(touches, event);
+  [super touchesBegan: touches withEvent: event];
+}
+
+- (void)touchesMoved: (NSSet *)touches 
+           withEvent: (UIEvent *)event
+{
+  _window->touches_moved(touches, event);
+  [super touchesMoved: touches withEvent: event];
+}
+
+- (void)touchesEnded: (NSSet *)touches 
+           withEvent: (UIEvent *)event
+{
+  _window->touches_ended(touches, event);
+  [super touchesEnded: touches withEvent: event];
+}
+
+- (void)touchesCancelled: (NSSet *)touches 
+               withEvent: (UIEvent *)event
+{
+  _window->touches_cancelled(touches, event);
+  [super touchesCancelled: touches withEvent: event];
+}
+
+/*
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 
+*/
+
 
 - (void)layoutSubviews {
   [EAGLContext setCurrentContext:context];

+ 11 - 3
panda/src/iphone/iPhoneGraphicsWindow.h

@@ -21,6 +21,8 @@
 #include "glesgsg.h"
 #import "eaglView.h"
 
+#import <UIKit/UIKit.h>
+
 ////////////////////////////////////////////////////////////////////
 //       Class : IPhoneGraphicsWindow
 // Description : An interface to the osx/ system for managing GL
@@ -47,20 +49,26 @@ public:
   virtual void clear_pipe();
 
   void rotate_window();
+  void touches_began(NSSet *touches, UIEvent *event);
+  void touches_moved(NSSet *touches, UIEvent *event);
+  void touches_ended(NSSet *touches, UIEvent *event);
+  void touches_cancelled(NSSet *touches, UIEvent *event);
+
+  CGPoint get_average_location(NSSet *touches);
+
 
 protected:
   virtual void close_window();
   virtual bool open_window();
 
 private:
-  void system_close_window();
-  void system_set_window_foreground(bool foreground);	
-
   void set_pointer_in_window(int x, int y);
   void set_pointer_out_of_window();
+  void handle_button_delta(int num_touches);
 
 private:
   EAGLView *_gl_view; 
+  int _last_buttons;
 
 public:
   static TypeHandle get_class_type() {

+ 219 - 79
panda/src/iphone/iPhoneGraphicsWindow.mm

@@ -57,6 +57,7 @@ IPhoneGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
   DCAST_INTO_V(ipipe, _pipe);
   ipipe->_graphics_windows.insert(this);
   _gl_view = nil;
+  _last_buttons = 0;
 
   GraphicsWindowInputDevice device =
     GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard/mouse");
@@ -75,29 +76,6 @@ IPhoneGraphicsWindow::
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: IPhoneGraphicsWindow::set_pointer_in_window
-//       Access: Private
-//  Description: Indicates the mouse pointer is seen within the
-//               window.
-////////////////////////////////////////////////////////////////////
-void IPhoneGraphicsWindow::
-set_pointer_in_window(int x, int y) {
-  _input_devices[0].set_pointer_in_window(x, y);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: IPhoneGraphicsWindow::set_pointer_out_of_window
-//       Access: Private
-//  Description: Indicates the mouse pointer is no longer within the
-//               window.
-////////////////////////////////////////////////////////////////////
-void IPhoneGraphicsWindow::
-set_pointer_out_of_window() {
-  _input_devices[0].set_pointer_out_of_window();
-}
-
-
 ////////////////////////////////////////////////////////////////////
 //     Function: IPhoneGraphicsWindow::begin_frame
 //       Access: Public, Virtual
@@ -170,61 +148,6 @@ void IPhoneGraphicsWindow::
 begin_flip() {
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: IPhoneGraphicsWindow::close_window
-//       Access: Protected, Virtual
-//  Description: Closes the window right now. Called from the window
-//               thread.
-////////////////////////////////////////////////////////////////////
-void IPhoneGraphicsWindow::
-close_window() {
-  //  system_close_window();
-
-  WindowProperties properties;
-  properties.set_open(false);
-  system_changed_properties(properties);
-
-//  release_system_resources(false);
-  _gsg.clear();
-  _active = false;
-  GraphicsWindow::close_window();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: IPhoneGraphicsWindow::open_window
-//       Access: Protected, Virtual
-//  Description: Opens the window right now. Called from the window
-//               thread. Returns true if the window is successfully
-//               opened, or false if there was a problem.
-////////////////////////////////////////////////////////////////////
-bool IPhoneGraphicsWindow::
-open_window() {
-  nassertr(_gsg == (GraphicsStateGuardian *)NULL, false);
-
-  _gl_view = [ [ EAGLView alloc ] initWithFrame: 
-        [ [ UIScreen mainScreen ] applicationFrame ] 
-    ]; 
-  _gl_view->_window = this;
-  
-  IPhoneGraphicsPipe *iphonepipe = DCAST(IPhoneGraphicsPipe, _pipe);
-  nassertr(iphonepipe != NULL, false);
-
-  iphonepipe->_view_controller.view = _gl_view;
-  [ _gl_view layoutSubviews ];
-
-  _gsg = new IPhoneGraphicsStateGuardian(_engine, _pipe, NULL);
-
-  CGRect bounds = [_gl_view bounds];
-
-  _properties.set_size(bounds.size.width, bounds.size.height);
-  _properties.set_foreground(true);
-  _properties.set_minimized(false);
-  _properties.set_open(true);
-  _is_valid = true;
-
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: IPhoneGraphicsWindow::process_events
 //       Access: Protected, Virtual
@@ -285,7 +208,7 @@ clear_pipe() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: IPhoneGraphicsWindow::rotate_window
-//       Access: Public, Virtual
+//       Access: Public
 //  Description: Called in response to an orientation change event,
 //               this tells the window to resize itself according to
 //               the new orientation.
@@ -298,3 +221,220 @@ rotate_window() {
   properties.set_size(bounds.size.width, bounds.size.height);
   system_changed_properties(properties);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::touches_began
+//       Access: Public
+//  Description: Beginning a single- or multi-touch gesture.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+touches_began(NSSet *touches, UIEvent *event) {
+  // Average the position of all of the touches.
+  CGPoint location = get_average_location(touches);
+
+  set_pointer_in_window(location.x, location.y);
+  handle_button_delta([touches count]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::touches_moved
+//       Access: Public
+//  Description: Continuing a single- or multi-touch gesture.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+touches_moved(NSSet *touches, UIEvent *event) {
+  // Average the position of all of the touches.
+  CGPoint location = get_average_location(touches);
+
+  set_pointer_in_window(location.x, location.y);
+  handle_button_delta([touches count]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::touches_ended
+//       Access: Public
+//  Description: Finishing a single- or multi-touch gesture.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+touches_ended(NSSet *touches, UIEvent *event) {
+  set_pointer_out_of_window();
+  handle_button_delta(0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::touches_cancelled
+//       Access: Public
+//  Description: Cancelling a single- or multi-touch gesture.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+touches_cancelled(NSSet *touches, UIEvent *event) {
+  set_pointer_out_of_window();
+  handle_button_delta(0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::get_average_location
+//       Access: Public
+//  Description: Returns the average location of all of the indicated
+//               touches.
+////////////////////////////////////////////////////////////////////
+CGPoint IPhoneGraphicsWindow::
+get_average_location(NSSet *touches) {
+  NSEnumerator *enumerator = [ touches objectEnumerator ]; 
+  CGPoint sum;
+  sum.x = 0.0;
+  sum.y = 0.0;
+
+  UITouch *touch;
+  while ((touch = [ enumerator nextObject ])) {
+    CGPoint location = [ touch locationInView: _gl_view ];
+    sum.x += location.x;
+    sum.y += location.y;
+  }
+
+  int count = [touches count];
+  sum.x /= count;
+  sum.y /= count;
+  return sum;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::close_window
+//       Access: Protected, Virtual
+//  Description: Closes the window right now. Called from the window
+//               thread.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+close_window() {
+  //  system_close_window();
+
+  WindowProperties properties;
+  properties.set_open(false);
+  system_changed_properties(properties);
+
+//  release_system_resources(false);
+  _gsg.clear();
+  _active = false;
+  GraphicsWindow::close_window();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::open_window
+//       Access: Protected, Virtual
+//  Description: Opens the window right now. Called from the window
+//               thread. Returns true if the window is successfully
+//               opened, or false if there was a problem.
+////////////////////////////////////////////////////////////////////
+bool IPhoneGraphicsWindow::
+open_window() {
+  nassertr(_gsg == (GraphicsStateGuardian *)NULL, false);
+
+  _gl_view = [ [ EAGLView alloc ] initWithFrame: 
+        [ [ UIScreen mainScreen ] applicationFrame ] 
+    ]; 
+  _gl_view->_window = this;
+  
+  IPhoneGraphicsPipe *iphonepipe = DCAST(IPhoneGraphicsPipe, _pipe);
+  nassertr(iphonepipe != NULL, false);
+
+  iphonepipe->_view_controller.view = _gl_view;
+  [ _gl_view layoutSubviews ];
+
+  _gsg = new IPhoneGraphicsStateGuardian(_engine, _pipe, NULL);
+
+  CGRect bounds = [_gl_view bounds];
+
+  _properties.set_size(bounds.size.width, bounds.size.height);
+  _properties.set_foreground(true);
+  _properties.set_minimized(false);
+  _properties.set_open(true);
+  _is_valid = true;
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::set_pointer_in_window
+//       Access: Private
+//  Description: Indicates the mouse pointer is seen within the
+//               window.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+set_pointer_in_window(int x, int y) {
+  _input_devices[0].set_pointer_in_window(x, y);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::set_pointer_out_of_window
+//       Access: Private
+//  Description: Indicates the mouse pointer is no longer within the
+//               window.
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+set_pointer_out_of_window() {
+  _input_devices[0].set_pointer_out_of_window();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: IPhoneGraphicsWindow::handle_button_delta
+//       Access: Private
+//  Description: Used to emulate button events
+////////////////////////////////////////////////////////////////////
+void IPhoneGraphicsWindow::
+handle_button_delta(int num_touches) {
+  // For now, we'll just map the number of touches to the mouse button
+  // number.  1 touch is button 1, 2 touches is button 3 (because this
+  // is the normal secondary button), and 3 touches is button 2.
+
+  // This is just a cheesy remapping that will assist migrating
+  // applications from standard PC's to iPhone.  It also works well
+  // enough within the existing Panda mouse-input framework.  We
+  // should expose the full multitouch functionality eventually, but
+  // really, the whole mouse-input framework needs a bit of a
+  // redesign.
+
+  int new_buttons;
+  switch (num_touches) {
+  case 0:
+    new_buttons = 0x00;
+    break;
+  case 1:
+    new_buttons = 0x01;
+    break;
+  case 2:
+    new_buttons = 0x04;
+    break;
+  case 3:
+  default:
+    new_buttons = 0x02;
+    break;
+  }
+
+  int changed = _last_buttons ^ new_buttons;
+
+  if (changed & 0x01) {
+    if (new_buttons & 0x01) {
+      _input_devices[0].button_down(MouseButton::one());
+    } else {
+      _input_devices[0].button_up(MouseButton::one());
+    }
+  }
+
+  if (changed & 0x04) {
+    if (new_buttons & 0x04) {
+      _input_devices[0].button_down(MouseButton::two());
+    } else {
+      _input_devices[0].button_up(MouseButton::two());
+    }
+  }
+
+  if (changed & 0x02) {
+    if (new_buttons & 0x02) {
+      _input_devices[0].button_down(MouseButton::three());
+    } else {
+      _input_devices[0].button_up(MouseButton::three());
+    }
+  }
+
+  _last_buttons = new_buttons;
+}

+ 8 - 2
panda/src/tform/trackball.cxx

@@ -48,6 +48,7 @@ Trackball(const string &name) :
   _rotscale = 0.3f;
   _fwdscale = 0.3f;
 
+  _last_button = 0;
   _lastx = _lasty = 0.5f;
 
   _rotation = LMatrix4f::ident_mat();
@@ -582,11 +583,16 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &input,
     
     float x = this_x - _lastx;
     float y = this_y - _lasty;
+
+    if (this_button == _last_button) {
+      apply(x, y, this_button);
+    }
     
-    apply(x, y, this_button);
-    
+    _last_button = this_button;
     _lastx = this_x;
     _lasty = this_y;
+  } else {
+    _last_button = 0;
   }
 
   // Now send our matrix down the pipe.

+ 1 - 1
panda/src/tform/trackball.h

@@ -101,7 +101,7 @@ private:
   void reextract();
   void recompute();
 
-
+  int _last_button;
   float _lastx, _lasty;
 
   float _rotscale;