void TransformHandles::invalidateHandles(Editor* editor, const gfx::Transformation& transform)
{
  SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
  fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);

  gfx::Transformation::Corners corners;
  transform.transformBox(corners);

  std::vector<gfx::Point> screenPoints(corners.size());
  for (size_t c=0; c<corners.size(); ++c)
    screenPoints[c] = editor->editorToScreen(
      gfx::Point((int)corners[c].x, (int)corners[c].y));

  // Invalidate each corner handle.
  for (size_t c=0; c<HANDLES; ++c) {
    she::Surface* part = theme->parts.transformationHandle()->getBitmap(0);
    int u = (screenPoints[handles_info[c].i1].x+screenPoints[handles_info[c].i2].x)/2;
    int v = (screenPoints[handles_info[c].i1].y+screenPoints[handles_info[c].i2].y)/2;

    adjustHandle(u, v, part->width(), part->height(), angle + handles_info[c].angle);

    editor->invalidateRect(gfx::Rect(u, v, part->width(), part->height()));
  }

  // Invalidate area where the pivot is.
  if (visiblePivot(angle)) {
    gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
    she::Surface* part = theme->parts.pivotHandle()->getBitmap(0);

    editor->invalidateRect(
      gfx::Rect(pivotBounds.x, pivotBounds.y,
                part->width(), part->height()));
  }
}
void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& transform)
{
  ScreenGraphics g;
  fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);

  gfx::Transformation::Corners corners;
  transform.transformBox(corners);

  std::vector<gfx::Point> screenPoints(corners.size());
  for (size_t c=0; c<corners.size(); ++c)
    screenPoints[c] = editor->editorToScreen(
      gfx::Point((int)corners[c].x, (int)corners[c].y));

  // TODO DO NOT COMMIT
#if 0 // Uncomment this if you want to see the bounds in red (only for debugging purposes)
  // -----------------------------------------------
  {
    gfx::Point
      a(transform.bounds().getOrigin()),
      b(transform.bounds().getPoint2());
    a = editor->editorToScreen(a);
    b = editor->editorToScreen(b);
    g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(a, b));

    a = transform.pivot();
    a = editor->editorToScreen(a);
    g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(a.x-2, a.y-2, 5, 5));
  }
  // -----------------------------------------------
#endif

  // Draw corner handle
  for (size_t c=0; c<HANDLES; ++c) {
    drawHandle(&g,
      (screenPoints[handles_info[c].i1].x+screenPoints[handles_info[c].i2].x)/2,
      (screenPoints[handles_info[c].i1].y+screenPoints[handles_info[c].i2].y)/2,
      angle + handles_info[c].angle);
  }

  // Draw the pivot
  if (visiblePivot(angle)) {
    gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
    SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
    she::Surface* part = theme->parts.pivotHandle()->getBitmap(0);

    g.drawRgbaSurface(part, pivotBounds.x, pivotBounds.y);
  }
}
void set_pivot_from_preferences(gfx::Transformation& t)
{
  gfx::Transformation::Corners corners;
  t.transformBox(corners);
  gfx::PointT<double> nw(corners[gfx::Transformation::Corners::LEFT_TOP]);
  gfx::PointT<double> ne(corners[gfx::Transformation::Corners::RIGHT_TOP]);
  gfx::PointT<double> sw(corners[gfx::Transformation::Corners::LEFT_BOTTOM]);
  gfx::PointT<double> se(corners[gfx::Transformation::Corners::RIGHT_BOTTOM]);
  gfx::PointT<double> pivotPos((nw + se) / 2);

  app::gen::PivotPosition pivot = Preferences::instance().selection.pivotPosition();
  switch (pivot) {
    case app::gen::PivotPosition::NORTHWEST:
      pivotPos = nw;
      break;
    case app::gen::PivotPosition::NORTH:
      pivotPos = (nw + ne) / 2.0;
      break;
    case app::gen::PivotPosition::NORTHEAST:
      pivotPos = ne;
      break;
    case app::gen::PivotPosition::WEST:
      pivotPos = (nw + sw) / 2.0;
      break;
    case app::gen::PivotPosition::EAST:
      pivotPos = (ne + se) / 2.0;
      break;
    case app::gen::PivotPosition::SOUTHWEST:
      pivotPos = sw;
      break;
    case app::gen::PivotPosition::SOUTH:
      pivotPos = (sw + se) / 2.0;
      break;
    case app::gen::PivotPosition::SOUTHEAST:
      pivotPos = se;
      break;
  }

  t.displacePivotTo(gfx::PointF(pivotPos));
}
gfx::Rect TransformHandles::getPivotHandleBounds(Editor* editor,
                                                 const gfx::Transformation& transform,
                                                 const gfx::Transformation::Corners& corners)
{
  SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
  gfx::Size partSize = theme->parts.pivotHandle()->getSize();
  gfx::Point screenPivotPos = editor->editorToScreen(transform.pivot());

  screenPivotPos.x += editor->zoom().apply(1) / 2;
  screenPivotPos.y += editor->zoom().apply(1) / 2;

  return gfx::Rect(
    screenPivotPos.x-partSize.w/2,
    screenPivotPos.y-partSize.h/2,
    partSize.w,
    partSize.h);
}
Exemple #5
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;
}
Exemple #6
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;
}