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));
}