static int SceneClick()

in layer1/Scene.cpp [3505:4384]


static int SceneClick(Block * block, int button, int x, int y, int mod, double when)
{
  PyMOLGlobals *G = block->m_G;
  CScene *I = G->Scene;
  CObject *obj;
  ObjectMolecule *objMol;
  OrthoLineType buffer, buf1, buf2;
  WordType selName = "";
  int mode = 0;        /* trying to work around something... */
  int atIndex;
  const char *sel_mode_kw = "";
  int is_single_click = ((button == P_GLUT_SINGLE_LEFT) ||
                         (button == P_GLUT_SINGLE_MIDDLE) ||
                         (button == P_GLUT_SINGLE_RIGHT));
  int click_handled = false;
  int click_side = 0;

  if(!is_single_click) {
    int click_handled = false;

    if(I->ButtonsShown) {

      int i;
      SceneElem *elem = I->SceneVLA;

      /* check & handle a click on the scrollbar */
      if(I->ScrollBarActive) {
        if((x - I->rect.left) < (SceneScrollBarWidth + SceneScrollBarMargin)) {
          click_handled = true;
          I->m_ScrollBar.click(button, x, y, mod);
        }
      }
      if(!click_handled) {
        for(i = 0; i < I->NScene; i++) {
          if(elem->drawn &&
             (x >= elem->x1) && (y >= elem->y1) && (x < elem->x2) && (y < elem->y2)) {
            click_handled = true;
            break;
          }
          elem++;
        }
      }
    }

    if(!click_handled) {
      // check for double click (within 0.35s and 10sq. pixels
      if(((ButModeCheckPossibleSingleClick(G, button, mod) || (!mod))
          && ((when - I->LastClickTime) < cDoubleTime))) {
        int dx, dy;
        dx = abs(I->LastWinX - x);
        dy = abs(I->LastWinY - y);
        if((dx < 10) && (dy < 10) && (I->LastButton == button)) {
          switch (button) {
          case P_GLUT_LEFT_BUTTON:
            button = P_GLUT_DOUBLE_LEFT;
            break;
          case P_GLUT_MIDDLE_BUTTON:
            button = P_GLUT_DOUBLE_MIDDLE;
            break;
          case P_GLUT_RIGHT_BUTTON:
            button = P_GLUT_DOUBLE_RIGHT;
            break;
          }
        }
      }
    } // end not click handled 

    if(ButModeCheckPossibleSingleClick(G, button, mod) || (!mod)) {
      I->PossibleSingleClick = 1;
    } else {
      const char *but_mode_name = SettingGetGlobal_s(G, cSetting_button_mode_name);
      if(but_mode_name && but_mode_name[0] == '1') {
        I->PossibleSingleClick = 1;
      } else {
        I->PossibleSingleClick = 0;
      }
    }
  } // end not single-click

  I->LastWinX = x;
  I->LastWinY = y;
  I->LastClickTime = when;
  I->LastButton = button;
  I->LastMod = mod;
  I->Threshold = 0;

  SceneGetCenter(G, I->LastClickVertex);
  {
    float vScale = SceneGetExactScreenVertexScale(G, I->LastClickVertex);
    float v[3];
    v[0] = -(I->Width / 2 - (x - I->rect.left)) * vScale;
    v[1] = -(I->Height / 2 - (y - I->rect.bottom)) * vScale;
    v[2] = 0;
    MatrixInvTransformC44fAs33f3f(I->RotMatrix, v, v);
    add3f(v, I->LastClickVertex, I->LastClickVertex);
  }

  if(I->ButtonsShown) {
    int i;
    SceneElem *elem = I->SceneVLA;

    if(I->ScrollBarActive) {
      if((x - I->rect.left) < (SceneScrollBarWidth + SceneScrollBarMargin)) {
        click_handled = true;
        I->m_ScrollBar.click(button, x, y, mod);
      }
    }
    if(!click_handled) {
      for(i = 0; i < I->NScene; i++) {
        if(elem->drawn &&
           (x >= elem->x1) && (y >= elem->y1) && (x < elem->x2) && (y < elem->y2)) {
          switch (button) {
          case P_GLUT_LEFT_BUTTON:     /* normal activate (with interpolation) */
            I->Pressed = i;
            I->Over = i;
            I->PressMode = 1;
            SceneDirty(G);
            click_handled = true;
            break;
          case P_GLUT_MIDDLE_BUTTON:   /* rapid browse mode */
            I->Pressed = i;
            I->PressMode = 2;
            I->Over = i;
            click_handled = true;
            {
              const char *cur_name = SettingGetGlobal_s(G, cSetting_scene_current_name);
              int animate = -1;
              if(mod & cOrthoCTRL)
                animate = 0;
              if(cur_name && elem->name && (strcmp(cur_name, elem->name))) {
                OrthoLineType buffer;
                sprintf(buffer, "cmd.scene('''%s''',animate=%d)", elem->name, animate);
                PParse(G, buffer);
                PFlush(G);
                PLog(G, buffer, cPLog_pym);
              }
            }
            break;
          case P_GLUT_RIGHT_BUTTON:    /* drag or menu... */
            I->Pressed = i;
            I->PressMode = 3;
            I->Over = i;
            click_handled = true;
            break;
          }
          break;
        }
        elem++;
      }
    }
  }
  if(!click_handled) {

    mode = ButModeTranslate(G, button, mod);

    I->Button = button;
    I->SculptingSave = 0;
    switch (mode) {
    case cButModeScaleSlabExpand:
      SceneNoteMouseInteraction(G);
      SceneClip(G, 5, 1.0F + (0.2 * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale)),
                NULL, 0);
      break;
    case cButModeScaleSlabShrink:
      SceneNoteMouseInteraction(G);
      SceneClip(G, 5, 1.0F - (0.2 * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale)),
                NULL, 0);
      break;
    case cButModeMoveSlabForward:
      SceneNoteMouseInteraction(G);
      {
        float old_front = I->Front;
        float old_back = I->Back;
        float old_origin = -I->Pos[2];
        SceneClip(G, 6, 0.1F * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale), NULL,
                  0);
        SceneDoRoving(G, old_front, old_back, old_origin, true, false);
      }
      break;
    case cButModeMoveSlabBackward:
      SceneNoteMouseInteraction(G);
      {
        float old_front = I->Front;
        float old_back = I->Back;
        float old_origin = -I->Pos[2];

        SceneClip(G, 6, -0.1F * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale), NULL,
                  0);
        SceneDoRoving(G, old_front, old_back, old_origin, true, false);
      }
      break;
    case cButModeZoomForward:
      SceneNoteMouseInteraction(G);
      {
        float factor = -((I->FrontSafe + I->BackSafe) / 2) * 0.1 *
          SettingGetGlobal_f(G, cSetting_mouse_wheel_scale);
        if(factor <= 0.0F) {
          I->Pos[2] += factor;
          I->Front -= factor;
          I->Back -= factor;
          UpdateFrontBackSafe(I);
        }
      }
      break;
    case cButModeZoomBackward:
      SceneNoteMouseInteraction(G);
      {
        float factor = ((I->FrontSafe + I->BackSafe) / 2) * 0.1F
          * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale);
        if(factor >= 0.0F) {
          I->Pos[2] += factor;
          I->Front -= factor;
          I->Back -= factor;
          UpdateFrontBackSafe(I);
        }
      }
      break;
    case cButModeMoveSlabAndZoomForward:
      SceneNoteMouseInteraction(G);
      {
        float old_front = I->Front;
        float old_back = I->Back;
        float old_origin = -I->Pos[2];
        SceneClip(G, 6, 0.1F * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale), NULL,
                  0);
        SceneDoRoving(G, old_front, old_back, old_origin, true, true);
      }
      break;
    case cButModeMoveSlabAndZoomBackward:
      SceneNoteMouseInteraction(G);
      {
        float old_front = I->Front;
        float old_back = I->Back;
        float old_origin = -I->Pos[2];
        SceneClip(G, 6, -0.1F * SettingGetGlobal_f(G, cSetting_mouse_wheel_scale), NULL,
                  0);
        SceneDoRoving(G, old_front, old_back, old_origin, true, true);
      }
      break;
    case cButModeRectAdd:      /* deprecated */
    case cButModeRectSub:      /* deprecated */
    case cButModeRect:         /* deprecated */
    case cButModeSeleAddBox:
    case cButModeSeleSetBox:
    case cButModeSeleSubBox:
      return SceneLoopClick(block, button, x, y, mod);
      break;
    case cButModeRotDrag:
    case cButModeMovDrag:
    case cButModeMovDragZ:
      SceneNoteMouseInteraction(G);
      SceneDontCopyNext(G);

      y = y - I->margin.bottom;
      x = x - I->margin.left;

      if(stereo_via_adjacent_array(I->StereoMode))
        x = get_stereo_x(x, NULL, I->Width, NULL);

      I->LastX = x;
      I->LastY = y;
      EditorReadyDrag(G, SettingGetGlobal_i(G, cSetting_state) - 1);

      if(EditorDraggingObjectMatrix(G)) {
        obj = EditorDragObject(G);
        if(obj) {
          if(SettingGetGlobal_b(G,cSetting_movie_auto_store)) {
            ObjectTranslateTTT(obj, NULL, true);
            I->MotionGrabbedObj = obj;
            obj->Grabbed = true;
            if(SettingGetGlobal_i(G,cSetting_movie_auto_interpolate)) {
              I->ReinterpolateFlag = true;
              I->ReinterpolateObj = obj;
            }
          } else {
            ObjectTranslateTTT(obj,NULL,false);
          }
        }
      }
      break;
    case cButModeRotXYZ:
    case cButModeTransXY:
    case cButModeTransZ:
    case cButModeClipNF:
    case cButModeClipN:
    case cButModeClipF:
    case cButModeRotZ:
    case cButModeInvRotZ:
    case cButModeRotL:
    case cButModeMovL:
    case cButModeMvzL:
      SceneNoteMouseInteraction(G);
      SceneDontCopyNext(G);

      y = y - I->margin.bottom;
      x = x - I->margin.left;

      if(stereo_via_adjacent_array(I->StereoMode))
        x = get_stereo_x(x, NULL, I->Width, NULL);

      I->LastX = x;
      I->LastY = y;
      break;
    case cButModePickAtom1:
    case cButModePickAtom:
    case cButModeMenu:
      if(stereo_via_adjacent_array(I->StereoMode))
        x = get_stereo_x(x, NULL, I->Width, NULL);

      if(SceneDoXYPick(G, x, y, click_side)) {
        obj = (CObject *) I->LastPicked.context.object;
        y = y - I->margin.bottom;
        x = x - I->margin.left;
        I->LastX = x;
        I->LastY = y;
        switch (obj->type) {
        case cObjectMolecule:
          switch (mode) {
          case cButModeMenu:
            {
              ObjectMolecule *objMol = (ObjectMolecule *) obj;
              int active_sele = ExecutiveGetActiveSele(G);
              if(active_sele
                 && SelectorIsMember(G,
                                     objMol->AtomInfo[I->LastPicked.src.index].selEntry,
                                     active_sele)) {
		/* user clicked on a selected atom */
                ObjectNameType name;
                ExecutiveGetActiveSeleName(G, name, false,
                                           SettingGetGlobal_i(G, cSetting_logging));
                MenuActivate2Arg(G, I->LastWinX, I->LastWinY + 20,      /* selection menu */
                                 I->LastWinX, I->LastWinY,
                                 is_single_click, "pick_sele", name, name);
              } else {
		/* user clicked on an atom not in a selection */
                obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
                ObjectMoleculeGetAtomSeleLog((ObjectMolecule *) obj,
                                             I->LastPicked.src.index, buf1, false);
                MenuActivate2Arg(G, I->LastWinX, I->LastWinY + 20, I->LastWinX,
                                 I->LastWinY, is_single_click, "pick_menu", buffer, buf1);
              }
            }
            break;
          case cButModePickAtom1:
            if(obj && obj->type == cObjectMolecule) {
              if(Feedback(G, FB_Scene, FB_Results)) {
                if(obj->fDescribeElement)
                  obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
                PRINTF " You clicked %s -> (%s)\n", buffer, cEditorSele1 ENDF(G);
              }
              if(SettingGetGlobal_i(G, cSetting_logging)) {
                objMol = (ObjectMolecule *) obj;
                ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buffer,
                                             false);
                sprintf(buf2, "cmd.edit(\"%s\",pkresi=1)", buffer);
                PLog(G, buf2, cPLog_pym);
              }
              OrthoRestorePrompt(G);
              sprintf(buffer, "%s`%d", obj->Name, I->LastPicked.src.index + 1);
              EditorInactivate(G);
              SelectorCreate(G, cEditorSele1, buffer, NULL, true, NULL);
              EditorActivate(G, SettingGetGlobal_i(G, cSetting_state) - 1, false);
              if(EditorActive(G)) {
                EditorDefineExtraPks(G);
              }
              WizardDoPick(G, 0, I->LastPicked.context.state);
            }
            break;
          case cButModePickAtom:
            if(obj && obj->type == cObjectMolecule) {
              WordType name;
              if(obj->fDescribeElement)
                obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
              if(EditorIsBondMode(G)
                 /* &&!(EditorIsAnActiveObject(G,(ObjectMolecule*)obj)) */
                ) {
                EditorInactivate(G);
                EditorLogState(G, false);
              }
              if((!EditorIsBondMode(G)) &&
                 EditorDeselectIfSelected(G,
                                          (ObjectMolecule *) obj, I->LastPicked.src.index,
                                          true)) {
                PRINTF " You unpicked %s.", buffer ENDF(G);
                if(EditorActive(G))
                  EditorDefineExtraPks(G);
                EditorLogState(G, false);
              } else {
                if(EditorIsBondMode(G) &&
                   EditorDeselectIfSelected(G,
                                            (ObjectMolecule *) obj,
                                            I->LastPicked.src.index, false)) {
                  EditorInactivate(G);
                }
                EditorGetNextMultiatom(G, name);

                PRINTFB(G, FB_Scene, FB_Results) " You clicked %s -> (%s)\n", buffer,
                  name ENDFB(G);
                /* TODO: logging */

                sprintf(buffer, "%s`%d", obj->Name, I->LastPicked.src.index + 1);
                ExecutiveDelete(G, name);
                SelectorCreate(G, name, buffer, NULL, true, NULL);
                EditorActivate(G, SettingGetGlobal_i(G, cSetting_state) - 1, false);
                if(EditorActive(G)) {
                  EditorDefineExtraPks(G);
                }
                EditorLogState(G, false);
                WizardDoPick(G, 0, I->LastPicked.context.state);
              }
            }
            break;
          }
          break;
        case cObjectGadget:
          break;
        default:
          EditorInactivate(G);
          break;
        }
      } else {                  /* no atom picked */
        switch (mode) {
        case cButModeMenu:

          MenuActivate3fv(G, I->LastWinX, I->LastWinY,
                          I->LastWinX, I->LastWinY,
                          is_single_click, "main_menu", I->LastClickVertex);
          break;
        default:
          EditorInactivate(G);
          if(SettingGetGlobal_i(G, cSetting_logging)) {
            PLog(G, "cmd.edit()", cPLog_pym);
          }
          break;
        }
      }
      SceneDirty(G);
      break;
    case cButModePickBond:
    case cButModePkTorBnd:
      if(stereo_via_adjacent_array(I->StereoMode))
        x = get_stereo_x(x, NULL, I->Width, &click_side);

      if(SceneDoXYPick(G, x, y, click_side)) {
        obj = (CObject *) I->LastPicked.context.object;
        y = y - I->margin.bottom;
        x = x - I->margin.left;
        I->LastX = x;
        I->LastY = y;

        if(mode == cButModePkTorBnd) {
          I->Threshold = 3;
          I->ThresholdX = x;
          I->ThresholdY = y;
        }

        switch (obj->type) {
        case cObjectMolecule:

          EditorInactivate(G);
          if(Feedback(G, FB_Scene, FB_Results)) {
            if(obj->fDescribeElement)
              obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
            PRINTF " You clicked %s -> (%s)", buffer, cEditorSele1 ENDF(G);
            OrthoRestorePrompt(G);
          }

          /*        ObjectMoleculeChooseBondDir(objMol,I->LastPicked.bond,
             &I->LastPicked.src.index,&atIndex); */

          sprintf(buffer, "%s`%d", obj->Name, I->LastPicked.src.index + 1);
          SelectorCreate(G, cEditorSele1, buffer, NULL, true, NULL);
          objMol = (ObjectMolecule *) obj;
          if(I->LastPicked.src.bond >= 0) {
            atIndex = objMol->Bond[I->LastPicked.src.bond].index[0];
            if(atIndex == I->LastPicked.src.index)
              atIndex = objMol->Bond[I->LastPicked.src.bond].index[1];
            if(Feedback(G, FB_Scene, FB_Results)) {
              if(obj->fDescribeElement)
                obj->fDescribeElement(obj, atIndex, buffer);
              PRINTF " You clicked %s -> (%s)", buffer, cEditorSele2 ENDF(G);
              OrthoRestorePrompt(G);
            }

            if(SettingGetGlobal_i(G, cSetting_logging)) {
              objMol = (ObjectMolecule *) obj;
              ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1, false);
              ObjectMoleculeGetAtomSeleLog(objMol, atIndex, buf2, false);
              sprintf(buffer, "cmd.edit(\"%s\",\"%s\")", buf1, buf2);
              PLog(G, buffer, cPLog_pym);
            }
            sprintf(buffer, "%s`%d", obj->Name, atIndex + 1);
            SelectorCreate(G, cEditorSele2, buffer, NULL, true, NULL);
            EditorActivate(G, SettingGetGlobal_i(G, cSetting_state) - 1, true);

            if(mode == cButModePkTorBnd) {
              /* get ready to drag */
              SceneDontCopyNext(G);
              switch (obj->type) {
              case cObjectMolecule:
                objMol = (ObjectMolecule *) obj;
                EditorPrepareDrag(G, obj, -1, I->LastPicked.src.index,
                                  SettingGetGlobal_i(G, cSetting_state) - 1, mode);
                I->SculptingFlag = 1;
                I->SculptingSave = objMol->AtomInfo[I->LastPicked.src.index].protekted;
                objMol->AtomInfo[I->LastPicked.src.index].protekted = 2;
                break;
              }
            }
            WizardDoPick(G, 1, I->LastPicked.context.state);
          } else {
            WizardDoPick(G, 0, I->LastPicked.context.state);
          }
          if(SettingGetGlobal_b(G, cSetting_auto_hide_selections))
            ExecutiveHideSelections(G);
          break;
        case cObjectGadget:
          break;
        default:
          EditorInactivate(G);
          break;
        }
      } else {
        EditorInactivate(G);
        EditorLogState(G, false);
      }
      SceneInvalidate(G);
      break;
    case cButModeRotObj:
    case cButModeMovObj:
    case cButModeMovObjZ:
    case cButModeRotView:
    case cButModeMovView:
    case cButModeMovViewZ:
    case cButModeRotFrag:
    case cButModeMovFrag:
    case cButModeMovFragZ:
    case cButModeTorFrag:
    case cButModeMoveAtom:
    case cButModeMoveAtomZ:
      if(stereo_via_adjacent_array(I->StereoMode))
        x = get_stereo_x(x, NULL, I->Width, &click_side);

      if(SceneDoXYPick(G, x, y, click_side)) {
        obj = (CObject *) I->LastPicked.context.object;
        y = y - I->margin.bottom;
        x = x - I->margin.left;
        I->LastX = x;
        I->LastY = y;
        switch (obj->type) {
        case cObjectMolecule:
          
          if(I->LastPicked.src.bond == cPickableLabel) {
            /* if user picks a label with move object/move fragment,
               then move the object/fragment, not the label */
            
            switch (mode) {
            case cButModeRotObj:
            case cButModeMovObj:
            case cButModeMovObjZ:
            case cButModeRotFrag:
            case cButModeMovFrag:
            case cButModeMovFragZ:
            case cButModeMovViewZ:
            case cButModeRotView:
            case cButModeMovView:
              I->LastPicked.src.bond = cPickableAtom;
              break;
            }
          }

          switch(mode) {
          case cButModeMovViewZ:
          case cButModeRotView:
          case cButModeMovView:
            {
              if(SettingGetGlobal_b(G,cSetting_movie_auto_store)) {
                ObjectTranslateTTT(obj, NULL, true);
                I->MotionGrabbedObj = obj;
                obj->Grabbed = true;
                if(SettingGetGlobal_i(G,cSetting_movie_auto_interpolate)) {
                  I->ReinterpolateFlag = true;
                  I->ReinterpolateObj = obj;
                }
              } else {
                ObjectTranslateTTT(obj, NULL, false);
              }
            }
            break;
          }
          
          if(I->LastPicked.src.bond >= cPickableAtom) {
            if(Feedback(G, FB_Scene, FB_Results)) {
              if(obj->fDescribeElement)
                obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
              PRINTF " You clicked %s", buffer ENDF(G);
              OrthoRestorePrompt(G);
            }
          }
          objMol = (ObjectMolecule *) obj;
          EditorPrepareDrag(G, obj, -1, I->LastPicked.src.index,
                            SettingGetGlobal_i(G, cSetting_state) - 1, mode);

          if(I->LastPicked.src.bond >= cPickableAtom) {
            I->SculptingFlag = 1;
            I->SculptingSave = objMol->AtomInfo[I->LastPicked.src.index].protekted;
            objMol->AtomInfo[I->LastPicked.src.index].protekted = 2;
          }
          break;
        case cObjectSlice:
          if(ObjectSliceGetVertex((ObjectSlice *) obj, I->LastPicked.src.index,
                                  I->LastPicked.src.bond, I->LastPickVertex)) {
            I->LastPickVertexFlag = true;
          }
          break;
        case cObjectMeasurement:
          break;
        case cObjectGadget:
          break;
        default:
          EditorInactivate(G);
          break;
        }
      }
      break;

    case cButModeSeleSet:
    case cButModeSeleToggle:
      sel_mode_kw = SceneGetSeleModeKeyword(G);

      /* intentional pass through */

    case cButModeLB:
    case cButModeMB:
    case cButModeRB:
    case cButModeAddToLB:
    case cButModeAddToMB:
    case cButModeAddToRB:
    case cButModeSimpleClick:
    case cButModeOrigAt:
    case cButModeCent:
    case cButModeDragMol:
    case cButModeDragObj:
      if(stereo_via_adjacent_array(I->StereoMode))
        x = get_stereo_x(x, NULL, I->Width, &click_side);

      if(SceneDoXYPick(G, x, y, click_side)) {
        obj = (CObject *) I->LastPicked.context.object;

        switch (obj->type) {
        case cObjectMolecule:
          if(Feedback(G, FB_Scene, FB_Results)) {
            if(obj->fDescribeElement)
              obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
            PRINTF " You clicked %s", buffer ENDF(G);
            OrthoRestorePrompt(G);
          }
          sprintf(buffer, "%s`%d", obj->Name, I->LastPicked.src.index + 1);
          switch (mode) {
          case cButModeLB:
          case cButModeAddToLB:
            strcpy(selName, "lb");
            break;
          case cButModeMB:
          case cButModeAddToMB:
            strcpy(selName, "mb");
            break;
          case cButModeRB:
          case cButModeAddToRB:
            strcpy(selName, "rb");
            break;
          case cButModeSeleSet:
          case cButModeSeleToggle:
            ExecutiveGetActiveSeleName(G, selName, true, SettingGetGlobal_i(G, cSetting_logging));
            break;
          case cButModeDragMol:
            {
              objMol = (ObjectMolecule *) obj;
              ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1, false);
              sprintf(buffer, "cmd.drag(\"bymol (%s)\")", buf1);
              PParse(G, buffer);
              PLog(G, buffer, cPLog_pym);
            }
            break;
          case cButModeDragObj:
            {
              objMol = (ObjectMolecule *) obj;
              ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1, false);
              sprintf(buffer, "cmd.drag(\"byobject (%s)\")", buf1);
              PParse(G, buffer);
              PLog(G, buffer, cPLog_pym);
            }
            break;
          case cButModeOrigAt:
            SceneNoteMouseInteraction(G);
            {
              float v1[3];

              if(ObjectMoleculeGetAtomTxfVertex((ObjectMolecule *) obj,
                                                I->LastPicked.context.state,
                                                I->LastPicked.src.index, v1)) {
                EditorFavorOrigin(G, v1);
                ExecutiveOrigin(G, NULL, true, NULL, v1, 0);
              }
            }
            if(obj->type == cObjectMolecule) {
              if(SettingGetGlobal_i(G, cSetting_logging)) {
                objMol = (ObjectMolecule *) obj;
                ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1,
                                             false);
                sprintf(buffer, "cmd.origin(\"%s\")", buf1);
                PLog(G, buffer, cPLog_pym);

              }
              if(Feedback(G, FB_Scene, FB_Results)) {
                if(obj->fDescribeElement)
                  obj->fDescribeElement(obj, I->LastPicked.src.index, buffer);
                PRINTF " You clicked %s", buffer ENDF(G);
                OrthoRestorePrompt(G);
              }
            }
            PRINTFB(G, FB_Scene, FB_Actions)
              " Scene: Origin set.\n" ENDFB(G);
            break;
          case cButModeCent:
            SceneNoteMouseInteraction(G);
            {
              float v1[3];

              if(ObjectMoleculeGetAtomTxfVertex((ObjectMolecule *) obj,
                                                I->LastPicked.context.state,
                                                I->LastPicked.src.index, v1)) {
                ExecutiveCenter(G, NULL, 0, true, -1, v1, true);
              }
            }

            if(SettingGetGlobal_i(G, cSetting_logging)) {
              objMol = (ObjectMolecule *) obj;
              ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1, false);
              sprintf(buffer, "cmd.center(\"%s\",state=%d)", buf1, I->LastPicked.context.state + 1);
              PLog(G, buffer, cPLog_pym);
            }
            break;
          }
          switch (mode) {
          case cButModeSimpleClick:
	    {
	      float pos_store[3], *pos = pos_store;
	      int index = I->LastPicked.src.index; /* 1-based */
	      int state = ObjectGetCurrentState(obj, true);
	      if(!( (obj->type == cObjectMolecule) &&
		    (I->LastPicked.src.bond != cPickableNoPick ) &&
		    ObjectMoleculeGetAtomTxfVertex((ObjectMolecule *)obj,-1,index, pos)))
		pos = NULL;
	      PyMOL_SetClickReady(G->PyMOL, obj->Name, I->LastPicked.src.index,
				  button, mod, I->LastWinX, I->Height - (I->LastWinY + 1),
				  pos, state + 1); /* send a 1-based state index */
	    }
            break;
          case cButModeLB:
          case cButModeMB:
          case cButModeRB:
          case cButModeSeleSet:
            sprintf(buf2, "(%s(%s))", sel_mode_kw, buffer);
            SelectorCreate(G, selName, buf2, NULL, false, NULL);
            if(SettingGetGlobal_b(G, cSetting_auto_hide_selections))
              ExecutiveHideSelections(G);
            if(SettingGetGlobal_b(G, cSetting_auto_show_selections))
              ExecutiveSetObjVisib(G, selName, 1, false);
            if(obj->type == cObjectMolecule) {
              if(SettingGetGlobal_i(G, cSetting_logging)) {
                objMol = (ObjectMolecule *) obj;
                ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1,
                                             false);
                sprintf(buffer, "cmd.select('%s',\"%s(%s)\",enable=1)", selName,
                        sel_mode_kw, buf1);
                PLog(G, buffer, cPLog_pym);
              }
            }
            WizardDoSelect(G, selName, I->LastPicked.context.state);
            break;
          case cButModeAddToLB:
          case cButModeAddToMB:
          case cButModeAddToRB:
          case cButModeSeleToggle:
            if(SelectorIndexByName(G, selName) >= 0) {
              sprintf(buf2, "(((%s) or %s(%s)) and not ((%s(%s)) and %s(%s)))",
                      selName, sel_mode_kw, buffer, sel_mode_kw, buffer, sel_mode_kw,
                      selName);
              SelectorCreate(G, selName, buf2, NULL, false, NULL);
              if(obj->type == cObjectMolecule) {
                if(SettingGetGlobal_i(G, cSetting_logging)) {
                  objMol = (ObjectMolecule *) obj;
                  ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buffer,
                                               false);
                  sprintf(buf2, "(((%s) or %s(%s)) and not ((%s(%s)) and %s(%s)))",
                          selName, sel_mode_kw, buffer, sel_mode_kw, buffer, sel_mode_kw,
                          selName);
                  sprintf(buffer, "cmd.select('%s',\"%s(%s)\",enable=1)", selName,
                          sel_mode_kw, buf2);
                  PLog(G, buffer, cPLog_pym);
                }
              }
            } else {
              sprintf(buf2, "%s(%s)", sel_mode_kw, buffer);
              SelectorCreate(G, selName, buf2, NULL, false, NULL);
              if(obj->type == cObjectMolecule) {
                if(SettingGetGlobal_i(G, cSetting_logging)) {
                  objMol = (ObjectMolecule *) obj;
                  ObjectMoleculeGetAtomSeleLog(objMol, I->LastPicked.src.index, buf1,
                                               false);
                  sprintf(buffer, "cmd.select('%s',\"%s(%s)\")", selName, sel_mode_kw,
                          buf1);
                  PLog(G, buffer, cPLog_pym);
                }
              }
            }
            if(SettingGetGlobal_b(G, cSetting_auto_hide_selections))
              ExecutiveHideSelections(G);
            if(SettingGetGlobal_b(G, cSetting_auto_show_selections))
              ExecutiveSetObjVisib(G, selName, 1, false);
            WizardDoSelect(G, selName, I->LastPicked.context.state);
            break;
          }
        case cObjectGadget:
          break;
        default:
          EditorInactivate(G);
          break;
        }
      } else {
        switch (mode) {
        case cButModeSeleSet:
          {
            OrthoLineType buf2;
            ObjectNameType name;

            if(ExecutiveGetActiveSeleName
               (G, name, false, SettingGetGlobal_i(G, cSetting_logging))) {
              SelectorCreate(G, name, "none", NULL, true, NULL);
              if(SettingGetGlobal_i(G, cSetting_logging)) {
                sprintf(buf2, "cmd.select('%s','none')\n", name);
                PLog(G, buf2, cPLog_no_flush);
              }
              SeqDirty(G);
            }
          }
        case cButModeSeleToggle:
          {
            OrthoLineType buf2;
            ObjectNameType name;

            if(ExecutiveGetActiveSeleName
               (G, name, false, SettingGetGlobal_i(G, cSetting_logging))) {
              ExecutiveSetObjVisib(G, name, 0, false);
              if(SettingGetGlobal_i(G, cSetting_logging)) {
                sprintf(buf2, "cmd.disable('%s')\n", name);
                PLog(G, buf2, cPLog_no_flush);
              }
            }
          }
          break;
        case cButModeSimpleClick:
          PyMOL_SetClickReady(G->PyMOL, "", -1, button, mod, I->LastWinX,
                              I->Height - (I->LastWinY + 1), NULL, 0);
          break;
        }
        PRINTFB(G, FB_Scene, FB_Blather)
          " SceneClick: no atom found nearby.\n" ENDFB(G);
        SceneInvalidate(G);     /* this here to prevent display weirdness after
                                   an unsuccessful picking pass... not sure it helps though */
        OrthoRestorePrompt(G);
      }
    }

    I->StartX = I->LastX;
    I->StartY = I->LastY;
  }
  return (1);
}