Logo Search packages:      
Sourcecode: inkscape version File versions

livepatheffect-editor.cpp

/**
 * \brief LivePathEffect dialog
 *
 * Authors:
 *   Johan Engelen <j.b.c.engelen@utwente.nl>
 *
 * Copyright (C) 2007 Author
 *
 * Released under GNU GPL.  Read the file 'COPYING' for more information.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <glibmm/i18n.h>
#include "livepatheffect-editor.h"
#include "verbs.h"
#include "selection.h"
#include "sp-shape.h"
#include "sp-path.h"
#include "live_effects/effect.h"
#include "live_effects/lpeobject.h"
#include "gtkmm/widget.h"
#include <vector>
#include "inkscape.h"
#include "desktop-handles.h"
#include "desktop.h"
#include "document-private.h"
#include "xml/node.h"
#include "xml/document.h"

namespace Inkscape {
class Application;

namespace UI {
namespace Dialog {


/*####################
 * Callback functions
 */
static void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data)
{
    LivePathEffectEditor *lpeeditor = static_cast<LivePathEffectEditor *>(data);
    lpeeditor->onSelectionChanged(selection);
}


/*#######################
 * LivePathEffectEditor
 */

LivePathEffectEditor::LivePathEffectEditor() 
    : UI::Widget::Panel("", "dialogs.livepatheffect", SP_VERB_DIALOG_LIVE_PATH_EFFECT),
      combo_effecttype(Inkscape::LivePathEffect::LPETypeConverter),
      button_apply(_("_Apply"), _("Apply chosen effect to selection")),
      button_remove(_("_Remove"), _("Remove effect from selection")),
      effectwidget(NULL),
      explain_label("", Gtk::ALIGN_CENTER),
      effectapplication_frame(_("Apply new effect")),
      effectcontrol_frame(_("Current effect")),
      current_desktop(NULL)
{
    Gtk::Box *contents = _getContents();
    contents->set_spacing(4);

    effectapplication_hbox.set_spacing(4);
    effectcontrol_vbox.set_spacing(4);

    effectapplication_hbox.pack_start(combo_effecttype, true, true);
    effectapplication_hbox.pack_start(button_apply, true, true);
    effectapplication_frame.add(effectapplication_hbox);

    effectcontrol_vbox.pack_start(explain_label, true, true);
    effectcontrol_vbox.pack_end(button_remove, true, true);
    effectcontrol_frame.add(effectcontrol_vbox);

    contents->pack_start(effectapplication_frame, false, false);
    contents->pack_start(effectcontrol_frame, false, false);

    // connect callback functions to buttons
    button_apply.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectEditor::onApply));
    button_remove.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectEditor::onRemove));

    show_all_children();

    button_remove.hide();
}

LivePathEffectEditor::~LivePathEffectEditor() 
{
    if (effectwidget) {
        effectcontrol_vbox.remove(*effectwidget);
        delete effectwidget;
        effectwidget = NULL;
    }

    if (current_desktop) {
        selection_changed_connection.disconnect();
    }
}

void
LivePathEffectEditor::showParams(LivePathEffect::Effect* effect)
{
    if (effectwidget) {
        effectcontrol_vbox.remove(*effectwidget);
        delete effectwidget;
        effectwidget = NULL;
    }

    explain_label.set_markup("<b>" + effect->getName() + "</b>");
    effectwidget = effect->newWidget(&tooltips);
    if (effectwidget) {
        effectcontrol_vbox.pack_start(*effectwidget, true, true);
    }
    button_remove.show();

    effectcontrol_vbox.show_all_children();
    // fixme: add resizing of dialog
}

void
LivePathEffectEditor::showText(Glib::ustring const &str)
{
    if (effectwidget) {
        effectcontrol_vbox.remove(*effectwidget);
        delete effectwidget;
        effectwidget = NULL;
    }

    explain_label.set_label(str);
    button_remove.hide();

    // fixme: do resizing of dialog ?
}

void
LivePathEffectEditor::set_sensitize_all(bool sensitive)
{
    combo_effecttype.set_sensitive(sensitive);
    button_apply.set_sensitive(sensitive);
    button_remove.set_sensitive(sensitive);
}

void
LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
{
    if ( sel && !sel->isEmpty() ) {
        SPItem *item = sel->singleItem();
        if ( item ) {
            if ( SP_IS_SHAPE(item) ) {
                SPShape *shape = SP_SHAPE(item);
                LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
                set_sensitize_all(true);
                if (lpeobj) {
                    if (lpeobj->lpe) {
                        showParams(lpeobj->lpe);
                    } else {
                        showText(_("Unknown effect is applied"));
                    }
                } else {
                    showText(_("No effect applied"));
                    button_remove.set_sensitive(false);
                }
            } else {
                showText(_("Item is not a shape or path"));
                set_sensitize_all(false);
            }
        } else {
            showText(_("Only one item can be selected"));
            set_sensitize_all(false);
        }
    } else {
        showText(_("Empty selection"));
        set_sensitize_all(false);
    }
}

void 
LivePathEffectEditor::setDesktop(SPDesktop *desktop)
{
    Panel::setDesktop(desktop);

    if ( desktop == current_desktop ) {
        return;
    }

    if (current_desktop) {
        selection_changed_connection.disconnect();
    }

    current_desktop = desktop;
    if (desktop) {
        Inkscape::Selection *selection = sp_desktop_selection(desktop);
        selection_changed_connection = selection->connectChanged(
            sigc::bind (sigc::ptr_fun(&lpeeditor_selection_changed), this ) );

        onSelectionChanged(selection);
    } else {
        onSelectionChanged(NULL);
    }
}




/*########################################################################
# BUTTON CLICK HANDLERS    (callbacks)
########################################################################*/

// TODO:  factor out the effect applying code which can be called from anywhere. (selection-chemistry.cpp also needs it)

void
LivePathEffectEditor::onApply()
{
    Inkscape::Selection *sel = _getSelection();
    if ( sel && !sel->isEmpty() ) {
        SPItem *item = sel->singleItem();
        if ( item && SP_IS_SHAPE(item) ) {
            SPDocument *doc = current_desktop->doc();

            const Util::EnumData<LivePathEffect::EffectType>* data = combo_effecttype.get_active_data();
            if (!data) return;

            Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
            Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect");
            repr->setAttribute("effect", data->key.c_str() );

            SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->addChild(repr, NULL); // adds to <defs> and assigns the 'id' attribute
            const gchar * repr_id = repr->attribute("id");
            Inkscape::GC::release(repr);

            gchar *href = g_strdup_printf("#%s", repr_id);
            sp_shape_set_path_effect(SP_SHAPE(item), href);
            g_free(href);

            // make sure there is an original-d for paths!!!
            if ( SP_IS_PATH(item) ) {
                Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(item);
                if ( ! pathrepr->attribute("inkscape:original-d") ) {
                    pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
                }
            }

            LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(item));
            if (lpeobj && lpeobj->lpe) {
                lpeobj->lpe->resetDefaults(item);
            }

            sp_document_done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
                             _("Create and apply path effect"));

            onSelectionChanged(sel);
        }
    }
}

void
LivePathEffectEditor::onRemove()
{
    Inkscape::Selection *sel = _getSelection();
    if ( sel && !sel->isEmpty() ) {
        SPItem *item = sel->singleItem();
        if ( item && SP_IS_SHAPE(item) ) {
            sp_shape_remove_path_effect(SP_SHAPE(item));
            showText(_("No effect applied"));
            button_remove.set_sensitive(false);
            sp_document_done ( sp_desktop_document (current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
                               _("Remove path effect") );
        }
    }
}



} // namespace Dialog
} // namespace UI
} // namespace Inkscape


Generated by  Doxygen 1.6.0   Back to index