frame_t onGetFrame(Editor* editor) override { frame_t frame = editor->frame(); FrameTag* tag = editor ->getCustomizationDelegate() ->getFrameTagProvider() ->getFrameTagByFrame(frame, false); frame_t first = (tag ? tag->fromFrame(): 0); frame_t last = (tag ? tag->toFrame(): editor->sprite()->lastFrame()); return (frame < last ? frame+1: first); }
void FrameTagPropertiesCommand::onExecute(Context* context) { const ContextReader reader(context); const Sprite* sprite = reader.sprite(); frame_t frame = reader.frame(); const FrameTag* foundTag = nullptr; if (!m_tagName.empty()) foundTag = sprite->frameTags().getByName(m_tagName); else if (m_tagId != NullId) foundTag = sprite->frameTags().getById(m_tagId); else foundTag = sprite->frameTags().innerTag(frame); if (!foundTag) return; FrameTagWindow window(sprite, foundTag); if (!window.show()) return; ContextWriter writer(reader); Transaction transaction(writer.context(), "Change Frame Tag Properties"); FrameTag* tag = const_cast<FrameTag*>(foundTag); std::string name = window.nameValue(); if (tag->name() != name) transaction.execute(new cmd::SetFrameTagName(tag, name)); doc::frame_t from, to; window.rangeValue(from, to); if (tag->fromFrame() != from || tag->toFrame() != to) { transaction.execute(new cmd::SetFrameTagRange(tag, from, to)); } doc::color_t docColor = window.colorValue(); if (tag->color() != docColor) transaction.execute(new cmd::SetFrameTagColor(tag, docColor)); doc::AniDir anidir = window.aniDirValue(); if (tag->aniDir() != anidir) transaction.execute(new cmd::SetFrameTagAniDir(tag, anidir)); transaction.commit(); }
void SaveFileCopyAsCommand::onExecute(Context* context) { Doc* doc = context->activeDocument(); std::string outputFilename = m_filename; std::string layers = kAllLayers; std::string frames = kAllFrames; double xscale = 1.0; double yscale = 1.0; bool applyPixelRatio = false; doc::AniDir aniDirValue = convert_string_to_anidir(m_aniDir); bool isForTwitter = false; #if ENABLE_UI if (context->isUIAvailable()) { ExportFileWindow win(doc); bool askOverwrite = true; win.SelectOutputFile.connect( [this, &win, &askOverwrite, context, doc]() -> std::string { std::string result = saveAsDialog( context, "Export", win.outputFilenameValue(), false, false, (doc->isAssociatedToFile() ? doc->filename(): std::string())); if (!result.empty()) askOverwrite = false; // Already asked in the file selector dialog return result; }); again:; if (!win.show()) return; outputFilename = win.outputFilenameValue(); if (askOverwrite && base::is_file(outputFilename)) { int ret = OptionalAlert::show( Preferences::instance().exportFile.showOverwriteFilesAlert, 1, // Yes is the default option when the alert dialog is disabled fmt::format(Strings::alerts_overwrite_files_on_export(), outputFilename)); if (ret != 1) goto again; } // Save the preferences used to export the file, so if we open the // window again, we will have the same options. win.savePref(); layers = win.layersValue(); frames = win.framesValue(); xscale = yscale = win.resizeValue(); applyPixelRatio = win.applyPixelRatio(); aniDirValue = win.aniDirValue(); isForTwitter = win.isForTwitter(); } #endif // Pixel ratio if (applyPixelRatio) { doc::PixelRatio pr = doc->sprite()->pixelRatio(); xscale *= pr.w; yscale *= pr.h; } // Apply scale const undo::UndoState* undoState = nullptr; bool undoResize = false; if (xscale != 1.0 || yscale != 1.0) { Command* resizeCmd = Commands::instance()->byId(CommandId::SpriteSize()); ASSERT(resizeCmd); if (resizeCmd) { int width = doc->sprite()->width(); int height = doc->sprite()->height(); int newWidth = int(double(width) * xscale); int newHeight = int(double(height) * yscale); if (newWidth < 1) newWidth = 1; if (newHeight < 1) newHeight = 1; if (width != newWidth || height != newHeight) { doc->setInhibitBackup(true); undoState = doc->undoHistory()->currentState(); undoResize = true; Params params; params.set("use-ui", "false"); params.set("width", base::convert_to<std::string>(newWidth).c_str()); params.set("height", base::convert_to<std::string>(newHeight).c_str()); params.set("resize-method", "nearest-neighbor"); // TODO add algorithm in the UI? context->executeCommand(resizeCmd, params); } } } { RestoreVisibleLayers layersVisibility; if (context->isUIAvailable()) { Site site = context->activeSite(); // Selected layers to export calculate_visible_layers(site, layers, layersVisibility); // Selected frames to export SelectedFrames selFrames; FrameTag* frameTag = calculate_selected_frames( site, frames, selFrames); if (frameTag) m_frameTag = frameTag->name(); m_selFrames = selFrames; m_adjustFramesByFrameTag = false; } base::ScopedValue<std::string> restoreAniDir( m_aniDir, convert_anidir_to_string(aniDirValue), // New value m_aniDir); // Restore old value // TODO This should be set as options for the specific encoder GifEncoderDurationFix fixGif(isForTwitter); PngEncoderOneAlphaPixel fixPng(isForTwitter); saveDocumentInBackground( context, doc, outputFilename, false); } // Undo resize if (undoResize && undoState != doc->undoHistory()->currentState()) { moveToUndoState(doc, undoState); doc->setInhibitBackup(false); } }