]> git.mxchange.org Git - flightgear.git/commitdiff
More work on the configurable mouse. Mouse motion is now configurable
authordavid <david>
Tue, 26 Mar 2002 13:45:44 +0000 (13:45 +0000)
committerdavid <david>
Tue, 26 Mar 2002 13:45:44 +0000 (13:45 +0000)
as well as mouse clicks.  You must configure with --with-new-mouse to
get this.

src/Input/input.cxx
src/Input/input.hxx
src/Main/fg_commands.cxx
src/Main/main.cxx

index 349226a0302afae27b8d959e2b96119491ef3105..20024c4d291b5d43cf9c786719931bd77e9924bf 100644 (file)
@@ -143,13 +143,10 @@ FGBinding::fire () const
 }
 
 void
-FGBinding::fire (int x, int y) const
+FGBinding::fire (double offset, double max) const
 {
   if (test()) {
-    if (x >= 0)
-      _arg->setIntValue("x-pos", x);
-    if (y >= 0)
-      _arg->setIntValue("y-pos", y);
+    _arg->setDoubleValue("offset", offset/max);
     fire();
   }
 }
@@ -180,8 +177,6 @@ FGInput current_input;
 
 
 FGInput::FGInput ()
-  : _current_mouse_mode(-1),
-    _last_mouse_mode(-1)
 {
   // no op
 }
@@ -197,6 +192,16 @@ FGInput::init ()
   _init_keyboard();
   _init_joystick();
   _init_mouse();
+
+  glutKeyboardFunc(GLUTkey);
+  glutKeyboardUpFunc(GLUTkeyup);
+  glutSpecialFunc(GLUTspecialkey);
+  glutSpecialUpFunc(GLUTspecialkeyup);
+#ifdef FG_NEW_MOUSE
+  glutMouseFunc (GLUTmouse);
+  glutMotionFunc (GLUTmotion);
+  glutPassiveMotionFunc (GLUTmotion);
+#endif
 }
 
 void
@@ -349,22 +354,65 @@ FGInput::doKey (int k, int modifiers, int x, int y)
 void
 FGInput::doMouseClick (int b, int updown, int x, int y)
 {
-  std::cout << "Mouse click " << b << ',' << updown << std::endl;
   int modifiers = FG_MOD_NONE; // FIXME: any way to get the real ones?
 
+  mouse &m = _mouse_bindings[0];
+
   if (b >= MAX_MOUSE_BUTTONS) {
     SG_LOG(SG_INPUT, SG_ALERT, "Mouse button " << b
           << " where only " << MAX_MOUSE_BUTTONS << " expected");
     return;
   }
 
-  _update_button(_mouse_bindings[0].buttons[b], modifiers, updown, x, y);
+  _update_button(m.modes[m.current_mode].buttons[b], modifiers, updown, x, y);
 }
 
 void
 FGInput::doMouseMotion (int x, int y)
 {
-  // TODO
+  int modifiers = FG_MOD_NONE; // FIXME: any way to get the real ones?
+
+  int xsize = fgGetInt("/sim/startup/xsize", 800);
+  int ysize = fgGetInt("/sim/startup/ysize", 600);
+  mouse &m = _mouse_bindings[0];
+  if (m.current_mode < 0 || m.current_mode >= m.nModes)
+    return;
+  mouse_mode &mode = m.modes[m.current_mode];
+  if (x != m.x) {
+    int delta = x - m.x;
+    for (int i = 0; i < mode.x_bindings[modifiers].size(); i++)
+      mode.x_bindings[modifiers][i]->fire(double(delta), double(xsize));
+  }
+  if (y != m.y) {
+    int delta = y - m.y;
+    for (int i = 0; i < mode.y_bindings[modifiers].size(); i++)
+      mode.y_bindings[modifiers][i]->fire(double(delta), double(ysize));
+  }
+
+                               // Constrain the mouse if requested
+  if (mode.constrained) {
+    bool need_warp = false;
+    if (x < 0) {
+      x = xsize - 1;
+      need_warp = true;
+    } else if (x >= xsize) {
+      x = 0;
+      need_warp = true;
+    }
+
+    if (y < 0) {
+      y = ysize - 1;
+      need_warp = true;
+    } else if (y >= ysize) {
+      y = 0;
+      need_warp = true;
+    }
+
+    if (need_warp)
+      glutWarpPointer(x, y);
+  }
+  m.x = x;
+  m.y = y;
 }
 
 void
@@ -539,40 +587,49 @@ FGInput::_init_mouse ()
 
   int j;
   for (int i = 0; i < MAX_MICE; i++) {
-    SGPropertyNode * mouse_node = mouse_nodes->getChild("mouse", i);
-
-                               // Read the cursor type for each mode.
-    _mouse_bindings[i].nModes = mouse_node->getIntValue("mode-count", 1);
-    _mouse_bindings[i].cursors = new int[_mouse_bindings[i].nModes];
-    SGPropertyNode * cursor_nodes =
-      mouse_node->getChild("mode-cursors", 0, true);
-    for (j = 0; j < _mouse_bindings[i].nModes; j++) {
-      const char * name = cursor_nodes->getChild("cursor", j, true)
-       ->getStringValue();
-      if (name[0] == '\0')
-       name = "inherit";
-      _mouse_bindings[i].cursors[j] = GLUT_CURSOR_INHERIT;
-      for (int k = 0; mouse_cursor_map[k].name != 0; k++) {
-       if (!strcmp(mouse_cursor_map[k].name, name)) {
-         _mouse_bindings[i].cursors[j] = mouse_cursor_map[k].cursor;
+    SGPropertyNode * mouse_node = mouse_nodes->getChild("mouse", i, true);
+    mouse &m = _mouse_bindings[i];
+
+                               // Read all the modes
+    m.nModes = mouse_node->getIntValue("mode-count", 1);
+    m.modes = new mouse_mode[m.nModes];
+
+    for (int j = 0; j < m.nModes; j++) {
+      int k;
+
+                               // Read the mouse cursor for this mode
+      SGPropertyNode * mode_node = mouse_node->getChild("mode", j, true);
+      const char * cursor_name =
+       mode_node->getStringValue("cursor", "inherit");
+      m.modes[j].cursor = GLUT_CURSOR_INHERIT;
+      for (k = 0; mouse_cursor_map[k].name != 0; k++) {
+       if (!strcmp(mouse_cursor_map[k].name, cursor_name)) {
+         m.modes[j].cursor = mouse_cursor_map[k].cursor;
          break;
        }
       }
-    }
 
-                               // Read the binding for each button
-    _mouse_bindings[i].buttons = new button[MAX_MOUSE_BUTTONS];
-    if (mouse_node == 0) {
-      SG_LOG(SG_INPUT, SG_DEBUG, "No bindings for mouse " << i);
-      mouse_node = mouse_nodes->getChild("mouse", i, true);
-    }
-    char buf[8];
-    for (j = 0; j < MAX_MOUSE_BUTTONS; j++) {
-      sprintf(buf, "%d", j);
-      SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << j);
-      _init_button(mouse_node->getChild("button", j),
-                  _mouse_bindings[i].buttons[j],
-                  buf);
+                               // Read other properties for this mode
+      m.modes[j].constrained = mode_node->getBoolValue("constrained", false);
+
+                               // Read the button bindings for this mode
+      m.modes[j].buttons = new button[MAX_MOUSE_BUTTONS];
+      char buf[8];
+      for (k = 0; k < MAX_MOUSE_BUTTONS; k++) {
+       sprintf(buf, "mouse button %d", k);
+       SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << k);
+       _init_button(mode_node->getChild("button", k),
+                    m.modes[j].buttons[k],
+                    buf);
+      }
+
+                               // Read the axis bindings for this mode
+      _read_bindings(mode_node->getChild("x-axis", 0, true),
+                    m.modes[j].x_bindings,
+                    FG_MOD_NONE);
+      _read_bindings(mode_node->getChild("y-axis", 0, true),
+                    m.modes[j].y_bindings,
+                    FG_MOD_NONE);
     }
   }
 }
@@ -665,15 +722,14 @@ FGInput::_update_joystick ()
 void
 FGInput::_update_mouse ()
 {
-  _current_mouse_mode = fgGetInt("/input/mice/mouse[0]/mode");
-  if (_current_mouse_mode != _last_mouse_mode) {
-    _last_mouse_mode = _current_mouse_mode;
-    if (_current_mouse_mode >= 0
-       && _current_mouse_mode < _mouse_bindings[0].nModes) {
-      glutSetCursor(_mouse_bindings[0].cursors[_current_mouse_mode]);
+  mouse &m = _mouse_bindings[0];
+  int mode =  fgGetInt("/input/mice/mouse[0]/mode");
+  if (mode != m.current_mode) {
+    m.current_mode = mode;
+    if (mode >= 0 && mode < m.nModes) {
+      glutSetCursor(m.modes[mode].cursor);
     } else {
-      SG_LOG(SG_INPUT, SG_DEBUG, "Mouse mode "
-            << _current_mouse_mode << " out of range");
+      SG_LOG(SG_INPUT, SG_DEBUG, "Mouse mode " << mode << " out of range");
       glutSetCursor(GLUT_CURSOR_INHERIT);
     }
   }
@@ -825,22 +881,49 @@ FGInput::joystick::~joystick ()
 }
 
 
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGInput::mouse_mode
+////////////////////////////////////////////////////////////////////////
+
+FGInput::mouse_mode::mouse_mode ()
+  : cursor(GLUT_CURSOR_INHERIT),
+    constrained(false),
+    buttons(0)
+{
+}
+
+FGInput::mouse_mode::~mouse_mode ()
+{
+                               // FIXME: memory leak
+//   for (int i = 0; i < FG_MOD_MAX; i++) {
+//     int j;
+//     for (j = 0; i < x_bindings[i].size(); j++)
+//       delete bindings[i][j];
+//     for (j = 0; j < y_bindings[i].size(); j++)
+//       delete bindings[i][j];
+//   }
+  delete [] buttons;
+}
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGInput::mouse
 ////////////////////////////////////////////////////////////////////////
 
 FGInput::mouse::mouse ()
-  : nModes(0),
-    cursors(0),
-    buttons(0)
+  : nModes(1),
+    current_mode(0),
+    x(-1),
+    y(-1),
+    modes(0)
 {
 }
 
 FGInput::mouse::~mouse ()
 {
-  delete [] cursors;
-  delete [] buttons;
+  delete [] modes;
 }
 
 
@@ -911,7 +994,7 @@ GLUTmouse (int button, int updown, int x, int y)
 void
 GLUTmotion (int x, int y)
 {
-  puMouse(x, y);
+//   puMouse(x, y);
 //   glutPostRedisplay();
   current_input.doMouseMotion(x, y);
 }
index 95731f8f056622b03a4e3da1e20f321983363ebd..f0c99491dd515d00b7c6c6222ee3e093fb0e7cd4 100644 (file)
@@ -123,9 +123,9 @@ public:
 
 
   /**
-   * Fire a binding with x and y positions.
+   * Fire a binding with a scaled movement (rather than absolute position).
    */
-  virtual void fire (int x, int y) const;
+  virtual void fire (double offset, double max) const;
 
 
   /**
@@ -246,7 +246,7 @@ private:
     MAX_JOYSTICK_BUTTONS = 32,
 
     MAX_MICE = 1,
-    MAX_MOUSE_BUTTONS = 3
+    MAX_MOUSE_BUTTONS = 8
   };
 
   typedef vector<FGBinding *> binding_list_t;
@@ -294,15 +294,31 @@ private:
   };
 
 
+  /**
+   * Settings for a mouse mode.
+   */
+  struct mouse_mode {
+    mouse_mode ();
+    virtual ~mouse_mode ();
+    int cursor;
+    bool constrained;
+    button * buttons;
+    binding_list_t x_bindings[FG_MOD_MAX];
+    binding_list_t y_bindings[FG_MOD_MAX];
+  };
+
+
   /**
    * Settings for a mouse.
    */
   struct mouse {
     mouse ();
     virtual ~mouse ();
+    int x;
+    int y;
     int nModes;
-    int * cursors;
-    button * buttons;
+    int current_mode;
+    mouse_mode * modes;
   };
 
 
@@ -374,9 +390,6 @@ private:
   joystick _joystick_bindings[MAX_JOYSTICKS];
   mouse _mouse_bindings[MAX_MICE];
 
-  int _current_mouse_mode;
-  int _last_mouse_mode;
-
 };
 
 
index 4ce64780da81e77950f458d59735a63756c30f01..b9060df069df77071fdaff772fe4eab561eb0f50 100644 (file)
@@ -52,6 +52,7 @@ public:
   virtual SGPropertyNode * getProp2 () const { return _prop2; }
   virtual const SGPropertyNode * getValue () const
     { return _value ? _value : &_dummy_0; }
+  virtual const bool hasStep () const { return _step != 0; }
   virtual const SGPropertyNode * getStep () const 
     { return _step ? _step : &_dummy_0; }
   virtual const SGPropertyNode * getMin () const { return _min; }
@@ -427,6 +428,8 @@ do_property_assign (const SGPropertyNode * arg, SGCommandState ** state)
  *
  * property: the name of the property to increment or decrement.
  * step: the amount of the increment or decrement (default: 0).
+ * offset: a normalized amount to offset by (if step is not present).
+ * factor: the amount by which to multiply the offset (if step is not present).
  * min: the minimum allowed value (default: no minimum).
  * max: the maximum allowed value (default: no maximum).
  * wrap: true if the value should be wrapped when it passes min or max;
@@ -438,20 +441,40 @@ do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
 {
   if (*state == 0)
     *state = new PropertyCommandState(arg);
+  bool hasStep = ((PropertyCommandState *)(*state))->hasStep();
   SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp();
   const SGPropertyNode * step = ((PropertyCommandState *)(*state))->getStep();
+  const SGPropertyNode * offset =
+    ((PropertyCommandState *)(*state))->getOffset();
+  const SGPropertyNode * factor =
+    ((PropertyCommandState *)(*state))->getFactor();
   const SGPropertyNode * min = ((PropertyCommandState *)(*state))->getMin();
   const SGPropertyNode * max = ((PropertyCommandState *)(*state))->getMax();
   bool wrap = ((PropertyCommandState *)(*state))->getWrap()->getBoolValue();
 
+  double amount = 0;
+  if (!hasStep) {
+    amount = offset->getDoubleValue() * factor->getDoubleValue();
+  }
+
+
   switch (prop->getType()) {
   case SGPropertyNode::BOOL:
-    if (step->getBoolValue())
+    bool value;
+    if (hasStep)
+      value = step->getBoolValue();
+    else
+      value = amount;
+    if (value)
       return prop->setBoolValue(!prop->getBoolValue());
     else
       return true;
   case SGPropertyNode::INT: {
-    int value = prop->getIntValue() + step->getIntValue();
+    int value;
+    if (hasStep)
+      value = prop->getIntValue() + step->getIntValue();
+    else
+      value = prop->getIntValue() + int(amount);
     if (min && (value < min->getIntValue())) {
       if (wrap && max)
        value = max->getIntValue();
@@ -467,7 +490,11 @@ do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
     return prop->setIntValue(value);
   }
   case SGPropertyNode::LONG: {
-    long value = prop->getLongValue() + step->getLongValue();
+    long value;
+    if (hasStep)
+      value = prop->getLongValue() + step->getLongValue();
+    else
+      value = prop->getLongValue() + long(amount);
     if (min && (value < min->getLongValue())) {
       if (wrap && max)
        value = max->getLongValue();
@@ -483,7 +510,11 @@ do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
     return prop->setLongValue(value);
   }
   case SGPropertyNode::FLOAT: {
-    float value = prop->getFloatValue() + step->getFloatValue();
+    float value;
+    if (hasStep)
+      value = prop->getFloatValue() + step->getFloatValue();
+    else
+      value = prop->getFloatValue() + float(amount);
     if (min && (value < min->getFloatValue())) {
       if (wrap && max)
        value = max->getFloatValue();
@@ -501,7 +532,11 @@ do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
   case SGPropertyNode::DOUBLE:
   case SGPropertyNode::UNSPECIFIED:
   case SGPropertyNode::NONE: {
-    double value = prop->getDoubleValue() + step->getDoubleValue();
+    double value;
+    if (hasStep)
+      value = prop->getDoubleValue() + step->getDoubleValue();
+    else
+      value = prop->getDoubleValue() + amount;
     if (min && (value < min->getDoubleValue())) {
       if (wrap && max)
        value = max->getDoubleValue();
index 7ddd9f41f94ec8a6c8f9cbf077aa5e9b1c53bb35..cdd158a13c5f47a01da861227bd067555b59fc23 100644 (file)
@@ -1259,17 +1259,9 @@ int fgGlutInitEvents( void ) {
     // call fgReshape() on window resizes
     glutReshapeFunc( fgReshape );
 
-    // call GLUTkey() on keyboard event
-    glutKeyboardFunc(GLUTkey);
-    glutKeyboardUpFunc(GLUTkeyup);
-    glutSpecialFunc(GLUTspecialkey);
-    glutSpecialUpFunc(GLUTspecialkeyup);
-
-#if FG_NEW_MOUSE
-    glutMouseFunc (GLUTmouse);
-    glutMotionFunc (GLUTmotion);
-    glutPassiveMotionFunc (GLUTmotion);
-#else
+    // keyboard and mouse callbacks are set in FGInput::init
+
+#ifndef FG_NEW_MOUSE
     // call guiMouseFunc() whenever our little rodent is used
     glutMouseFunc ( guiMouseFunc );
     glutMotionFunc (guiMotionFunc );