Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/share/ui/menus.xml b/share/ui/menus.xml
- index 03cd74d74..27c5a5523 100644
- --- a/share/ui/menus.xml
- +++ b/share/ui/menus.xml
- @@ -224,6 +224,7 @@
- <verb verb-id="DialogAlignDistribute" />
- <verb verb-id="DialogArrange" />
- <verb verb-id="DialogPrototype" />
- + <verb verb-id="DialogAnimation" />
- </submenu>
- <submenu _name="_Path">
- <verb verb-id="ObjectToPath" />
- diff --git a/src/desktop.cpp b/src/desktop.cpp
- index 335afa17d..a99b99ebb 100644
- --- a/src/desktop.cpp
- +++ b/src/desktop.cpp
- @@ -1,3 +1,4 @@
- +
- /*
- * Editable view implementation
- *
- @@ -1945,6 +1946,7 @@ SPDesktop::show_dialogs()
- mapVerbPreference.insert(std::make_pair ("ObjectsPanel", "/dialogs/objects") );
- mapVerbPreference.insert(std::make_pair ("TagsPanel", "/dialogs/tags") );
- mapVerbPreference.insert(std::make_pair ("Prototype", "/dialogs/prototype") );
- + mapVerbPreference.insert(std::make_pair ("Animation", "/dialogs/animation") );
- for (std::map<Glib::ustring, Glib::ustring>::const_iterator iter = mapVerbPreference.begin(); iter != mapVerbPreference.end(); ++iter) {
- diff --git a/src/document.cpp b/src/document.cpp
- index 5b8fe305c..124ee7ca0 100644
- --- a/src/document.cpp
- +++ b/src/document.cpp
- @@ -1673,7 +1673,7 @@ bool SPDocument::addResource(gchar const *key, SPObject *object)
- bool result = false;
- - if ( !object->cloned ) {
- + if ( !object->cloned || !strcmp(key, "animate") ) {
- std::vector<SPObject *> rlist = priv->resources[key];
- g_return_val_if_fail(std::find(rlist.begin(),rlist.end(),object) == rlist.end(), false);
- priv->resources[key].insert(priv->resources[key].begin(),object);
- @@ -1704,7 +1704,7 @@ bool SPDocument::removeResource(gchar const *key, SPObject *object)
- bool result = false;
- - if ( !object->cloned ) {
- + if ( !object->cloned || !strcmp(key, "animate") ) {
- std::vector<SPObject *> rlist = priv->resources[key];
- g_return_val_if_fail(!rlist.empty(), false);
- std::vector<SPObject*>::iterator it = std::find(priv->resources[key].begin(),priv->resources[key].end(),object);
- diff --git a/src/object/CMakeLists.txt b/src/object/CMakeLists.txt
- index 3c347ce03..e45152b79 100644
- --- a/src/object/CMakeLists.txt
- +++ b/src/object/CMakeLists.txt
- @@ -8,6 +8,7 @@ set(object_SRC
- persp3d-reference.cpp
- persp3d.cpp
- sp-anchor.cpp
- + sp-animate.cpp
- sp-clippath.cpp
- sp-conn-end-pair.cpp
- sp-conn-end.cpp
- diff --git a/src/object/sp-animate.cpp b/src/object/sp-animate.cpp
- new file mode 100644
- index 000000000..c5902c13b
- --- /dev/null
- +++ b/src/object/sp-animate.cpp
- @@ -0,0 +1,399 @@
- +/*
- + * SVG <animate> implementation
- + *
- + * Authors:
- + *
- + * Copyright (C) 2018 authors
- + *
- + * Released under GNU GPL, read the file 'COPYING' for more information
- + */
- +#include <cmath>
- +
- +#include "attributes.h"
- +#include "desktop-style.h"
- +#include "sp-animate.h"
- +#include "xml/repr.h"
- +#include "document.h"
- +
- +#include "svg/stringstream.h"
- +
- +SPAnimate::SPAnimate() : SPObject() {
- + this->begin = 0;
- + this->end = std::numeric_limits<float>::infinity();
- + this->dur = std::numeric_limits<float>::infinity();
- +
- + this->calcMode = g_strdup("linear");
- + this->attributeName = SP_ATTR_INVALID;
- +
- + this->_originalValue = nullptr;
- +}
- +
- +SPAnimate::~SPAnimate() = default;
- +
- +void SPAnimate::release() {
- + if (this->calcMode) {
- + g_free(this->calcMode);
- + }
- +
- + if (this->document) {
- + // Unregister ourselves
- + this->document->removeResource("animate", this);
- + }
- +
- + SPObject::release();
- +}
- +
- +void SPAnimate::update(SPCtx *ctx, guint flags) {
- + if (flags & SP_OBJECT_MODIFIED_FLAG) {
- + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
- + }
- +
- + flags &= SP_OBJECT_MODIFIED_CASCADE;
- + std::vector<SPObject*> l(this->childList(true));
- + for(std::vector<SPObject*>::const_iterator i=l.begin();i!=l.end();++i){
- + SPObject *child = *i;
- + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
- + child->updateDisplay(ctx, flags);
- + }
- + sp_object_unref(child);
- + }
- +}
- +
- +std::vector<float> SPAnimate::_read_semicolon_list(gchar const *value) {
- + std::vector<float> v;
- +
- + gchar const* beg = value;
- + while(isspace(*beg) || (*beg == ';')) beg++;
- + while(*beg)
- + {
- + char *end;
- + double ret = g_ascii_strtod(beg, &end);
- + if (end==beg){
- + g_warning("SPAnimate::_read_semicolon_list() Unable to convert \"%s\" to number", beg);
- + // We could leave this out, too. If strtod can't convert
- + // anything, it will return zero.
- + // ret = 0;
- + break;
- + }
- + v.push_back(ret);
- +
- + beg = end;
- + while(isspace(*beg) || (*beg == ';')) beg++;
- + }
- + return v;
- +}
- +
- +void SPAnimate::build(SPDocument *doc, Inkscape::XML::Node* repr) {
- + SPObject::build(doc, repr);
- +
- + this->readAttr("begin");
- + this->readAttr("dur");
- + this->readAttr("repeatCount");
- + this->readAttr("repeatDur");
- + this->readAttr("end");
- +
- + this->readAttr("calcMode");
- + this->readAttr("values");
- + this->readAttr("keyTimes");
- +
- + this->readAttr("attributeName");
- +
- + if (this->values.size() == 0) {
- + this->readAttr("from");
- + this->readAttr("by");
- + this->readAttr("to");
- + }
- + if (this->keyTimes.size() == 0) {
- + int size = this->values.size();
- + if (!strcmp(this->calcMode, "discrete")) {
- + for (int i = 0; i < size; i++) {
- + this->keyTimes.push_back(1.0 * i / size);
- + }
- + } else {
- + g_assert(size != 1);
- + for (int i = 0; i < size; i++) {
- + this->keyTimes.push_back(1.0 * i / (size - 1));
- + }
- + }
- + } else {
- + if (this->keyTimes.size() != this->values.size()) {
- + g_warning("SPAnimate::build() keyTimes and values have different number of values");
- + while (this->keyTimes.size() > this->values.size()) {
- + this->values.push_back(this->values.back());
- + }
- + while (this->keyTimes.size() < this->values.size()) {
- + this->values.pop_back();
- + }
- + }
- + if (this->keyTimes.front() != 0.0) {
- + g_warning("SPAnimate::build() first keyTimes is not 0");
- + this->keyTimes.front() = 0.0;
- + }
- + if (strcmp(this->calcMode, "discrete") && this->keyTimes.back() != 1.0) {
- + g_warning("SPAnimate::build() last keyTimes is not 1");
- + this->keyTimes.back() = 0.0;
- + }
- + }
- +
- + // Register ourselves
- + doc->addResource("animate", this);
- +}
- +
- +void SPAnimate::set(SPAttributeEnum key, const gchar *value) {
- + switch (key) {
- + case SP_ATTR_BEGIN:
- + if (value) {
- + if (!strcmp (value, "indefinite")) {
- + this->begin = std::numeric_limits<float>::infinity();
- + } else {
- + this->begin = g_ascii_strtod (value, nullptr);
- + }
- + }
- + break;
- + case SP_ATTR_DUR:
- + if (value) {
- + if (!strcmp (value, "indefinite")) {
- + this->dur = std::numeric_limits<float>::infinity();
- + } else {
- + this->dur = g_ascii_strtod (value, nullptr);
- + }
- + this->end = this->begin + this->dur;
- + }
- + break;
- +
- + case SP_ATTR_REPEATCOUNT:
- + if (value) {
- + float end_;
- + if (!strcmp (value, "indefinite")) {
- + this->end = std::numeric_limits<float>::infinity();
- + } else {
- + this->end = this->begin + this->dur * g_ascii_strtod (value, nullptr);
- + }
- + }
- + break;
- + case SP_ATTR_REPEATDUR:
- + if (value) {
- + float end_;
- + if (!strcmp (value, "indefinite")) {
- + end_ = std::numeric_limits<float>::infinity();
- + } else {
- + end_ = this->begin + g_ascii_strtod (value, nullptr);
- + }
- + this->end = MIN(end_, this->end);
- + }
- + break;
- + case SP_ATTR_END:
- + if (value) {
- + float end_;
- + if (!strcmp (value, "indefinite")) {
- + end_ = std::numeric_limits<float>::infinity();
- + } else {
- + end_ = g_ascii_strtod (value, nullptr);
- + }
- + this->end = MIN(end_, this->end);
- + }
- + break;
- +
- + case SP_ATTR_CALCMODE:
- + if (value) {
- + if (this->calcMode) {
- + if (strcmp(value, this->calcMode) == 0) break;
- +
- + g_free(this->calcMode);
- + this->calcMode = nullptr;
- + }
- + this->calcMode = g_strdup(value);
- + }
- + break;
- + case SP_ATTR_VALUES:
- + if (value) {
- + this->values = _read_semicolon_list(value);
- + }
- + break;
- + case SP_ATTR_FROM:
- + this->values.clear();
- + if (value) {
- + this->values.push_back(g_ascii_strtod(value, nullptr));
- + } else {
- + const char *attrKey = sp_attribute_name(this->attributeName);
- + this->values.push_back(g_ascii_strtod(this->parent->getAttribute(attrKey), nullptr));
- + }
- + break;
- + case SP_ATTR_TO:
- + if (value) {
- + this->values.push_back(g_ascii_strtod(value, nullptr));
- + }
- + break;
- + case SP_ATTR_BY:
- + if (value) {
- + g_assert(this->values.size() > 0);
- + this->values.push_back(this->values[0] + g_ascii_strtod(value, nullptr));
- + }
- + break;
- + case SP_ATTR_KEYTIMES:
- + if (value) {
- + this->keyTimes = _read_semicolon_list(value);
- + }
- + break;
- +
- + case SP_ATTR_ATTRIBUTENAME:
- + if (value) {
- + this->attributeName = sp_attribute_lookup(value);
- + }
- +
- + default:
- + SPObject::set(key, value);
- + break;
- + }
- +}
- +
- +void SPAnimate::modified(unsigned int flags) {
- + if (flags & SP_OBJECT_MODIFIED_FLAG) {
- + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
- + }
- +
- + flags &= SP_OBJECT_MODIFIED_CASCADE;
- + std::vector<SPObject *> l;
- + for (auto& child: children) {
- + sp_object_ref(&child);
- + l.push_back(&child);
- + }
- +
- + for (auto child:l) {
- + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
- + child->emitModified(flags);
- + }
- + sp_object_unref(child);
- + }
- +}
- +
- +Inkscape::XML::Node* SPAnimate::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
- + if (flags & SP_OBJECT_WRITE_BUILD) {
- +
- + if (!repr) {
- + repr = xml_doc->createElement("svg:animate");
- + }
- +
- + std::vector<Inkscape::XML::Node *> l;
- + for (auto& child: children) {
- + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, nullptr, flags);
- + if (crepr) {
- + l.push_back(crepr);
- + }
- + }
- + for (auto i=l.rbegin();i!=l.rend();++i) {
- + repr->addChild(*i, nullptr);
- + Inkscape::GC::release(*i);
- + }
- + } else {
- + for (auto& child: children) {
- + child.updateRepr(flags);
- + }
- + }
- +
- + SPObject::write(xml_doc, repr, flags);
- +
- + return repr;
- +}
- +
- +void SPAnimate::setAnimateTime(float time) {
- + if (!this->parent) {
- + g_warning("SPAnimate::setAnimateTime no parent!");
- + return;
- + }
- +
- + if (!_isAnimating(time)) {
- + restoreOriginalValue();
- + return;
- + }
- +
- + if (!_originalValue) {
- + const char *key = sp_attribute_name(this->attributeName);
- + _originalValue = g_strdup(this->parent->getAttribute(key));
- + }
- +
- + float val = _calcAnimateValue(time);
- + if (val != val) { // test for nan
- + g_warning("SPAnimate::setAnimateTime calculated value was nan");
- + return;
- + }
- + // g_message("SPAnimate::setAnimateTime val=%f", val);
- +
- + Inkscape::SVGOStringStream os;
- + os << val;
- + _setParentAttr(os.str().c_str());
- +}
- +
- +void SPAnimate::restoreOriginalValue() {
- + if (!this->parent) {
- + return;
- + }
- + if (_originalValue) {
- + _setParentAttr(_originalValue);
- + g_free(_originalValue);
- + _originalValue = nullptr;
- + }
- +}
- +
- +void SPAnimate::_setParentAttr(gchar const *val) {
- + if (SP_ATTRIBUTE_IS_CSS(this->attributeName)) {
- +
- + SPCSSAttr *css = sp_repr_css_attr_new ();
- +
- + const char *key = sp_attribute_name(this->attributeName);
- + sp_repr_css_set_property (css, key, val);
- +
- + sp_desktop_apply_css_recursive(this->parent, css, true);
- +
- + sp_repr_css_attr_unref (css);
- +
- + } else {
- + this->parent->setKeyValue(this->attributeName, val);
- + }
- +}
- +
- +bool SPAnimate::_isAnimating(float time) {
- + return this->begin <= time && time < this->end;
- +}
- +
- +float SPAnimate::_calcAnimateValue(float time) {
- + g_assert(_isAnimating(time));
- +
- + float dtime = std::fmod(time - this->begin, this->dur);
- +
- + if (!strcmp(this->calcMode, "discrete")) {
- + size_t i = 0;
- + for (; i < this->keyTimes.size() - 1; i++) {
- + if (dtime < this->dur * this->keyTimes[i + 1]) {
- + break;
- + }
- + }
- + return this->values[i];
- +
- + } else {
- + size_t i = 0;
- + for (; i < this->keyTimes.size() - 2; i++) {
- + if (dtime < this->dur * this->keyTimes[i + 1]) {
- + break;
- + }
- + }
- + float v1 = this->values[i], v2 = this->values[i + 1];
- + float t1 = this->dur * this->keyTimes[i], t2 = this->dur * this->keyTimes[i + 1];
- + if (t1 == t2) {
- + return v1;
- + }
- + // linear interpolation
- + return v1 + (v2 - v1) * (dtime - t1) / (t2 - t1);
- + }
- +}
- +
- +/*
- + Local Variables:
- + mode:c++
- + c-file-style:"stroustrup"
- + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- + indent-tabs-mode:nil
- + fill-column:99
- + End:
- +*/
- +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
- diff --git a/src/object/sp-animate.h b/src/object/sp-animate.h
- new file mode 100644
- index 000000000..bf047fdf5
- --- /dev/null
- +++ b/src/object/sp-animate.h
- @@ -0,0 +1,65 @@
- +#ifndef SEEN_SP_ANIMATE_H
- +#define SEEN_SP_ANIMATE_H
- +
- +/*
- + * SVG <animate> implementation
- + *
- + * Authors:
- + *
- + * Copyright (C) 2018 authors
- + *
- + * Released under GNU GPL, read the file 'COPYING' for more information
- + */
- +
- +#include "sp-object.h"
- +
- +#define SP_ANIMATE(obj) (dynamic_cast<SPAnimate*>((SPObject*)obj))
- +#define SP_IS_ANIMATE(obj) (dynamic_cast<const SPAnimate*>((SPObject*)obj) != NULL)
- +
- +class SPAnimate : public SPObject {
- +public:
- + SPAnimate();
- + ~SPAnimate() override;
- +
- + float begin;
- + float end;
- + float dur;
- +
- + char *calcMode;
- + std::vector<float> values;
- + std::vector<float> keyTimes;
- +
- + SPAttributeEnum attributeName;
- +
- + void setAnimateTime(float time);
- + void restoreOriginalValue();
- +
- +protected:
- + void release() override;
- + void update(SPCtx* ctx, unsigned int flags) override;
- + void build(SPDocument *doc, Inkscape::XML::Node *repr) override;
- + void set(SPAttributeEnum key, const gchar *value) override;
- + void modified(unsigned int flags) override;
- + Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override;
- +
- +private:
- + std::vector<float> _read_semicolon_list(gchar const *value);
- + bool _isAnimating(float time);
- + float _calcAnimateValue(float time);
- + void _setParentAttr(gchar const *value);
- +
- + char *_originalValue;
- +};
- +
- +#endif // SEEN_SP_ANIMATE_H
- +
- +/*
- + Local Variables:
- + mode:c++
- + c-file-style:"stroustrup"
- + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- + indent-tabs-mode:nil
- + fill-column:99
- + End:
- +*/
- +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
- diff --git a/src/object/sp-factory.cpp b/src/object/sp-factory.cpp
- index 09ef89138..20fbb1c36 100644
- --- a/src/object/sp-factory.cpp
- +++ b/src/object/sp-factory.cpp
- @@ -16,6 +16,7 @@
- #include "color-profile.h"
- #include "persp3d.h"
- #include "sp-anchor.h"
- +#include "sp-animate.h"
- #include "sp-clippath.h"
- #include "sp-defs.h"
- #include "sp-desc.h"
- @@ -308,6 +309,11 @@ SPObject *SPFactory::createObject(std::string const& id)
- ret = new SPFeTile;
- else if (id == "svg:feTurbulence")
- ret = new SPFeTurbulence;
- +
- + // animation
- + else if (id == "svg:animate")
- + ret = new SPAnimate;
- +
- else if (id == "inkscape:grid")
- ret = new SPObject; // TODO wtf
- else if (id == "rdf:RDF") // no SP node yet
- diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
- index 3411eeaba..975c794a8 100644
- --- a/src/ui/CMakeLists.txt
- +++ b/src/ui/CMakeLists.txt
- @@ -79,6 +79,7 @@ set(ui_SRC
- dialog/aboutbox.cpp
- dialog/align-and-distribute.cpp
- + dialog/animation.cpp
- dialog/calligraphic-profile-rename.cpp
- dialog/clonetiler.cpp
- dialog/color-item.cpp
- diff --git a/src/ui/dialog/animation.cpp b/src/ui/dialog/animation.cpp
- new file mode 100644
- index 000000000..064d2c818
- --- /dev/null
- +++ b/src/ui/dialog/animation.cpp
- @@ -0,0 +1,241 @@
- +/*
- + * A simple panel for layers
- + *
- + * Authors:
- + * Jon A. Cruz
- + * Abhishek Sharma
- + *
- + * Copyright (C) 2006,2010 Jon A. Cruz
- + *
- + * Released under GNU GPL, read the file 'COPYING' for more information
- + */
- +
- +#include "animation.h"
- +
- +#include <gtkmm/icontheme.h>
- +#include <gtkmm/separatormenuitem.h>
- +#include <glibmm/main.h>
- +#include <glibmm/i18n.h>
- +#include <glibmm/timer.h>
- +
- +#include "desktop-style.h"
- +#include "desktop.h"
- +#include "document-undo.h"
- +#include "document.h"
- +#include "inkscape.h"
- +#include "selection-chemistry.h"
- +#include "verbs.h"
- +
- +#include "helper/action.h"
- +#include "helper/icon-loader.h"
- +
- +#include "include/gtkmm_version.h"
- +
- +#include "object/sp-root.h"
- +#include "object/sp-animate.h"
- +
- +#include "helper/icon-loader.h"
- +#include "ui/icon-names.h"
- +#include "ui/tools/tool-base.h"
- +#include "ui/widget/spin-scale.h"
- +
- +//#define DUMP_ANIMATION 1
- +
- +namespace Inkscape {
- +namespace UI {
- +namespace Dialog {
- +
- +Animation& Animation::getInstance()
- +{
- + return *new Animation();
- +}
- +
- +enum {
- + BUTTON_PLAY = 0,
- +};
- +
- +
- +
- +class Animation::InternalUIBounce
- +{
- +public:
- + int _actionCode;
- + // SPObject* _target;
- +};
- +
- +void Animation::_takeAction( int val )
- +{
- + if ( !_pending ) {
- + _pending = new InternalUIBounce();
- + _pending->_actionCode = val;
- + Glib::signal_timeout().connect( sigc::mem_fun(*this, &Animation::_executeAction), 0 );
- + }
- +}
- +
- +bool Animation::_executeAction()
- +{
- +
- + if ( _pending
- + && (
- + (_pending->_actionCode == BUTTON_PLAY)
- + )
- + ) {
- +
- + int val = _pending->_actionCode;
- +// SPObject* target = _pending->_target;
- +
- + switch ( val ) {
- + case BUTTON_PLAY:
- + {
- + bool active = _playButton.get_active();
- + if (_isPlaying && !active) {
- + _animationStop();
- + } else if (!_isPlaying && active) {
- + _animationStart();
- + }
- + }
- + break;
- + }
- +
- +
- + delete _pending;
- + _pending = nullptr;
- + }
- +
- + return false;
- +}
- +
- +
- +/**
- + * Constructor
- + */
- +Animation::Animation() :
- + UI::Widget::Panel("/dialogs/animation", SP_VERB_DIALOG_ANIMATION),
- + deskTrack(),
- + _maxNestDepth(20),
- + _desktop(nullptr),
- + _pending(nullptr),
- + _scrollBar(_("Scroll Bar (s)"), 0, 0, 30, 0.1, 1, 1),
- + desktopChangeConn()
- +{
- + Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- + _maxNestDepth = prefs->getIntLimited("/dialogs/animation/maxDepth", 20, 1, 1000);
- +
- + _scrollBar.signal_value_changed().connect(sigc::mem_fun(*this, &Animation::_scrollBarValueChanged));
- +
- + Gtk::Box *contents = _getContents();
- + contents->pack_start(_buttonsRow);
- + contents->pack_start(_scrollBar);
- +
- + SPDesktop* targetDesktop = getDesktop();
- +
- + GtkWidget *child = GTK_WIDGET(sp_get_icon_image(INKSCAPE_ICON("media-playback-start"), GTK_ICON_SIZE_SMALL_TOOLBAR)->gobj());
- + gtk_widget_show( child );
- + _playButton.add( *Gtk::manage(Glib::wrap(child)) );
- + _playButton.set_relief(Gtk::RELIEF_NONE);
- + _playButton.signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &Animation::_takeAction), (int)BUTTON_PLAY) );
- + _buttonsSecondary.pack_start(_playButton, Gtk::PACK_SHRINK);
- +
- + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET);
- +
- + setDesktop( targetDesktop );
- +
- + show_all_children();
- +
- + // restorePanelPrefs();
- +
- + // Connect this up last
- + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Animation::setDesktop) );
- + deskTrack.connect(GTK_WIDGET(gobj()));
- +}
- +
- +Animation::~Animation()
- +{
- + setDesktop(nullptr);
- +
- + if (_pending) {
- + delete _pending;
- + _pending = nullptr;
- + }
- +
- + desktopChangeConn.disconnect();
- + deskTrack.disconnect();
- +}
- +
- +
- +void Animation::setDesktop( SPDesktop* desktop )
- +{
- + Panel::setDesktop(desktop);
- +
- + if ( desktop != _desktop ) {
- + if ( _desktop ) {
- + _desktop = nullptr;
- + }
- +
- + _desktop = Panel::getDesktop();
- + if ( _desktop ) {
- + //setLabel( _desktop->doc()->name );
- +
- + _animationStop();
- + }
- + }
- + deskTrack.setBase(desktop);
- +}
- +
- +void Animation::_scrollBarValueChanged() {
- + double val = _scrollBar.get_value();
- + _animationDraw(val);
- +}
- +
- +void Animation::_animationDraw(float time) {
- + std::vector<SPObject *> animates = SP_ACTIVE_DOCUMENT->getResourceList("animate");
- + for (std::vector<SPObject *>::const_iterator item = animates.begin(); item != animates.end(); ++item) {
- + SPAnimate *anim = SP_ANIMATE(*item);
- + anim->setAnimateTime(time);
- + }
- +}
- +
- +void Animation::_animationStart() {
- + _isPlaying = true;
- + _timer.reset();
- + _timeDiff = _scrollBar.get_value();
- + _timer.start();
- +
- + Glib::signal_timeout().connect( sigc::mem_fun(*this, &Animation::_animationNext), 1, Glib::PRIORITY_DEFAULT_IDLE );
- +}
- +
- +void Animation::_animationStop() {
- + _isPlaying = false;
- + _timer.stop();
- +
- + std::vector<SPObject *> animates = SP_ACTIVE_DOCUMENT->getResourceList("animate");
- + for (std::vector<SPObject *>::const_iterator item = animates.begin(); item != animates.end(); ++item) {
- + SPAnimate *anim = SP_ANIMATE(*item);
- + anim->restoreOriginalValue();
- + }
- +}
- +
- +bool Animation::_animationNext() {
- + if (!_isPlaying) {
- + return false;
- + }
- + _scrollBar.set_value(_timeDiff + _timer.elapsed());
- + return true;
- +}
- +
- +
- +} //namespace Dialogs
- +} //namespace UI
- +} //namespace Inkscape
- +
- +
- +/*
- + Local Variables:
- + mode:c++
- + c-file-style:"stroustrup"
- + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- + indent-tabs-mode:nil
- + fill-column:99
- + End:
- +*/
- +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
- diff --git a/src/ui/dialog/animation.h b/src/ui/dialog/animation.h
- new file mode 100644
- index 000000000..e2dab3724
- --- /dev/null
- +++ b/src/ui/dialog/animation.h
- @@ -0,0 +1,103 @@
- +/*
- + * A simple dialog for layer UI.
- + *
- + * Authors:
- + * Jon A. Cruz
- + *
- + * Copyright (C) 2006,2010 Jon A. Cruz
- + *
- + * Released under GNU GPL, read the file 'COPYING' for more information
- + */
- +
- +#ifndef SEEN_ANIMATION_PANEL_H
- +#define SEEN_ANIMATION_PANEL_H
- +
- +#include <glibmm/timer.h>
- +
- +#include <gtkmm/box.h>
- +#include "ui/widget/panel.h"
- +#include "desktop-tracker.h"
- +#include "ui/widget/style-subject.h"
- +#include "ui/widget/spin-scale.h"
- +
- +namespace Inkscape {
- +
- +namespace UI {
- +namespace Dialog {
- +
- +
- +/**
- + * A panel that displays layers.
- + */
- +class Animation : public UI::Widget::Panel
- +{
- +public:
- + Animation();
- + ~Animation() override;
- +
- + static Animation& getInstance();
- +
- + void setDesktop( SPDesktop* desktop ) override;
- +
- +private:
- + class InternalUIBounce;
- +
- + Animation(Animation const &) = delete; // no copy
- + Animation &operator=(Animation const &) = delete; // no assign
- +
- + void _fireAction( unsigned int code );
- +
- + bool _handleButtonEvent(GdkEventButton *event);
- +
- + void _takeAction( int val );
- + bool _executeAction();
- +
- + void _scrollBarValueChanged();
- +
- + void _animationDraw(float time);
- + void _animationStart();
- + void _animationStop();
- +
- + bool _animationNext();
- +
- + // Internal
- + sigc::connection _selectedConnection;
- +
- + bool _isPlaying;
- + Glib::Timer _timer;
- + double _timeDiff;
- +
- + DesktopTracker deskTrack;
- + int _maxNestDepth;
- + SPDesktop* _desktop;
- + InternalUIBounce* _pending;
- +
- + Gtk::Box _buttonsRow;
- + Gtk::Box _buttonsSecondary;
- + Gtk::ToggleButton _playButton;
- + Inkscape::UI::Widget::SpinScale _scrollBar;
- +
- + UI::Widget::StyleSubject::CurrentLayer _subject;
- + sigc::connection desktopChangeConn;
- +};
- +
- +
- +
- +} //namespace Dialogs
- +} //namespace UI
- +} //namespace Inkscape
- +
- +
- +
- +#endif // SEEN_ANIMATION_PANEL_H
- +
- +/*
- + Local Variables:
- + mode:c++
- + c-file-style:"stroustrup"
- + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- + indent-tabs-mode:nil
- + fill-column:99
- + End:
- +*/
- +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
- diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
- index 28e45d50a..143eac3a5 100644
- --- a/src/ui/dialog/dialog-manager.cpp
- +++ b/src/ui/dialog/dialog-manager.cpp
- @@ -57,6 +57,7 @@
- #include "ui/dialog/tags.h"
- #include "ui/dialog/styledialog.h"
- #include "ui/dialog/cssdialog.h"
- +#include "ui/dialog/animation.h"
- namespace Inkscape {
- namespace UI {
- @@ -143,6 +144,7 @@ DialogManager::DialogManager() {
- registerFactory("Export", &create<Export, FloatingBehavior>);
- registerFactory("CloneTiler", &create<CloneTiler, FloatingBehavior>);
- registerFactory("XmlTree", &create<XmlTree, FloatingBehavior>);
- + registerFactory("Animation", &create<Animation, FloatingBehavior>);
- } else {
- @@ -186,6 +188,7 @@ DialogManager::DialogManager() {
- registerFactory("Export", &create<Export, DockBehavior>);
- registerFactory("CloneTiler", &create<CloneTiler, DockBehavior>);
- registerFactory("XmlTree", &create<XmlTree, DockBehavior>);
- + registerFactory("Animation", &create<Animation, DockBehavior>);
- }
- }
- diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp
- index 216b2688b..ecf83d5db 100644
- --- a/src/ui/widget/selected-style.cpp
- +++ b/src/ui/widget/selected-style.cpp
- @@ -45,6 +45,7 @@
- #include "ui/dialog/panel-dialog.h"
- #include "ui/tools/tool-base.h"
- #include "ui/widget/color-preview.h"
- +#include "ui/dialog/animation.h"
- #include "widgets/gradient-image.h"
- #include "widgets/spinbutton-events.h"
- diff --git a/src/verbs.cpp b/src/verbs.cpp
- index fe617148a..2a6a133fd 100644
- --- a/src/verbs.cpp
- +++ b/src/verbs.cpp
- @@ -2289,7 +2289,9 @@ void DialogVerb::perform(SPAction *action, void *data)
- case SP_VERB_DIALOG_CSS:
- dt->_dlg_mgr->showDialog("CssDialog");
- break;
- -
- + case SP_VERB_DIALOG_ANIMATION:
- + dt->_dlg_mgr->showDialog("Animation");
- + break;
- default:
- break;
- }
- @@ -3209,6 +3211,9 @@ Verb *Verb::_base_verbs[] = {
- N_("Select which color separations to render in Print Colors Preview rendermode"), nullptr),
- new DialogVerb(SP_VERB_DIALOG_EXPORT, "DialogExport", N_("_Export PNG Image..."),
- N_("Export this document or a selection as a PNG image"), INKSCAPE_ICON("document-export")),
- + new DialogVerb(SP_VERB_DIALOG_ANIMATION, "DialogAnimation", N_("_Play SVG files..."),
- + N_("Play and stop svg animations..."),
- + INKSCAPE_ICON("media-playback-start")),
- // Help
- new HelpVerb(SP_VERB_HELP_ABOUT_EXTENSIONS, "HelpAboutExtensions", N_("About E_xtensions"),
- N_("Information on Inkscape extensions"), nullptr),
- diff --git a/src/verbs.h b/src/verbs.h
- index fec42cca2..ce341fc9c 100644
- --- a/src/verbs.h
- +++ b/src/verbs.h
- @@ -342,6 +342,7 @@ enum {
- SP_VERB_DIALOG_SVG_FONTS,
- SP_VERB_DIALOG_PRINT_COLORS_PREVIEW,
- SP_VERB_DIALOG_EXPORT,
- + SP_VERB_DIALOG_ANIMATION,
- /* Help */
- SP_VERB_HELP_ABOUT_EXTENSIONS,
- SP_VERB_HELP_MEMORY,
Add Comment
Please, Sign In to add comment