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