void StatusBar::onCelOpacityChange() { try { ContextWriter writer(UIContext::instance(), 500); DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range(); if (range.enabled()) { for (Cel* cel : get_unique_cels(writer.sprite(), range)) cel->setOpacity(m_slider->getValue()); } else { Cel* cel = writer.cel(); if (cel) { // Update the opacity cel->setOpacity(m_slider->getValue()); } } // Update the editors update_screen_for_document(writer.document()); } catch (LockedDocumentException&) { // do nothing } }
void RotateCommand::onExecute(Context* context) { ContextReader reader(context); { CelList cels; bool rotateSprite = false; // Flip the mask or current cel if (m_flipMask) { DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range(); if (range.enabled()) cels = get_unique_cels(reader.sprite(), range); else if (reader.cel()) cels.push_back(reader.cel()); } // Flip the whole sprite else if (reader.sprite()) { for (Cel* cel : reader.sprite()->uniqueCels()) cels.push_back(cel); rotateSprite = true; } if (cels.empty()) // Nothing to do return; RotateJob job(reader, m_angle, cels, rotateSprite); job.startJob(); job.waitJob(); } reader.document()->generateMaskBoundaries(); update_screen_for_document(reader.document()); }
bool ReverseFramesCommand::onEnabled(Context* context) { DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range(); return context->checkFlags(ContextFlags::ActiveDocumentIsWritable) && range.enabled() && range.frames() >= 2; // We need at least 2 frames to reverse }
void ReverseFramesCommand::onExecute(Context* context) { DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range(); if (!range.enabled()) return; // Nothing to do Document* doc = context->activeDocument(); reverse_frames(doc, range); update_screen_for_document(doc); }
void CopyCommand::onExecute(Context* context) { const ContextReader reader(context); // Copy a range from the timeline. DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range(); if (range.enabled()) { clipboard::copy_range(reader, range); } else if (reader.site()->document() && static_cast<const app::Document*>(reader.site()->document())->isMaskVisible() && reader.site()->image()) { clipboard::copy(reader); } }
void ClearCommand::onExecute(Context* context) { // Clear of several frames is handled with ClearCel command. DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range(); if (range.enabled()) { Command* subCommand = NULL; switch (range.type()) { case DocumentRange::kCels: subCommand = CommandsModule::instance()->getCommandByName(CommandId::ClearCel); break; case DocumentRange::kFrames: subCommand = CommandsModule::instance()->getCommandByName(CommandId::RemoveFrame); break; case DocumentRange::kLayers: subCommand = CommandsModule::instance()->getCommandByName(CommandId::RemoveLayer); break; } if (subCommand) { context->executeCommand(subCommand); return; } } // TODO add support to clear the mask in the selected range of frames. ContextWriter writer(context); Document* document = writer.document(); bool visibleMask = document->isMaskVisible(); if (!writer.cel()) return; { Transaction transaction(writer.context(), "Clear"); transaction.execute(new cmd::ClearMask(writer.cel())); if (visibleMask) transaction.execute(new cmd::DeselectMask(document)); transaction.commit(); } if (visibleMask) document->generateMaskBoundaries(); update_screen_for_document(document); }
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; }