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