bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg)
{
  ASSERT(m_pixelsMovement != NULL);

  Decorator* decorator = static_cast<Decorator*>(editor->getDecorator());
  Document* document = editor->getDocument();

  // Start scroll loop
  if (checkForScroll(editor, msg))
    return true;

  // Transform selected pixels
  if (document->isMaskVisible() &&
      decorator->getTransformHandles(editor)) {
    TransformHandles* transfHandles = decorator->getTransformHandles(editor);

    // Get the handle covered by the mouse.
    HandleType handle = transfHandles->getHandleAtPoint(editor,
                                                        gfx::Point(msg->mouse.x, msg->mouse.y),
                                                        getTransformation(editor));

    if (handle != NoHandle) {
      // Re-catch the image
      int x, y;
      editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y);
      m_pixelsMovement->catchImageAgain(x, y, handle);

      editor->captureMouse();
      return true;
    }
  }

  // Start "moving pixels" loop
  if (editor->isInsideSelection() && (msg->mouse.left ||
                                      msg->mouse.right)) {
    // In case that the user is pressing the copy-selection keyboard shortcut.
    EditorCustomizationDelegate* customization = editor->getCustomizationDelegate();
    if (customization && customization->isCopySelectionKeyPressed()) {
      // Stamp the pixels to create the copy.
      m_pixelsMovement->stampImage();
    }

    // Re-catch the image
    int x, y;
    editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y);
    m_pixelsMovement->catchImageAgain(x, y, MoveHandle);

    editor->captureMouse();
    return true;
  }
  // End "moving pixels" loop
  else {
    // Drop pixels (e.g. to start drawing)
    dropPixels(editor);
  }

  // Use StandbyState implementation
  return StandbyState::onMouseDown(editor, msg);
}
bool MovingPixelsState::onMouseMove(Editor* editor, MouseMessage* msg)
{
  ASSERT(m_pixelsMovement != NULL);

  // If there is a button pressed
  if (m_pixelsMovement->isDragging()) {
    // Auto-scroll
    gfx::Point mousePos = editor->autoScroll(msg, AutoScroll::MouseDir, false);

    // Get the position of the mouse in the sprite
    int x, y;
    editor->screenToEditor(mousePos.x, mousePos.y, &x, &y);

    // Get the customization for the pixels movement (snap to grid, angle snap, etc.).
    PixelsMovement::MoveModifier moveModifier = PixelsMovement::NormalMovement;

    if (editor->getCustomizationDelegate()->isSnapToGridKeyPressed())
      moveModifier |= PixelsMovement::SnapToGridMovement;

    if (editor->getCustomizationDelegate()->isAngleSnapKeyPressed())
      moveModifier |= PixelsMovement::AngleSnapMovement;

    if (editor->getCustomizationDelegate()->isMaintainAspectRatioKeyPressed())
      moveModifier |= PixelsMovement::MaintainAspectRatioMovement;

    if (editor->getCustomizationDelegate()->isLockAxisKeyPressed())
      moveModifier |= PixelsMovement::LockAxisMovement;

    // Invalidate handles
    Decorator* decorator = static_cast<Decorator*>(editor->decorator());
    TransformHandles* transfHandles = decorator->getTransformHandles(editor);
    transfHandles->invalidateHandles(editor, m_pixelsMovement->getTransformation());

    // Drag the image to that position
    m_pixelsMovement->moveImage(x, y, moveModifier);

    editor->updateStatusBar();
    return true;
  }

  // Use StandbyState implementation
  return StandbyState::onMouseMove(editor, msg);
}
Beispiel #3
0
bool StandbyState::Decorator::onSetCursor(Editor* editor)
{
  if (!editor->document()->isMaskVisible())
    return false;

  const gfx::Transformation transformation(m_standbyState->getTransformation(editor));
  TransformHandles* tr = getTransformHandles(editor);
  HandleType handle = tr->getHandleAtPoint(editor,
    ui::get_mouse_position(), transformation);

  CursorType newCursor = kArrowCursor;

  switch (handle) {
    case ScaleNWHandle:         newCursor = kSizeNWCursor; break;
    case ScaleNHandle:          newCursor = kSizeNCursor; break;
    case ScaleNEHandle:         newCursor = kSizeNECursor; break;
    case ScaleWHandle:          newCursor = kSizeWCursor; break;
    case ScaleEHandle:          newCursor = kSizeECursor; break;
    case ScaleSWHandle:         newCursor = kSizeSWCursor; break;
    case ScaleSHandle:          newCursor = kSizeSCursor; break;
    case ScaleSEHandle:         newCursor = kSizeSECursor; break;
    case RotateNWHandle:        newCursor = kRotateNWCursor; break;
    case RotateNHandle:         newCursor = kRotateNCursor; break;
    case RotateNEHandle:        newCursor = kRotateNECursor; break;
    case RotateWHandle:         newCursor = kRotateWCursor; break;
    case RotateEHandle:         newCursor = kRotateECursor; break;
    case RotateSWHandle:        newCursor = kRotateSWCursor; break;
    case RotateSHandle:         newCursor = kRotateSCursor; break;
    case RotateSEHandle:        newCursor = kRotateSECursor; break;
    case PivotHandle:           newCursor = kHandCursor; break;
    default:
      return false;
  }

  // Adjust the cursor depending the current transformation angle.
  fixmath::fixed angle = fixmath::ftofix(128.0 * transformation.angle() / PI);
  angle = fixmath::fixadd(angle, fixmath::itofix(16));
  angle &= (255<<16);
  angle >>= 16;
  angle /= 32;

  if (newCursor >= kSizeNCursor && newCursor <= kSizeNWCursor) {
    size_t num = sizeof(rotated_size_cursors) / sizeof(rotated_size_cursors[0]);
    size_t c;
    for (c=num-1; c>0; --c)
      if (rotated_size_cursors[c] == newCursor)
        break;

    newCursor = rotated_size_cursors[(c+angle) % num];
  }
  else if (newCursor >= kRotateNCursor && newCursor <= kRotateNWCursor) {
    size_t num = sizeof(rotated_rotate_cursors) / sizeof(rotated_rotate_cursors[0]);
    size_t c;
    for (c=num-1; c>0; --c)
      if (rotated_rotate_cursors[c] == newCursor)
        break;

    newCursor = rotated_rotate_cursors[(c+angle) % num];
  }

  // Hide the drawing cursor (just in case) and show the new system cursor.
  editor->hideDrawingCursor();
  ui::set_mouse_cursor(newCursor);
  return true;
}
Beispiel #4
0
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
{
  if (editor->hasCapture())
    return true;

  UIContext* context = UIContext::instance();
  tools::Ink* clickedInk = editor->getCurrentEditorInk();
  Site site;
  editor->getSite(&site);
  app::Document* document = static_cast<app::Document*>(site.document());
  Layer* layer = site.layer();

  // When an editor is clicked the current view is changed.
  context->setActiveView(editor->getDocumentView());

  // Start scroll loop
  if (checkForScroll(editor, msg) || checkForZoom(editor, msg))
    return true;

  // Move cel X,Y coordinates
  if (clickedInk->isCelMovement()) {
    // Handle "Auto Select Layer"
    if (editor->isAutoSelectLayer()) {
      gfx::Point cursor = editor->screenToEditor(msg->position());

      ColorPicker picker;
      picker.pickColor(site, cursor, ColorPicker::FromComposition);

      if (layer != picker.layer()) {
        layer = picker.layer();
        if (layer) {
          editor->setLayer(layer);
          editor->flashCurrentLayer();
        }
      }
    }

    if ((layer) &&
        (layer->type() == ObjectType::LayerImage)) {
      // TODO we should be able to move the `Background' with tiled mode
      if (layer->isBackground()) {
        StatusBar::instance()->showTip(1000,
          "The background layer cannot be moved");
      }
      else if (!layer->isVisible()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is hidden", layer->name().c_str());
      }
      else if (!layer->isMovable() || !layer->isEditable()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is locked", layer->name().c_str());
      }
      else {
        // Change to MovingCelState
        editor->setState(EditorStatePtr(new MovingCelState(editor, msg)));
      }
    }

    return true;
  }

  // Call the eyedropper command
  if (clickedInk->isEyedropper()) {
    callEyedropper(editor);
    return true;
  }

  if (clickedInk->isSelection()) {
    // Transform selected pixels
    if (document->isMaskVisible() && m_decorator->getTransformHandles(editor)) {
      TransformHandles* transfHandles = m_decorator->getTransformHandles(editor);

      // Get the handle covered by the mouse.
      HandleType handle = transfHandles->getHandleAtPoint(editor,
        msg->position(),
        document->getTransformation());

      if (handle != NoHandle) {
        int x, y, opacity;
        Image* image = site.image(&x, &y, &opacity);
        if (layer && image) {
          if (!layer->isEditable()) {
            StatusBar::instance()->showTip(1000,
              "Layer '%s' is locked", layer->name().c_str());
            return true;
          }

          // Change to MovingPixelsState
          transformSelection(editor, msg, handle);
        }
        return true;
      }
    }

    // Move selected pixels
    if (layer && editor->isInsideSelection() && msg->left()) {
      if (!layer->isEditable()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is locked", layer->name().c_str());
        return true;
      }

      // Change to MovingPixelsState
      transformSelection(editor, msg, MoveHandle);
      return true;
    }
  }

  // Start the Tool-Loop
  if (layer) {
    tools::ToolLoop* toolLoop = create_tool_loop(editor, context);
    if (toolLoop) {
      EditorStatePtr newState(new DrawingState(toolLoop));
      editor->setState(newState);

      static_cast<DrawingState*>(newState.get())
        ->initToolLoop(editor, msg);
    }
    return true;
  }

  return true;
}
Beispiel #5
0
bool StandbyState::Decorator::onSetCursor(tools::Ink* ink, Editor* editor, const gfx::Point& mouseScreenPos)
{
  if (!editor->isActive())
    return false;

  if (ink && ink->isSelection() && editor->document()->isMaskVisible()) {
    const gfx::Transformation transformation(m_standbyState->getTransformation(editor));
    TransformHandles* tr = getTransformHandles(editor);
    HandleType handle = tr->getHandleAtPoint(
      editor, mouseScreenPos, transformation);

    CursorType newCursor = kArrowCursor;

    switch (handle) {
      case ScaleNWHandle:         newCursor = kSizeNWCursor; break;
      case ScaleNHandle:          newCursor = kSizeNCursor; break;
      case ScaleNEHandle:         newCursor = kSizeNECursor; break;
      case ScaleWHandle:          newCursor = kSizeWCursor; break;
      case ScaleEHandle:          newCursor = kSizeECursor; break;
      case ScaleSWHandle:         newCursor = kSizeSWCursor; break;
      case ScaleSHandle:          newCursor = kSizeSCursor; break;
      case ScaleSEHandle:         newCursor = kSizeSECursor; break;
      case RotateNWHandle:        newCursor = kRotateNWCursor; break;
      case RotateNHandle:         newCursor = kRotateNCursor; break;
      case RotateNEHandle:        newCursor = kRotateNECursor; break;
      case RotateWHandle:         newCursor = kRotateWCursor; break;
      case RotateEHandle:         newCursor = kRotateECursor; break;
      case RotateSWHandle:        newCursor = kRotateSWCursor; break;
      case RotateSHandle:         newCursor = kRotateSCursor; break;
      case RotateSEHandle:        newCursor = kRotateSECursor; break;
      case PivotHandle:           newCursor = kHandCursor; break;
      default:
        return false;
    }

    // Adjust the cursor depending the current transformation angle.
    fixmath::fixed angle = fixmath::ftofix(128.0 * transformation.angle() / PI);
    angle = fixmath::fixadd(angle, fixmath::itofix(16));
    angle &= (255<<16);
    angle >>= 16;
    angle /= 32;

    if (newCursor >= kSizeNCursor && newCursor <= kSizeNWCursor) {
      size_t num = sizeof(rotated_size_cursors) / sizeof(rotated_size_cursors[0]);
      size_t c;
      for (c=num-1; c>0; --c)
        if (rotated_size_cursors[c] == newCursor)
          break;

      newCursor = rotated_size_cursors[(c+angle) % num];
    }
    else if (newCursor >= kRotateNCursor && newCursor <= kRotateNWCursor) {
      size_t num = sizeof(rotated_rotate_cursors) / sizeof(rotated_rotate_cursors[0]);
      size_t c;
      for (c=num-1; c>0; --c)
        if (rotated_rotate_cursors[c] == newCursor)
          break;

      newCursor = rotated_rotate_cursors[(c+angle) % num];
    }

    editor->showMouseCursor(newCursor);
    return true;
  }

  gfx::Rect box1, box2;
  if (getSymmetryHandles(editor, box1, box2) &&
      (box1.contains(mouseScreenPos) ||
       box2.contains(mouseScreenPos))) {
    switch (Preferences::instance().document(editor->document()).symmetry.mode()) {
      case app::gen::SymmetryMode::HORIZONTAL:
        editor->showMouseCursor(kSizeWECursor);
        break;
      case app::gen::SymmetryMode::VERTICAL:
        editor->showMouseCursor(kSizeNSCursor);
        break;
    }
    return true;
  }

  return false;
}
Beispiel #6
0
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
{
  if (editor->hasCapture())
    return true;

  UIContext* context = UIContext::instance();
  tools::Ink* clickedInk = editor->getCurrentEditorInk();
  Site site;
  editor->getSite(&site);
  app::Document* document = static_cast<app::Document*>(site.document());
  Layer* layer = site.layer();

  // When an editor is clicked the current view is changed.
  context->setActiveView(editor->getDocumentView());

  // Start scroll loop
  if (checkForScroll(editor, msg) || checkForZoom(editor, msg))
    return true;

  // Move cel X,Y coordinates
  if (clickedInk->isCelMovement()) {
    // Handle "Auto Select Layer"
    if (editor->isAutoSelectLayer()) {
      gfx::Point cursor = editor->screenToEditor(msg->position());

      ColorPicker picker;
      picker.pickColor(site, cursor, ColorPicker::FromComposition);

      DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();

      // Change layer only when the layer is diffrent from current one, and
      // the range we selected is not with multiple cels.
      bool layerChanged = (layer != picker.layer());
      bool rangeEnabled = range.enabled();
      bool rangeSingleCel = ((range.type() == DocumentRange::kCels) &&
                             (range.layers() == 1) && (range.frames() == 1));

      if (layerChanged && (!rangeEnabled || rangeSingleCel)) {
        layer = picker.layer();
        if (layer) {
          editor->setLayer(layer);
          editor->flashCurrentLayer();
        }
      }
    }

    if ((layer) &&
        (layer->type() == ObjectType::LayerImage)) {
      // TODO we should be able to move the `Background' with tiled mode
      if (layer->isBackground()) {
        StatusBar::instance()->showTip(1000,
          "The background layer cannot be moved");
      }
      else if (!layer->isVisible()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is hidden", layer->name().c_str());
      }
      else if (!layer->isMovable() || !layer->isEditable()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is locked", layer->name().c_str());
      }
      else if (!layer->cel(editor->frame())) {
        StatusBar::instance()->showTip(1000,
          "Cel is empty, nothing to move");
      }
      else {
        // Change to MovingCelState
        editor->setState(EditorStatePtr(new MovingCelState(editor, msg)));
      }
    }

    return true;
  }

  // Call the eyedropper command
  if (clickedInk->isEyedropper()) {
    editor->captureMouse();
    callEyedropper(editor);
    return true;
  }

  if (clickedInk->isSelection()) {
    // Transform selected pixels
    if (editor->isActive() &&
        document->isMaskVisible() &&
        m_decorator->getTransformHandles(editor)) {
      TransformHandles* transfHandles = m_decorator->getTransformHandles(editor);

      // Get the handle covered by the mouse.
      HandleType handle = transfHandles->getHandleAtPoint(editor,
        msg->position(),
        document->getTransformation());

      if (handle != NoHandle) {
        int x, y, opacity;
        Image* image = site.image(&x, &y, &opacity);
        if (layer && image) {
          if (!layer->isEditable()) {
            StatusBar::instance()->showTip(1000,
              "Layer '%s' is locked", layer->name().c_str());
            return true;
          }

          // Change to MovingPixelsState
          transformSelection(editor, msg, handle);
        }
        return true;
      }
    }

    // Move selected pixels
    if (layer && editor->isInsideSelection() && msg->left()) {
      if (!layer->isEditable()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is locked", layer->name().c_str());
        return true;
      }

      // Change to MovingPixelsState
      transformSelection(editor, msg, MoveHandle);
      return true;
    }
  }

  // Move symmetry
  gfx::Rect box1, box2;
  if (m_decorator->getSymmetryHandles(editor, box1, box2) &&
      (box1.contains(msg->position()) ||
       box2.contains(msg->position()))) {
    auto& symmetry = Preferences::instance().document(editor->document()).symmetry;
    auto mode = symmetry.mode();
    bool horz = (mode == app::gen::SymmetryMode::HORIZONTAL);
    auto& axis = (horz ? symmetry.xAxis:
                         symmetry.yAxis);
    editor->setState(
      EditorStatePtr(new MovingSymmetryState(editor, msg,
                                             mode, axis)));
    return true;
  }

  // Start the Tool-Loop
  if (layer) {
    tools::ToolLoop* toolLoop = create_tool_loop(editor, context);
    if (toolLoop) {
      EditorStatePtr newState(new DrawingState(toolLoop));
      editor->setState(newState);

      static_cast<DrawingState*>(newState.get())
        ->initToolLoop(editor, msg);
    }
    return true;
  }

  return true;
}
bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg)
{
  ASSERT(m_pixelsMovement != NULL);

  // Set this editor as the active one and setup the ContextBar for
  // moving pixels. This is needed in case that the user is working
  // with a couple of Editors, in one is moving pixels and the other
  // one not.
  UIContext* ctx = UIContext::instance();
  ctx->setActiveView(editor->getDocumentView());

  ContextBar* contextBar = App::instance()->getMainWindow()->getContextBar();
  contextBar->updateForMovingPixels();

  // Start scroll loop
  if (checkForScroll(editor, msg))
    return true;

  Decorator* decorator = static_cast<Decorator*>(editor->decorator());
  Document* document = editor->document();

  // Transform selected pixels
  if (document->isMaskVisible() &&
      decorator->getTransformHandles(editor)) {
    TransformHandles* transfHandles = decorator->getTransformHandles(editor);

    // Get the handle covered by the mouse.
    HandleType handle = transfHandles->getHandleAtPoint(editor,
                                                        msg->position(),
                                                        getTransformation(editor));

    if (handle != NoHandle) {
      // Re-catch the image
      int x, y;
      editor->screenToEditor(msg->position().x, msg->position().y, &x, &y);
      m_pixelsMovement->catchImageAgain(x, y, handle);

      editor->captureMouse();
      return true;
    }
  }

  // Start "moving pixels" loop
  if (editor->isInsideSelection() && (msg->left() ||
                                      msg->right())) {
    // In case that the user is pressing the copy-selection keyboard shortcut.
    EditorCustomizationDelegate* customization = editor->getCustomizationDelegate();
    if (customization && customization->isCopySelectionKeyPressed()) {
      // Stamp the pixels to create the copy.
      m_pixelsMovement->stampImage();
    }

    // Re-catch the image
    int x, y;
    editor->screenToEditor(msg->position().x, msg->position().y, &x, &y);
    m_pixelsMovement->catchImageAgain(x, y, MoveHandle);

    editor->captureMouse();
    return true;
  }
  // End "moving pixels" loop
  else {
    // Drop pixels (e.g. to start drawing)
    dropPixels(editor);
  }

  // Use StandbyState implementation
  return StandbyState::onMouseDown(editor, msg);
}
Beispiel #8
0
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
{
  if (editor->hasCapture())
    return true;

  UIContext* context = UIContext::instance();
  tools::Tool* currentTool = editor->getCurrentEditorTool();
  tools::Ink* clickedInk = editor->getCurrentEditorInk();
  DocumentLocation location;
  editor->getDocumentLocation(&location);
  Document* document = location.document();
  Layer* layer = location.layer();

  // When an editor is clicked the current view is changed.
  context->setActiveView(editor->getDocumentView());

  // Start scroll loop
  if (checkForScroll(editor, msg) || checkForZoom(editor, msg))
    return true;

  // Move cel X,Y coordinates
  if (clickedInk->isCelMovement()) {
    if ((layer) &&
        (layer->type() == OBJECT_LAYER_IMAGE)) {
      // TODO you can move the `Background' with tiled mode
      if (layer->isBackground()) {
        Alert::show(PACKAGE
                    "<<You can't move the `Background' layer."
                    "||&Close");
      }
      else if (!layer->isMoveable()) {
        Alert::show(PACKAGE "<<The layer movement is locked.||&Close");
      }
      else {
        // Change to MovingCelState
        editor->setState(EditorStatePtr(new MovingCelState(editor, msg)));
      }
    }
    return true;
  }

  // Transform selected pixels
  if (document->isMaskVisible() &&
      m_decorator->getTransformHandles(editor)) {
    TransformHandles* transfHandles = m_decorator->getTransformHandles(editor);

    // Get the handle covered by the mouse.
    HandleType handle = transfHandles->getHandleAtPoint(editor,
                                                        msg->position(),
                                                        document->getTransformation());

    if (handle != NoHandle) {
      int x, y, opacity;
      Image* image = location.image(&x, &y, &opacity);
      if (image) {
        if (!layer->isWritable()) {
          Alert::show(PACKAGE "<<The layer is locked.||&Close");
          return true;
        }

        // Change to MovingPixelsState
        transformSelection(editor, msg, handle);
      }
      return true;
    }
  }

  // Move selected pixels
  if (editor->isInsideSelection() &&
      currentTool->getInk(0)->isSelection() &&
      msg->left()) {
    if (!layer->isWritable()) {
      Alert::show(PACKAGE "<<The layer is locked.||&Close");
      return true;
    }

    // Change to MovingPixelsState
    transformSelection(editor, msg, MoveHandle);
    return true;
  }

  // Call the eyedropper command
  if (clickedInk->isEyedropper()) {
    onMouseMove(editor, msg);
    return true;
  }

  // Start the Tool-Loop
  if (layer) {
    tools::ToolLoop* toolLoop = create_tool_loop(editor, context);
    if (toolLoop)
      editor->setState(EditorStatePtr(new DrawingState(toolLoop, editor, msg)));
    return true;
  }

  return true;
}