void FramePropertiesCommand::onExecute(Context* context) { const ContextReader reader(context); const Sprite* sprite = reader.sprite(); auto& docPref = Preferences::instance().document(context->activeDocument()); int base = docPref.timeline.firstFrame(); app::gen::FrameProperties window; SelectedFrames selFrames; switch (m_target) { case ALL_FRAMES: selFrames.insert(0, sprite->lastFrame()); break; case CURRENT_RANGE: { Site site = context->activeSite(); if (site.inTimeline()) { selFrames = site.selectedFrames(); } else { selFrames.insert(site.frame()); } break; } case SPECIFIC_FRAME: selFrames.insert(m_frame-base); break; } ASSERT(!selFrames.empty()); if (selFrames.empty()) return; if (selFrames.size() == 1) window.frame()->setTextf("%d", selFrames.firstFrame()+base); else if (selFrames.ranges() == 1) { window.frame()->setTextf("[%d...%d]", selFrames.firstFrame()+base, selFrames.lastFrame()+base); } else window.frame()->setTextf("Multiple Frames"); window.frlen()->setTextf( "%d", sprite->frameDuration(selFrames.firstFrame())); window.openWindowInForeground(); if (window.closer() == window.ok()) { int newMsecs = window.frlen()->textInt(); ContextWriter writer(reader); Transaction transaction(writer.context(), "Frame Duration"); DocApi api = writer.document()->getApi(transaction); for (frame_t frame : selFrames) api.setFrameDuration(writer.sprite(), frame, newMsecs); transaction.commit(); } }