Пример #1
0
cmsHTRANSFORM Inkscape::CMSSystem::getDisplayTransform()
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display");
    if ( fromDisplay ) {
        if ( transf ) {
            cmsDeleteTransform(transf);
            transf = 0;
        }
        return 0;
    }

    bool warn = prefs->getBool( "/options/softproof/gamutwarn");
    int intent = prefs->getIntLimited( "/options/displayprofile/intent", 0, 0, 3 );
    int proofIntent = prefs->getIntLimited( "/options/softproof/intent", 0, 0, 3 );
    bool bpc = prefs->getBool( "/options/softproof/bpc");
#if defined(cmsFLAGS_PRESERVEBLACK)
    bool preserveBlack = prefs->getBool( "/options/softproof/preserveblack");
#endif //defined(cmsFLAGS_PRESERVEBLACK)
    Glib::ustring colorStr = prefs->getString("/options/softproof/gamutcolor");

#if WITH_GTKMM_3_0
    Gdk::RGBA gamutColor( colorStr.empty() ? "#808080" : colorStr );
#else
    Gdk::Color gamutColor( colorStr.empty() ? "#808080" : colorStr );
#endif

    if ( (warn != gamutWarn)
            || (lastIntent != intent)
            || (lastProofIntent != proofIntent)
            || (bpc != lastBPC)
#if defined(cmsFLAGS_PRESERVEBLACK)
            || (preserveBlack != lastPreserveBlack)
#endif // defined(cmsFLAGS_PRESERVEBLACK)
            || (gamutColor != lastGamutColor)
       ) {
        gamutWarn = warn;
        free_transforms();
        lastIntent = intent;
        lastProofIntent = proofIntent;
        lastBPC = bpc;
#if defined(cmsFLAGS_PRESERVEBLACK)
        lastPreserveBlack = preserveBlack;
#endif // defined(cmsFLAGS_PRESERVEBLACK)
        lastGamutColor = gamutColor;
    }

    // Fetch these now, as they might clear the transform as a side effect.
    cmsHPROFILE hprof = getSystemProfileHandle();
    cmsHPROFILE proofProf = hprof ? getProofProfileHandle() : 0;

    if ( !transf ) {
        if ( hprof && proofProf ) {
            cmsUInt32Number dwFlags = cmsFLAGS_SOFTPROOFING;
            if ( gamutWarn ) {
                dwFlags |= cmsFLAGS_GAMUTCHECK;

#if WITH_GTKMM_3_0
                gushort gamutColor_r = gamutColor.get_red_u();
                gushort gamutColor_g = gamutColor.get_green_u();
                gushort gamutColor_b = gamutColor.get_blue_u();
#else
                gushort gamutColor_r = gamutColor.get_red();
                gushort gamutColor_g = gamutColor.get_green();
                gushort gamutColor_b = gamutColor.get_blue();
#endif

#if HAVE_LIBLCMS1
                cmsSetAlarmCodes(gamutColor_r >> 8, gamutColor_g >> 8, gamutColor_b >> 8);
#elif HAVE_LIBLCMS2
                cmsUInt16Number newAlarmCodes[cmsMAXCHANNELS] = {0};
                newAlarmCodes[0] = gamutColor_r;
                newAlarmCodes[1] = gamutColor_g;
                newAlarmCodes[2] = gamutColor_b;
                newAlarmCodes[3] = ~0;
                cmsSetAlarmCodes(newAlarmCodes);
#endif
            }
            if ( bpc ) {
                dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
            }
#if defined(cmsFLAGS_PRESERVEBLACK)
            if ( preserveBlack ) {
                dwFlags |= cmsFLAGS_PRESERVEBLACK;
            }
#endif // defined(cmsFLAGS_PRESERVEBLACK)
            transf = cmsCreateProofingTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags );
        } else if ( hprof ) {
Пример #2
0
void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
    Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    {
        /* Width */
        gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")};
        gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "SprayWidthAction",
                                                              _("Width"), _("Width:"), _("The width of the spray area (relative to the visible canvas area)"),
                                                              "/tools/spray/width", 15,
                                                              GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spray",
                                                              1, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_spray_width_value_changed, NULL /*unit tracker*/, 1, 0 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    }

    {
        /* Mean */
        gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")};
        gdouble values[] = {0, 5, 10, 20, 30, 50, 70, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "SprayMeanAction",
                                                              _("Focus"), _("Focus:"), _("0 to spray a spot; increase to enlarge the ring radius"),
                                                              "/tools/spray/mean", 0,
                                                              GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-mean",
                                                              0, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_spray_mean_value_changed, NULL /*unit tracker*/, 1, 0 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    }

    {
        /* Standard_deviation */
        gchar const* labels[] = {_("(minimum scatter)"), 0, 0, 0, 0, 0, _("(default)"), _("(maximum scatter)")};
        gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "SprayStandard_deviationAction",
                                                              C_("Spray tool", "Scatter"), C_("Spray tool", "Scatter:"), _("Increase to scatter sprayed objects"),
                                                              "/tools/spray/standard_deviation", 70,
                                                              GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-standard_deviation",
                                                              1, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_spray_standard_deviation_value_changed, NULL /*unit tracker*/, 1, 0 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    }

    /* Mode */
    {
        GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );

        GtkTreeIter iter;
        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Spray with copies"),
                            1, _("Spray copies of the initial selection"),
                            2, INKSCAPE_ICON("spray-mode-copy"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Spray with clones"),
                            1, _("Spray clones of the initial selection"),
                            2, INKSCAPE_ICON("spray-mode-clone"),
                            -1 );
#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH
        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Spray single path"),
                            1, _("Spray objects in a single path"),
                            2, INKSCAPE_ICON("spray-mode-union"),
                            -1 );
#endif
        EgeSelectOneAction* act = ege_select_one_action_new( "SprayModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) );
        g_object_set( act, "short_label", _("Mode:"), NULL );
        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
        g_object_set_data( holder, "mode_action", act );

        ege_select_one_action_set_appearance( act, "full" );
        ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
        g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
        ege_select_one_action_set_icon_column( act, 2 );
        ege_select_one_action_set_icon_size( act, secondarySize );
        ege_select_one_action_set_tooltip_column( act, 1  );

        gint mode = prefs->getInt("/tools/spray/mode", 1);
        ege_select_one_action_set_active( act, mode );
        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_spray_mode_changed), holder );

        g_object_set_data( G_OBJECT(holder), "spray_tool_mode", act);
    }

    {   /* Population */
        gchar const* labels[] = {_("(low population)"), 0, 0, 0, _("(default)"), 0, _("(high population)")};
        gdouble values[] = {5, 20, 35, 50, 70, 85, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "SprayPopulationAction",
                                                              _("Amount"), _("Amount:"),
                                                              _("Adjusts the number of items sprayed per click"),
                                                              "/tools/spray/population", 70,
                                                              GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-population",
                                                              1, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_spray_population_value_changed, NULL /*unit tracker*/, 1, 0 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
        g_object_set_data( holder, "spray_population", eact );
    }

    /* Use Pressure button */
    {
        InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction",
                                                      _("Pressure"),
                                                      _("Use the pressure of the input device to alter the amount of sprayed objects"),
                                                      INKSCAPE_ICON("draw-use-pressure"),
                                                      Inkscape::ICON_SIZE_DECORATION );
        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
        PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressure");
        g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher);

    }

    {   /* Rotation */
        gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high rotation variation)")};
        gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "SprayRotationAction",
                                                              _("Rotation"), _("Rotation:"),
                                                              // xgettext:no-c-format
                                                              _("Variation of the rotation of the sprayed objects; 0% for the same rotation than the original object"),
                                                              "/tools/spray/rotation_variation", 0,
                                                              GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-rotation",
                                                              0, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_spray_rotation_value_changed, NULL /*unit tracker*/, 1, 0 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
        g_object_set_data( holder, "spray_rotation", eact );
    }

    {   /* Scale */
        gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high scale variation)")};
        gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "SprayScaleAction",
                                                              C_("Spray tool", "Scale"), C_("Spray tool", "Scale:"),
                                                              // xgettext:no-c-format
                                                              _("Variation in the scale of the sprayed objects; 0% for the same scale than the original object"),
                                                              "/tools/spray/scale_variation", 0,
                                                              GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-scale",
                                                              0, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_spray_scale_value_changed, NULL /*unit tracker*/, 1, 0 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
        g_object_set_data( holder, "spray_scale", eact );
    }



}
Пример #3
0
static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ )
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    prefs->setDouble( "/tools/spray/scale_variation",
            gtk_adjustment_get_value(adj));
}
Пример #4
0
ParamRadioButton::ParamRadioButton (const gchar * name,
                                    const gchar * guitext,
                                    const gchar * desc,
                                    const Parameter::_scope_t scope,
                                    bool gui_hidden,
                                    const gchar * gui_tip,
                                    Inkscape::Extension::Extension * ext,
                                    Inkscape::XML::Node * xml,
                                    AppearanceMode mode) :
    Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext),
    _value(0),
    _mode(mode),
    choices(0)
{
    // Read XML tree to add enumeration items:
    // printf("Extension Constructor: ");
    if (xml != NULL) {
        Inkscape::XML::Node *child_repr = sp_repr_children(xml);
        while (child_repr != NULL) {
            char const * chname = child_repr->name();
            if (!strcmp(chname, INKSCAPE_EXTENSION_NS "option") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) {
                Glib::ustring * newguitext = NULL;
                Glib::ustring * newvalue = NULL;
                const char * contents = sp_repr_children(child_repr)->content();

                if (contents != NULL)
                    // don't translate when 'option' but do translate when '_option'
                    newguitext = new Glib::ustring( !strcmp(chname, INKSCAPE_EXTENSION_NS "_option") ? _(contents) : contents );
                else
                    continue;

                const char * val = child_repr->attribute("value");
                if (val != NULL)
                    newvalue = new Glib::ustring(val);
                else
                    newvalue = new Glib::ustring(contents);

                if ( (newguitext) && (newvalue) ) {   // logical error if this is not true here
                    choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
                }
            }
            child_repr = sp_repr_next(child_repr);
        }
    }

    // Initialize _value with the default value from xml
    // for simplicity : default to the contents of the first xml-child
    const char * defaultval = NULL;
    if (choices)
        defaultval = ((optionentry*) choices->data)->value->c_str();

    gchar * pref_name = this->pref_name();
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name);
    g_free(pref_name);

    if (!paramval.empty())
        defaultval = paramval.data();
    if (defaultval != NULL)
        _value = g_strdup(defaultval);  // allocate space for _value

    return;
}
Пример #5
0
static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve)
{
    using namespace Inkscape::LivePathEffect;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    if (item && SP_IS_LPE_ITEM(item)) {
        bool simplify = prefs->getInt(tool_name(dc) + "/simplify", 0);
        if(simplify){
            double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0);
            tol = tol/(100.0*(102.0-tol));
            std::ostringstream ss;
            ss << tol;
            spdc_apply_simplify(ss.str(), dc, item);
            sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
        }
        if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) {
            Effect::createAndApply(SPIRO, dc->desktop->doc(), item);
        }

        if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) {
            Effect::createAndApply(BSPLINE, dc->desktop->doc(), item);
        }
        SPShape *sp_shape = dynamic_cast<SPShape *>(item);
        if (sp_shape) {
            curve = sp_shape->getCurve();
        }

        //Store the clipboard path to apply in the future without the use of clipboard
        static Geom::PathVector previous_shape_pathv;

        shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0);
        bool shape_applied = false;
        SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS);
        const char *cstroke = sp_repr_css_property(css_item, "stroke", "none");
        static SPItem *bend_item;

#define SHAPE_LENGTH 10
#define SHAPE_HEIGHT 10


        if(shape == LAST_APPLIED){

            shape = previous_shape_type;
            if(shape == CLIPBOARD || shape == BEND_CLIPBOARD){
                shape = LAST_APPLIED;
            }
        }

        switch (shape) {
            case NONE:
                // don't apply any shape
                break;
            case TRIANGLE_IN:
            {
                // "triangle in"
                std::vector<Geom::Point> points(1);
                points[0] = Geom::Point(0., SHAPE_HEIGHT/2);
                spdc_apply_powerstroke_shape(points, dc, item);

                shape_applied = true;
                break;
            }
            case TRIANGLE_OUT:
            {
                // "triangle out"
                guint curve_length = curve->get_segment_count();
                std::vector<Geom::Point> points(1);
                points[0] = Geom::Point((double)curve_length, SHAPE_HEIGHT/2);
                spdc_apply_powerstroke_shape(points, dc, item);

                shape_applied = true;
                break;
            }
            case ELLIPSE:
            {
                // "ellipse"
                SPCurve *c = new SPCurve();
                const double C1 = 0.552;
                c->moveto(0, SHAPE_HEIGHT/2);
                c->curveto(0, (1 - C1) * SHAPE_HEIGHT/2, (1 - C1) * SHAPE_LENGTH/2, 0, SHAPE_LENGTH/2, 0);
                c->curveto((1 + C1) * SHAPE_LENGTH/2, 0, SHAPE_LENGTH, (1 - C1) * SHAPE_HEIGHT/2, SHAPE_LENGTH, SHAPE_HEIGHT/2);
                c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT);
                c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2);
                c->closepath();
                spdc_paste_curve_as_freehand_shape(c->get_pathvector(), dc, item);
                c->unref();

                shape_applied = true;
                break;
            }
            case CLIPBOARD:
            {
                // take shape from clipboard;
                Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get();
                if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){
                    SPItem * pasted_clipboard = dc->selection->singleItem();
                    if(pasted_clipboard){
                        Inkscape::XML::Node *pasted_clipboard_root = pasted_clipboard->getRepr();
                        Inkscape::XML::Node *path = sp_repr_lookup_name(pasted_clipboard_root, "svg:path", -1); // unlimited search depth
                        if ( path != NULL ) {
                            gchar const *svgd = path->attribute("d");
                            dc->selection->remove(SP_OBJECT(pasted_clipboard));
                            previous_shape_pathv =  sp_svg_read_pathv(svgd);
                            previous_shape_pathv *= pasted_clipboard->transform;
                            spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item);

                            shape = CLIPBOARD;
                            shape_applied = true;
                            pasted_clipboard->deleteObject();
                        } else {
                            shape = NONE;
                        }
                    } else {
                        shape = NONE;
                    }
                } else {
                    shape = NONE;
                }
                break;
            }
            case BEND_CLIPBOARD:
            {
                Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get();
                if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){
                    gchar const *svgd = item->getRepr()->attribute("d");
                    bend_item = dc->selection->singleItem();
                    if(bend_item){
                        bend_item->moveTo(item,false);
                        bend_item->transform.setTranslation(Geom::Point());
                        spdc_apply_bend_shape(svgd, dc, bend_item);
                        dc->selection->add(SP_OBJECT(bend_item));

                        shape = BEND_CLIPBOARD;
                    } else {
                        shape = NONE;
                    }
                } else {
                    shape = NONE;
                }
                break;
            }
            case LAST_APPLIED:
            {
                if(previous_shape_type == CLIPBOARD){
                    if(previous_shape_pathv.size() != 0){
                        spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item);

                        shape_applied = true;
                        shape = CLIPBOARD;
                    } else{
                        shape = NONE;
                    }
                } else {
                    if(bend_item != NULL && bend_item->getRepr() != NULL){
                        gchar const *svgd = item->getRepr()->attribute("d");
                        dc->selection->add(SP_OBJECT(bend_item));
                        sp_selection_duplicate(dc->desktop);
                        dc->selection->remove(SP_OBJECT(bend_item));
                        bend_item = dc->selection->singleItem();
                        if(bend_item){
                            bend_item->moveTo(item,false);
                            Geom::Coord expansion_X = bend_item->transform.expansionX();
                            Geom::Coord expansion_Y = bend_item->transform.expansionY();
                            bend_item->transform = Geom::Affine(1,0,0,1,0,0);
                            bend_item->transform.setExpansionX(expansion_X);
                            bend_item->transform.setExpansionY(expansion_Y);
                            spdc_apply_bend_shape(svgd, dc, bend_item);
                            dc->selection->add(SP_OBJECT(bend_item));

                            shape = BEND_CLIPBOARD;
                        } else {
                            shape = NONE;
                        }
                    } else {
                        shape = NONE;
                    }
                }
                break;
            }
            default:
                break;
        }
        previous_shape_type = shape;

        if (shape_applied) {
            // apply original stroke color as fill and unset stroke; then return
            SPCSSAttr *css = sp_repr_css_attr_new();

            if (!strcmp(cstroke, "none")){
                sp_repr_css_set_property (css, "fill", "black");
            } else {
                sp_repr_css_set_property (css, "fill", cstroke);
            }
            sp_repr_css_set_property (css, "stroke", "none");
            sp_desktop_apply_css_recursive(item, css, true);
            sp_repr_css_attr_unref(css);
            return;
        }

        if (dc->waiting_LPE_type != INVALID_LPE) {
            Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item);
            dc->waiting_LPE_type = INVALID_LPE;

            if (SP_IS_LPETOOL_CONTEXT(dc)) {
                // since a geometric LPE was applied, we switch back to "inactive" mode
                lpetool_context_switch_mode(SP_LPETOOL_CONTEXT(dc), INVALID_LPE);
            }
        }
        if (SP_IS_PEN_CONTEXT(dc)) {
            SP_PEN_CONTEXT(dc)->setPolylineMode();
        }
    }
}
Пример #6
0
static void sp_tweak_force_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ )
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    prefs->setDouble( "/tools/tweak/force",
            gtk_adjustment_get_value(adj) * 0.01 );
}
Пример #7
0
/*  If the viewBox is missing, set one 
*/
void Metafile::setViewBoxIfMissing(SPDocument *doc) {

    if (doc && !doc->getRoot()->viewBox_set) {
        bool saved = Inkscape::DocumentUndo::getUndoSensitive(doc);
        Inkscape::DocumentUndo::setUndoSensitive(doc, false);
        
        doc->ensureUpToDate();
        
        // Set document unit
        Inkscape::XML::Node *repr = sp_document_namedview(doc, 0)->getRepr();
        Inkscape::SVGOStringStream os;
        Inkscape::Util::Unit const* doc_unit = doc->getWidth().unit;
        os << doc_unit->abbr;
        repr->setAttribute("inkscape:document-units", os.str().c_str());

        // Set viewBox
        doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc_unit), doc->getHeight().value(doc_unit)));
        doc->ensureUpToDate();

        // Scale and translate objects
        double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit);
        Inkscape::UI::ShapeEditor::blockSetItem(true);
        double dh;
        if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard
            dh = SP_ACTIVE_DOCUMENT->getHeight().value("px");
        }
        else { // for open via --file on command line
            dh = doc->getHeight().value("px");
        }

        // These should not affect input, but they do, so set them to a neutral state
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        bool transform_stroke      = prefs->getBool("/options/transform/stroke", true);
        bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true);
        bool transform_pattern     = prefs->getBool("/options/transform/pattern", true);
        bool transform_gradient    = prefs->getBool("/options/transform/gradient", true);
        prefs->setBool("/options/transform/stroke", true);
        prefs->setBool("/options/transform/rectcorners", true);
        prefs->setBool("/options/transform/pattern", true);
        prefs->setBool("/options/transform/gradient", true);
        
        doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh), true);
        Inkscape::UI::ShapeEditor::blockSetItem(false);

        // restore options
        prefs->setBool("/options/transform/stroke",      transform_stroke);
        prefs->setBool("/options/transform/rectcorners", transform_rectcorners);
        prefs->setBool("/options/transform/pattern",     transform_pattern);
        prefs->setBool("/options/transform/gradient",    transform_gradient);

        Inkscape::DocumentUndo::setUndoSensitive(doc, saved);
    }
}
Пример #8
0
/*
 * set attributes via outer (t=1) knot point:
 *   [default] increase/decrease revolution factor
 *   [control] constrain inner arg to round per PI/4
 */
void
SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);

    SPSpiral *spiral = SP_SPIRAL(item);

    gdouble  dx = p[Geom::X] - spiral->cx;
    gdouble  dy = p[Geom::Y] - spiral->cy;

    if (state & GDK_SHIFT_MASK) { // rotate without roll/unroll
        spiral->arg = atan2(dy, dx) - 2.0*M_PI*spiral->revo;
        if (!(state & GDK_MOD1_MASK)) {
            // if alt not pressed, change also rad; otherwise it is locked
            spiral->rad = MAX(hypot(dx, dy), 0.001);
        }
        if ( ( state & GDK_CONTROL_MASK )
                && snaps ) {
            spiral->arg = sp_round(spiral->arg, M_PI/snaps);
        }
    } else { // roll/unroll
        // arg of the spiral outer end
        double arg_1;
        spiral->getPolar(1, NULL, &arg_1);

        // its fractional part after the whole turns are subtracted
        double arg_r = arg_1 - sp_round(arg_1, 2.0*M_PI);

        // arg of the mouse point relative to spiral center
        double mouse_angle = atan2(dy, dx);
        if (mouse_angle < 0)
            mouse_angle += 2*M_PI;

        // snap if ctrl
        if ( ( state & GDK_CONTROL_MASK ) && snaps ) {
            mouse_angle = sp_round(mouse_angle, M_PI/snaps);
        }

        // by how much we want to rotate the outer point
        double diff = mouse_angle - arg_r;
        if (diff > M_PI)
            diff -= 2*M_PI;
        else if (diff < -M_PI)
            diff += 2*M_PI;

        // calculate the new rad;
        // the value of t corresponding to the angle arg_1 + diff:
        double t_temp = ((arg_1 + diff) - spiral->arg)/(2*M_PI*spiral->revo);
        // the rad at that t:
        double rad_new = 0;
        if (t_temp > spiral->t0)
            spiral->getPolar(t_temp, &rad_new, NULL);

        // change the revo (converting diff from radians to the number of turns)
        spiral->revo += diff/(2*M_PI);
        if (spiral->revo < 1e-3)
            spiral->revo = 1e-3;

        // if alt not pressed and the values are sane, change the rad
        if (!(state & GDK_MOD1_MASK) && rad_new > 1e-3 && rad_new/spiral->rad < 2) {
            // adjust t0 too so that the inner point stays unmoved
            double r0;
            spiral->getPolar(spiral->t0, &r0, NULL);
            spiral->rad = rad_new;
            spiral->t0 = pow(r0 / spiral->rad, 1.0/spiral->exp);
        }
        if (!IS_FINITE(spiral->t0)) spiral->t0 = 0.0;
        spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999);
    }

    (static_cast<SPObject *>(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
Пример #9
0
/**
 * \return   A new document created from the filename passed in
 * \brief    This is a generic function to use the open function of
 *           a module (including Autodetect)
 * \param    key       Identifier of which module to use
 * \param    filename  The file that should be opened
 *
 * First things first, are we looking at an autodetection?  Well if that's the case then the module
 * needs to be found, and that is done with a database lookup through the module DB.  The foreach
 * function is called, with the parameter being a gpointer array.  It contains both the filename
 * (to find its extension) and where to write the module when it is found.
 *
 * If there is no autodetection, then the module database is queried with the key given.
 *
 * If everything is cool at this point, the module is loaded, and there is possibility for
 * preferences.  If there is a function, then it is executed to get the dialog to be displayed.
 * After it is finished the function continues.
 *
 * Lastly, the open function is called in the module itself.
 */
SPDocument *open(Extension *key, gchar const *filename)
{
    Input *imod = NULL;

    if (key == NULL) {
        gpointer parray[2];
        parray[0] = (gpointer)filename;
        parray[1] = (gpointer)&imod;
        db.foreach(open_internal, (gpointer)&parray);
    } else {
        imod = dynamic_cast<Input *>(key);
    }

    bool last_chance_svg = false;
    if (key == NULL && imod == NULL) {
        last_chance_svg = true;
        imod = dynamic_cast<Input *>(db.get(SP_MODULE_KEY_INPUT_SVG));
    }

    if (imod == NULL) {
        throw Input::no_extension_found();
    }

    // Hide pixbuf extensions depending on user preferences.
    //g_warning("Extension: %s", imod->get_id());

    bool show = true;
    if (strlen(imod->get_id()) > 27) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        bool ask = prefs->getBool("/dialogs/import/ask");
        Glib::ustring id = Glib::ustring(imod->get_id(), 28);
        if (!ask && id.compare( "org.inkscape.input.gdkpixbuf") == 0) {
            show = false;
            imod->set_gui(false);
        }
    }
    imod->set_state(Extension::STATE_LOADED);

    if (!imod->loaded()) {
        throw Input::open_failed();
    }

    if (!imod->prefs(filename)) {
        return NULL;
    }

    SPDocument *doc = imod->open(filename);

    if (!doc) {
        throw Input::open_failed();
    }

    if (last_chance_svg) {
        if ( inkscape_use_gui() ) {
            sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG."));
        } else {
            g_warning("%s", _("Format autodetect failed. The file is being opened as SVG."));
        }
    }

    doc->setUri(filename);
    if (!show) {
        imod->set_gui(true);
    }

    return doc;
}
Пример #10
0
gint sp_spray_context_root_handler(SPEventContext *event_context, GdkEvent *event)
{
    SPSprayContext *tc = SP_SPRAY_CONTEXT(event_context);
    SPDesktop *desktop = event_context->desktop;

    gint ret = FALSE;

    switch (event->type) {
        case GDK_ENTER_NOTIFY:
            sp_canvas_item_show(tc->dilate_area);
            break;
        case GDK_LEAVE_NOTIFY:
            sp_canvas_item_hide(tc->dilate_area);
            break;
        case GDK_BUTTON_PRESS:
            if (event->button.button == 1 && !event_context->space_panning) {
                if (Inkscape::have_viable_layer(desktop, tc->_message_context) == false) {
                    return TRUE;
                }

                Geom::Point const motion_w(event->button.x, event->button.y);
                Geom::Point const motion_dt(desktop->w2d(motion_w));
                tc->last_push = desktop->dt2doc(motion_dt);

                sp_spray_extinput(tc, event);

                desktop->canvas->forceFullRedrawAfterInterruptions(3);
                tc->is_drawing = true;
                tc->is_dilating = true;
                tc->has_dilated = false;

                if(tc->is_dilating && event->button.button == 1 && !event_context->space_panning) {
                    sp_spray_dilate(tc, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT);
                }

                tc->has_dilated = true;
                ret = TRUE;
            }
            break;
        case GDK_MOTION_NOTIFY: {
            Geom::Point const motion_w(event->motion.x,
                                     event->motion.y);
            Geom::Point motion_dt(desktop->w2d(motion_w));
            Geom::Point motion_doc(desktop->dt2doc(motion_dt));
            sp_spray_extinput(tc, event);

            // draw the dilating cursor
            double radius = get_dilate_radius(tc);
            Geom::Affine const sm (Geom::Scale(radius/(1-tc->ratio), radius/(1+tc->ratio)) );
            sp_canvas_item_affine_absolute(tc->dilate_area, (sm*Geom::Rotate(tc->tilt))*Geom::Translate(desktop->w2d(motion_w)));
            sp_canvas_item_show(tc->dilate_area);

            guint num = 0;
            if (!desktop->selection->isEmpty()) {
                num = g_slist_length((GSList *) desktop->selection->itemList());
            }
            if (num == 0) {
                tc->_message_context->flash(Inkscape::ERROR_MESSAGE, _("<b>Nothing selected!</b> Select objects to spray."));
            }

            // dilating:
            if (tc->is_drawing && ( event->motion.state & GDK_BUTTON1_MASK )) {
                sp_spray_dilate(tc, motion_w, motion_doc, motion_doc - tc->last_push, event->button.state & GDK_SHIFT_MASK? true : false);
                //tc->last_push = motion_doc;
                tc->has_dilated = true;

                // it's slow, so prevent clogging up with events
                gobble_motion_events(GDK_BUTTON1_MASK);
                return TRUE;
            }
        }
        break;
        /*Spray with the scroll*/
        case GDK_SCROLL: {
            if (event->scroll.state & GDK_BUTTON1_MASK) {
                double temp ;
                temp = tc->population;
                tc->population = 1.0;
                desktop->setToolboxAdjustmentValue("population", tc->population * 100);
                Geom::Point const scroll_w(event->button.x, event->button.y);
                Geom::Point const scroll_dt = desktop->point();;
                Geom::Point motion_doc(desktop->dt2doc(scroll_dt));
                switch (event->scroll.direction) {
                    case GDK_SCROLL_DOWN:
                    case GDK_SCROLL_UP: {
                        if (Inkscape::have_viable_layer(desktop, tc->_message_context) == false) {
                            return TRUE;
                        }
                        tc->last_push = desktop->dt2doc(scroll_dt);
                        sp_spray_extinput(tc, event);
                        desktop->canvas->forceFullRedrawAfterInterruptions(3);
                        tc->is_drawing = true;
                        tc->is_dilating = true;
                        tc->has_dilated = false;
                        if(tc->is_dilating && !event_context->space_panning) {
                            sp_spray_dilate(tc, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0), false);
                        }
                        tc->has_dilated = true;
                        
                        tc->population = temp;
                        desktop->setToolboxAdjustmentValue("population", tc->population * 100);

                        ret = TRUE;
                    }
                    break;
                    case GDK_SCROLL_RIGHT:
                       {} break;
                    case GDK_SCROLL_LEFT:
                       {} break;
                }
            }
            break;
        }
        
        case GDK_BUTTON_RELEASE: {
            Geom::Point const motion_w(event->button.x, event->button.y);
            Geom::Point const motion_dt(desktop->w2d(motion_w));

            desktop->canvas->endForcedFullRedraws();
            tc->is_drawing = false;

            if (tc->is_dilating && event->button.button == 1 && !event_context->space_panning) {
                if (!tc->has_dilated) {
                    // if we did not rub, do a light tap
                    tc->pressure = 0.03;
                    sp_spray_dilate(tc, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT);
                }
                tc->is_dilating = false;
                tc->has_dilated = false;
                switch (tc->mode) {
                    case SPRAY_MODE_COPY:
                        DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
                                           SP_VERB_CONTEXT_SPRAY, _("Spray with copies"));
                        break;
                    case SPRAY_MODE_CLONE:
                        DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
                                           SP_VERB_CONTEXT_SPRAY, _("Spray with clones"));
                        break;
                    case SPRAY_MODE_SINGLE_PATH:
                        DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
                                           SP_VERB_CONTEXT_SPRAY, _("Spray in single path"));
                        break;
                }
            }
            break;
        }

        case GDK_KEY_PRESS:
            switch (get_group0_keyval (&event->key)) {
                case GDK_KEY_j:
                case GDK_KEY_J:
                    if (MOD__SHIFT_ONLY) {
                        sp_spray_switch_mode(tc, SPRAY_MODE_COPY, MOD__SHIFT);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_k:
                case GDK_KEY_K:
                    if (MOD__SHIFT_ONLY) {
                        sp_spray_switch_mode(tc, SPRAY_MODE_CLONE, MOD__SHIFT);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_l:
                case GDK_KEY_L:
                    if (MOD__SHIFT_ONLY) {
                        sp_spray_switch_mode(tc, SPRAY_MODE_SINGLE_PATH, MOD__SHIFT);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_Up:
                case GDK_KEY_KP_Up:
                    if (!MOD__CTRL_ONLY) {
                        tc->population += 0.01;
                        if (tc->population > 1.0) {
                            tc->population = 1.0;
                        }
                        desktop->setToolboxAdjustmentValue("spray-population", tc->population * 100);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_Down:
                case GDK_KEY_KP_Down:
                    if (!MOD__CTRL_ONLY) {
                        tc->population -= 0.01;
                        if (tc->population < 0.0) {
                            tc->population = 0.0;
                        }
                        desktop->setToolboxAdjustmentValue("spray-population", tc->population * 100);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_Right:
                case GDK_KEY_KP_Right:
                    if (!MOD__CTRL_ONLY) {
                        tc->width += 0.01;
                        if (tc->width > 1.0) {
                            tc->width = 1.0;
                        }
                        // the same spinbutton is for alt+x
                        desktop->setToolboxAdjustmentValue("altx-spray", tc->width * 100);
                        sp_spray_update_area(tc);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_Left:
                case GDK_KEY_KP_Left:
                    if (!MOD__CTRL_ONLY) {
                        tc->width -= 0.01;
                        if (tc->width < 0.01) {
                            tc->width = 0.01;
                        }
                        desktop->setToolboxAdjustmentValue("altx-spray", tc->width * 100);
                        sp_spray_update_area(tc);
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_Home:
                case GDK_KEY_KP_Home:
                    tc->width = 0.01;
                    desktop->setToolboxAdjustmentValue("altx-spray", tc->width * 100);
                    sp_spray_update_area(tc);
                    ret = TRUE;
                    break;
                case GDK_KEY_End:
                case GDK_KEY_KP_End:
                    tc->width = 1.0;
                    desktop->setToolboxAdjustmentValue("altx-spray", tc->width * 100);
                    sp_spray_update_area(tc);
                    ret = TRUE;
                    break;
                case GDK_KEY_x:
                case GDK_KEY_X:
                    if (MOD__ALT_ONLY) {
                        desktop->setToolboxFocusTo("altx-spray");
                        ret = TRUE;
                    }
                    break;
                case GDK_KEY_Shift_L:
                case GDK_KEY_Shift_R:
                    sp_spray_update_cursor(tc, true);
                    break;
                case GDK_KEY_Control_L:
                case GDK_KEY_Control_R:
                    break;
                case GDK_KEY_Delete:
                case GDK_KEY_KP_Delete:
                case GDK_KEY_BackSpace:
                    ret = event_context->deleteSelectedDrag(MOD__CTRL_ONLY);
                    break;

                default:
                    break;
            }
            break;

        case GDK_KEY_RELEASE: {
            Inkscape::Preferences *prefs = Inkscape::Preferences::get();
            switch (get_group0_keyval(&event->key)) {
                case GDK_KEY_Shift_L:
                case GDK_KEY_Shift_R:
                    sp_spray_update_cursor(tc, false);
                    break;
                case GDK_KEY_Control_L:
                case GDK_KEY_Control_R:
                    sp_spray_switch_mode (tc, prefs->getInt("/tools/spray/mode"), MOD__SHIFT);
                    tc->_message_context->clear();
                    break;
                default:
                    sp_spray_switch_mode (tc, prefs->getInt("/tools/spray/mode"), MOD__SHIFT);
                    break;
            }
        }

        default:
            break;
    }

    if (!ret) {
        if (((SPEventContextClass *) parent_class)->root_handler) {
            ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event);
        }
    }

    return ret;
}
Пример #11
0
Dock::Dock(Gtk::Orientation orientation)
    : _gdl_dock(gdl_dock_new()),
#if WITH_GDL_3_6
      _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(G_OBJECT(_gdl_dock)))),
#else
      _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
#endif
      _scrolled_window (Gtk::manage(new Gtk::ScrolledWindow))
{
#if WITH_GDL_3_6
    gtk_orientable_set_orientation(GTK_ORIENTABLE(_gdl_dock_bar),
                                   static_cast<GtkOrientation>(orientation));
#else
    gdl_dock_bar_set_orientation(_gdl_dock_bar,
                                 static_cast<GtkOrientation>(orientation));
#endif

#if WITH_GTKMM_3_0
    switch(orientation) {
        case Gtk::ORIENTATION_VERTICAL:
            _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
            break;
        case Gtk::ORIENTATION_HORIZONTAL:
            _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
    }
    
    _paned = Gtk::manage(new Gtk::Paned(orientation));
#else
    switch (orientation) {
        case Gtk::ORIENTATION_VERTICAL:
            _dock_box = Gtk::manage(new Gtk::HBox());
            _paned = Gtk::manage(new Gtk::VPaned());
            break;
        case Gtk::ORIENTATION_HORIZONTAL:
            _dock_box = Gtk::manage(new Gtk::VBox());
            _paned = Gtk::manage(new Gtk::HPaned());
    }
#endif

    _scrolled_window->add(*_dock_box);
    _scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);

    _paned->pack1(*Glib::wrap(GTK_WIDGET(_gdl_dock)), false, false);
    _paned->pack2(_filler, true, false);

    _dock_box->pack_start(*_paned, Gtk::PACK_EXPAND_WIDGET);
    _dock_box->pack_end(*Gtk::manage(Glib::wrap(GTK_WIDGET(_gdl_dock_bar))), Gtk::PACK_SHRINK);
    _dock_box->get_parent()->set_resize_mode(Gtk::RESIZE_PARENT);

    _scrolled_window->set_size_request(0);

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    GdlSwitcherStyle gdl_switcher_style =
        static_cast<GdlSwitcherStyle>(prefs->getIntLimited("/options/dock/switcherstyle",
                                                                      GDL_SWITCHER_STYLE_BOTH, 0, 4));

    GdlDockMaster* master = NULL;
    
    g_object_get(GDL_DOCK_OBJECT(_gdl_dock),
            "master", &master,
            NULL);
    
    g_object_set(master,
            "switcher-style", gdl_switcher_style,
            NULL);

    GdlDockBarStyle gdl_dock_bar_style =
        static_cast<GdlDockBarStyle>(prefs->getIntLimited("/options/dock/dockbarstyle",
                                                                     GDL_DOCK_BAR_BOTH, 0, 3));

    gdl_dock_bar_set_style(_gdl_dock_bar, gdl_dock_bar_style);

    g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this);
    g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this);

    g_signal_connect(_paned->gobj(), "button-press-event", G_CALLBACK(_on_paned_button_event), (void *)this);
    g_signal_connect(_paned->gobj(), "button-release-event", G_CALLBACK(_on_paned_button_event), (void *)this);

    signal_layout_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::Dock::_onLayoutChanged));
}
Пример #12
0
/**
 * Called to handle events on knots.
 */
static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot)
{
    g_assert(knot != NULL);
    g_assert(SP_IS_KNOT(knot));

    /* Run client universal event handler, if present */

    gboolean consumed = FALSE;

    g_signal_emit(knot, knot_signals[EVENT], 0, event, &consumed);

    if (consumed) {
        return TRUE;
    }

    g_object_ref(knot);
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);

    switch (event->type) {
	case GDK_2BUTTON_PRESS:
            if (event->button.button == 1) {
                g_signal_emit(knot, knot_signals[DOUBLECLICKED], 0, event->button.state);

                grabbed = FALSE;
                moved = FALSE;
                consumed = TRUE;
            }
            break;
	case GDK_BUTTON_PRESS:
            if (event->button.button == 1 && !knot->desktop->event_context->space_panning) {
                Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y));
                sp_knot_start_dragging(knot, p, (gint) event->button.x, (gint) event->button.y, event->button.time);
                consumed = TRUE;
            }
            break;
	case GDK_BUTTON_RELEASE:
            if (event->button.button == 1 && !knot->desktop->event_context->space_panning) {
                knot->pressure = 0;
                if (transform_escaped) {
                    transform_escaped = false;
                    consumed = TRUE;
                } else {
                    sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);
                    if (!nograb) {
                        sp_canvas_item_ungrab(knot->item, event->button.time);
                    }
                    if (moved) {
                        sp_knot_set_flag(knot,
                                         SP_KNOT_DRAGGING,
                                         FALSE);
                        g_signal_emit(knot,
                                      knot_signals[UNGRABBED], 0,
                                      event->button.state);
                        knot->_ungrabbed_signal.emit(knot);
                    } else {
                        g_signal_emit(knot,
                                      knot_signals[CLICKED], 0,
                                      event->button.state);
                        knot->_click_signal.emit(knot, event->button.state);
                    }
                    grabbed = FALSE;
                    moved = FALSE;
                    consumed = TRUE;
                }
            }
            break;
	case GDK_MOTION_NOTIFY:
            if (grabbed && !knot->desktop->event_context->space_panning) {
                consumed = TRUE;

                if ( within_tolerance
                     && ( abs( (gint) event->motion.x - xp ) < tolerance )
                     && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) {
                    break; // do not drag if we're within tolerance from origin
                }

                // Once the user has moved farther than tolerance from the original location
                // (indicating they intend to move the object, not click), then always process the
                // motion notify coordinates as given (no snapping back to origin)
                within_tolerance = false;

                if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &knot->pressure))
                    knot->pressure = CLAMP (knot->pressure, 0, 1);
                else
                    knot->pressure = 0.5;

                if (!moved) {
                    g_signal_emit(knot,
                                  knot_signals[GRABBED], 0,
                                  event->motion.state);
                    sp_knot_set_flag(knot,
                                     SP_KNOT_DRAGGING,
                                     TRUE);
                }
                Geom::Point const motion_w(event->motion.x, event->motion.y);
                Geom::Point const motion_dt = knot->desktop->w2d(motion_w);
                Geom::Point p = motion_dt - knot->grabbed_rel_pos;
                sp_knot_request_position (knot, p, event->motion.state);
                knot->desktop->scroll_to_point (motion_dt);
                knot->desktop->set_coordinate_status(knot->pos); // display the coordinate of knot, not cursor - they may be different!
                if (event->motion.state & GDK_BUTTON1_MASK)
                    gobble_motion_events(GDK_BUTTON1_MASK);
                moved = TRUE;
            }
            break;
	case GDK_ENTER_NOTIFY:
            sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
            sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);

            if (knot->tip) {
                knot->desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, knot->tip);
            }

            grabbed = FALSE;
            moved = FALSE;
            consumed = TRUE;
            break;
	case GDK_LEAVE_NOTIFY:
            sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE);
            sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);

            if (knot->tip) {
                knot->desktop->event_context->defaultMessageContext()->clear();
            }

            grabbed = FALSE;
            moved = FALSE;

            consumed = TRUE;
            break;
	case GDK_KEY_PRESS: // keybindings for knot
            switch (get_group0_keyval(&event->key)) {
		case GDK_Escape:
                    sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE);
                    if (!nograb) {
                        sp_canvas_item_ungrab(knot->item, event->button.time);
                    }
                    if (moved) {
                        sp_knot_set_flag(knot,
                                         SP_KNOT_DRAGGING,
                                         FALSE);
                        g_signal_emit(knot,
                                      knot_signals[UNGRABBED], 0,
                                      event->button.state);
                        sp_document_undo(sp_desktop_document(knot->desktop));
                        knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled."));
                        transform_escaped = true;
                        consumed = TRUE;
                    }
                    grabbed = FALSE;
                    moved = FALSE;
                    break;
		default:
                    consumed = FALSE;
                    break;
            }
            break;
	default:
            break;
    }

    g_object_unref(knot);

    return consumed;
}
Пример #13
0
static void sp_mesh_drag(SPMeshContext &rc, Geom::Point const /*pt*/, guint /*state*/, guint32 /*etime*/)
{

    SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop;
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
    SPDocument *document = sp_desktop_document(desktop);
    SPEventContext *ec = SP_EVENT_CONTEXT(&rc);

    if (!selection->isEmpty()) {

        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        int type = SP_GRADIENT_TYPE_MESH;
        Inkscape::PaintTarget fill_or_stroke = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE;

        SPGradient *vector;
        if (ec->item_to_select) {
            // pick color from the object where drag started
            vector = sp_gradient_vector_for_object(document, desktop, ec->item_to_select, fill_or_stroke);
        } else {
            // Starting from empty space:
            // Sort items so that the topmost comes last
            GSList *items = g_slist_copy ((GSList *) selection->itemList());
            items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position);
            // take topmost
            vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(g_slist_last(items)->data), fill_or_stroke);
            g_slist_free (items);
        }

        // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
        SPCSSAttr *css = sp_repr_css_attr_new();
        sp_repr_css_set_property(css, "fill-opacity", "1.0");

        for (GSList const *i = selection->itemList(); i != NULL; i = i->next) {

            //FIXME: see above
            sp_repr_css_change_recursive(SP_OBJECT(i->data)->getRepr(), css, "style");

            sp_item_set_gradient(SP_ITEM(i->data), vector, (SPGradientType) type, fill_or_stroke);

            // We don't need to do anything. Mesh is already sized appropriately.
 
            SP_OBJECT(i->data)->requestModified(SP_OBJECT_MODIFIED_FLAG);
        }
        // if (ec->_grdrag) {
        //     ec->_grdrag->updateDraggers();
        //     // prevent regenerating draggers by selection modified signal, which sometimes
        //     // comes too late and thus destroys the knot which we will now grab:
        //     ec->_grdrag->local_change = true;
        //     // give the grab out-of-bounds values of xp/yp because we're already dragging
        //     // and therefore are already out of tolerance
        //     ec->_grdrag->grabKnot (SP_ITEM(selection->itemList()->data),
        //                            type == SP_GRADIENT_TYPE_LINEAR? POINT_LG_END : POINT_RG_R1,
        //                            -1, // ignore number (though it is always 1)
        //                            fill_or_stroke, 99999, 99999, etime);
        // }
        // We did an undoable action, but SPDocumentUndo::done will be called by the knot when released

        // status text; we do not track coords because this branch is run once, not all the time
        // during drag
        int n_objects = g_slist_length((GSList *) selection->itemList());
        rc._message_context->setF(Inkscape::NORMAL_MESSAGE,
                                  ngettext("<b>Gradient</b> for %d object; with <b>Ctrl</b> to snap angle",
                                           "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects),
                                  n_objects);
    } else {
        sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient."));
    }

}
Пример #14
0
/**
Handles all keyboard and mouse input for meshs.
*/
static gint
sp_mesh_context_root_handler(SPEventContext *event_context, GdkEvent *event)
{
    // static int count = 0;
    // std::cout << "sp_mesh_context_root_handler: " << count++ << std::endl;
    static bool dragging;

    SPDesktop *desktop = event_context->desktop;
    Inkscape::Selection *selection = sp_desktop_selection (desktop);
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    SPMeshContext *rc = SP_MESH_CONTEXT(event_context);

    event_context->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
    double const nudge = prefs->getDoubleLimited("/options/nudgedistance/value", 2, 0, 1000, "px"); // in px

    GrDrag *drag = event_context->_grdrag;
    g_assert (drag);

    gint ret = FALSE;
    switch (event->type) {

    case GDK_2BUTTON_PRESS:

#ifdef DEBUG_MESH
        std::cout << "sp_mesh_context_root_handler: GDK_2BUTTON_PRESS" << std::endl;
#endif

        // Double click:
        //  If over a mesh line, divide mesh row/column
        //  If not over a line, create new gradients for selected objects.

        if ( event->button.button == 1 ) {

            // Are we over a mesh line?
            bool over_line = false;
            SPCtrlCurve *line = NULL;
            if (drag->lines) {
                for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) {
                    line = (SPCtrlCurve*) l->data;
                    over_line |= sp_mesh_context_is_over_line (rc, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y));
                }
            }

            if (over_line) {
                // We take the first item in selection, because with doubleclick, the first click
                // always resets selection to the single object under cursor
                sp_mesh_context_split_near_point(rc, SP_ITEM(selection->itemList()->data), rc->mousepoint_doc, event->button.time);

            } else {
                // Create a new gradient with default coordinates.

                for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {

                    SPItem *item = SP_ITEM(i->data);
                    SPGradientType new_type = SP_GRADIENT_TYPE_MESH;
                    Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE;

#ifdef DEBUG_MESH
                    std::cout << "sp_mesh_context_root_handler: creating new mesh on: " << (fsmode == Inkscape::FOR_FILL ? "Fill" : "Stroke") << std::endl;
#endif
                    SPGradient *vector = sp_gradient_vector_for_object(sp_desktop_document(desktop), desktop, item, fsmode);

                    SPGradient *priv = sp_item_set_gradient(item, vector, new_type, fsmode);
                    sp_gradient_reset_to_userspace(priv, item);
                }

                DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH,
                                   _("Create default mesh"));
            }
            ret = TRUE;
        }
        break;

    case GDK_BUTTON_PRESS:

#ifdef DEBUG_MESH
        std::cout << "sp_mesh_context_root_handler: GDK_BUTTON_PRESS" << std::endl;
#endif
        // Button down
        //  If Shift key down: do rubber band selection
        //  Else set origin for drag. A drag creates a new gradient if one does not exist
 
        if ( event->button.button == 1 && !event_context->space_panning ) {
            Geom::Point button_w(event->button.x, event->button.y);

            // save drag origin
            event_context->xp = (gint) button_w[Geom::X];
            event_context->yp = (gint) button_w[Geom::Y];
            event_context->within_tolerance = true;

            dragging = true;

            Geom::Point button_dt = desktop->w2d(button_w);
            if (event->button.state & GDK_SHIFT_MASK) {
                Inkscape::Rubberband::get(desktop)->start(desktop, button_dt);
            } else {
                // remember clicked item, disregarding groups, honoring Alt; do nothing with Crtl to
                // enable Ctrl+doubleclick of exactly the selected item(s)
                if (!(event->button.state & GDK_CONTROL_MASK))
                    event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE);

                if (!selection->isEmpty()) {
                    SnapManager &m = desktop->namedview->snap_manager;
                    m.setup(desktop);
                    m.freeSnapReturnByRef(button_dt, Inkscape::SNAPSOURCE_NODE_HANDLE);
                    m.unSetup();
                }
                rc->origin = button_dt;
            }

            ret = TRUE;
        }
        break;

    case GDK_MOTION_NOTIFY:

        // Mouse move

        if ( dragging
             && ( event->motion.state & GDK_BUTTON1_MASK ) && !event_context->space_panning )
        {
 
#ifdef DEBUG_MESH
            std::cout << "sp_mesh_context_root_handler: GDK_MOTION_NOTIFY: Dragging" << std::endl;
#endif
            if ( event_context->within_tolerance
                 && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance )
                 && ( abs( (gint) event->motion.y - event_context->yp ) < event_context->tolerance ) ) {
                break; // do not drag if we're within tolerance from origin
            }
            // Once the user has moved farther than tolerance from the original location
            // (indicating they intend to draw, not click), then always process the
            // motion notify coordinates as given (no snapping back to origin)
            event_context->within_tolerance = false;

            Geom::Point const motion_w(event->motion.x,
                                     event->motion.y);
            Geom::Point const motion_dt = event_context->desktop->w2d(motion_w);

            if (Inkscape::Rubberband::get(desktop)->is_started()) {
                Inkscape::Rubberband::get(desktop)->move(motion_dt);
                event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Draw around</b> handles to select them"));
            } else {
                // Create new gradient with coordinates determined by drag.
                sp_mesh_drag(*rc, motion_dt, event->motion.state, event->motion.time);
            }
            gobble_motion_events(GDK_BUTTON1_MASK);

            ret = TRUE;

        } else {
            // Not dragging

            // Do snapping
            if (!drag->mouseOver() && !selection->isEmpty()) {
                SnapManager &m = desktop->namedview->snap_manager;
                m.setup(desktop);

                Geom::Point const motion_w(event->motion.x, event->motion.y);
                Geom::Point const motion_dt = event_context->desktop->w2d(motion_w);

                m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE));
                m.unSetup();
            }

            // Highlight corner node corresponding to side or tensor node
            if( drag->mouseOver() ) {
                // MESH FIXME: Light up corresponding corner node corresponding to node we are over.
                // See "pathflash" in ui/tools/node-tool.cpp for ideas.
                // Use desktop->add_temporary_canvasitem( SPCanvasItem, milliseconds );
            }

            // Change cursor shape if over line
            bool over_line = false;
            if (drag->lines) {
                for (GSList *l = drag->lines; l != NULL; l = l->next) {
                    over_line |= sp_mesh_context_is_over_line (rc, (SPItem*) l->data, Geom::Point(event->motion.x, event->motion.y));
                }
            }

            if (rc->cursor_addnode && !over_line) {
                event_context->cursor_shape = cursor_gradient_xpm;
                sp_event_context_update_cursor(event_context);
                rc->cursor_addnode = false;
            } else if (!rc->cursor_addnode && over_line) {
                event_context->cursor_shape = cursor_gradient_add_xpm;
                sp_event_context_update_cursor(event_context);
                rc->cursor_addnode = true;
            }
        }
        break;

    case GDK_BUTTON_RELEASE:

#ifdef DEBUG_MESH
        std::cout << "sp_mesh_context_root_handler: GDK_BUTTON_RELEASE" << std::endl;
#endif

        event_context->xp = event_context->yp = 0;
        if ( event->button.button == 1 && !event_context->space_panning ) {

            // Check if over line
            bool over_line = false;
            SPCtrlLine *line = NULL;
            if (drag->lines) {
                for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) {
                    line = (SPCtrlLine*) l->data;
                    over_line = sp_mesh_context_is_over_line (rc, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y));
                    if (over_line)
                        break;
                }
            }

            if ( (event->button.state & GDK_CONTROL_MASK) && (event->button.state & GDK_MOD1_MASK ) ) {
                if (over_line && line) {
                    sp_mesh_context_split_near_point(rc, line->item, rc->mousepoint_doc, 0);
                    ret = TRUE;
                }

            } else {

                dragging = false;

                // unless clicked with Ctrl (to enable Ctrl+doubleclick).
                if (event->button.state & GDK_CONTROL_MASK) {
                    ret = TRUE;
                    break;
                }

                if (!event_context->within_tolerance) {
                    // we've been dragging, either do nothing (grdrag handles that),
                    // or rubberband-select if we have rubberband
                    Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop);
                    if (r->is_started() && !event_context->within_tolerance) {
                        // this was a rubberband drag
                        if (r->getMode() == RUBBERBAND_MODE_RECT) {
                            Geom::OptRect const b = r->getRectangle();
                            drag->selectRect(*b);
                        }
                    }

                } else if (event_context->item_to_select) {
                    if (over_line && line) {
                        // Clicked on an existing mesh line, don't change selection. This stops
                        // possible change in selection during a double click with overlapping objects
                    }
                    else {
                        // no dragging, select clicked item if any
                        if (event->button.state & GDK_SHIFT_MASK) {
                            selection->toggle(event_context->item_to_select);
                        } else {
                            selection->set(event_context->item_to_select);
                        }
                    }
                } else {
                    // click in an empty space; do the same as Esc
                    if (drag->selected) {
                        drag->deselectAll();
                    } else {
                        selection->clear();
                    }
                }

                event_context->item_to_select = NULL;
                ret = TRUE;
            }
            Inkscape::Rubberband::get(desktop)->stop();
        }
        break;

    case GDK_KEY_PRESS:

#ifdef DEBUG_MESH
        std::cout << "sp_mesh_context_root_handler: GDK_KEY_PRESS" << std::endl;
#endif

        // FIXME: tip
        switch (get_group0_keyval (&event->key)) {
        case GDK_KEY_Alt_L:
        case GDK_KEY_Alt_R:
        case GDK_KEY_Control_L:
        case GDK_KEY_Control_R:
        case GDK_KEY_Shift_L:
        case GDK_KEY_Shift_R:
        case GDK_KEY_Meta_L:  // Meta is when you press Shift+Alt (at least on my machine)
        case GDK_KEY_Meta_R:
            sp_event_show_modifier_tip (event_context->defaultMessageContext(), event,
                                        _("FIXME<b>Ctrl</b>: snap mesh angle"),
                                        _("FIXME<b>Shift</b>: draw mesh around the starting point"),
                                        NULL);
            break;

        case GDK_KEY_A:
        case GDK_KEY_a:
            if (MOD__CTRL_ONLY && drag->isNonEmpty()) {
                drag->selectAll();
                ret = TRUE;
            }
            break;

        case GDK_KEY_Escape:
            if (drag->selected) {
                drag->deselectAll();
            } else {
                selection->clear();
            }
            ret = TRUE;
            //TODO: make dragging escapable by Esc
            break;

        case GDK_KEY_Left: // move handle left
        case GDK_KEY_KP_Left:
        case GDK_KEY_KP_4:
            if (!MOD__CTRL) { // not ctrl
                gint mul = 1 + gobble_key_events(
                    get_group0_keyval(&event->key), 0); // with any mask
                if (MOD__ALT) { // alt
                    if (MOD__SHIFT) drag->selected_move_screen(mul*-10, 0); // shift
                    else drag->selected_move_screen(mul*-1, 0); // no shift
                }
                else { // no alt
                    if (MOD__SHIFT) drag->selected_move(mul*-10*nudge, 0); // shift
                    else drag->selected_move(mul*-nudge, 0); // no shift
                }
                ret = TRUE;
            }
            break;
        case GDK_KEY_Up: // move handle up
        case GDK_KEY_KP_Up:
        case GDK_KEY_KP_8:
            if (!MOD__CTRL) { // not ctrl
                gint mul = 1 + gobble_key_events(
                    get_group0_keyval(&event->key), 0); // with any mask
                if (MOD__ALT) { // alt
                    if (MOD__SHIFT) drag->selected_move_screen(0, mul*10); // shift
                    else drag->selected_move_screen(0, mul*1); // no shift
                }
                else { // no alt
                    if (MOD__SHIFT) drag->selected_move(0, mul*10*nudge); // shift
                    else drag->selected_move(0, mul*nudge); // no shift
                }
                ret = TRUE;
            }
            break;

        case GDK_KEY_Right: // move handle right
        case GDK_KEY_KP_Right:
        case GDK_KEY_KP_6:
            if (!MOD__CTRL) { // not ctrl
                gint mul = 1 + gobble_key_events(
                    get_group0_keyval(&event->key), 0); // with any mask
                if (MOD__ALT) { // alt
                    if (MOD__SHIFT) drag->selected_move_screen(mul*10, 0); // shift
                    else drag->selected_move_screen(mul*1, 0); // no shift
                }
                else { // no alt
                    if (MOD__SHIFT) drag->selected_move(mul*10*nudge, 0); // shift
                    else drag->selected_move(mul*nudge, 0); // no shift
                }
                ret = TRUE;
            }
            break;

        case GDK_KEY_Down: // move handle down
        case GDK_KEY_KP_Down:
        case GDK_KEY_KP_2:
            if (!MOD__CTRL) { // not ctrl
                gint mul = 1 + gobble_key_events(
                    get_group0_keyval(&event->key), 0); // with any mask
                if (MOD__ALT) { // alt
                    if (MOD__SHIFT) drag->selected_move_screen(0, mul*-10); // shift
                    else drag->selected_move_screen(0, mul*-1); // no shift
                }
                else { // no alt
                    if (MOD__SHIFT) drag->selected_move(0, mul*-10*nudge); // shift
                    else drag->selected_move(0, mul*-nudge); // no shift
                }
                ret = TRUE;
            }
            break;

        case GDK_KEY_Insert:
        case GDK_KEY_KP_Insert:
            // with any modifiers:
            //sp_gradient_context_add_stops_between_selected_stops (rc);
            std::cout << "Inserting stops between selected stops not implemented yet" << std::endl;
            ret = TRUE;
            break;

        case GDK_KEY_Delete:
        case GDK_KEY_KP_Delete:
        case GDK_KEY_BackSpace:
            if ( drag->selected ) {
                std::cout << "Deleting mesh stops not implemented yet" << std::endl;
                ret = TRUE;
            }
            break;

        // Mesh Operations --------------------------------------------

        case GDK_KEY_b:  // Toggle mesh side between lineto and curveto.
        case GDK_KEY_B: 
            if (MOD__ALT && drag->isNonEmpty() && drag->hasSelection()) {
                sp_mesh_context_corner_operation ( rc, MG_CORNER_SIDE_TOGGLE );
                ret = TRUE;
            }
            break;

        case GDK_KEY_c:  // Convert mesh side from generic Bezier to Bezier approximating arc,
        case GDK_KEY_C:  // preserving handle direction.
            if (MOD__ALT && drag->isNonEmpty() && drag->hasSelection()) {
                sp_mesh_context_corner_operation ( rc, MG_CORNER_SIDE_ARC );
                ret = TRUE;
            }
            break;

        case GDK_KEY_g:  // Toggle mesh tensor points on/off
        case GDK_KEY_G: 
            if (MOD__ALT && drag->isNonEmpty() && drag->hasSelection()) {
                sp_mesh_context_corner_operation ( rc, MG_CORNER_TENSOR_TOGGLE );
                ret = TRUE;
            }
            break;

        case GDK_KEY_j:  // Smooth corner color
        case GDK_KEY_J:
            if (MOD__ALT && drag->isNonEmpty() && drag->hasSelection()) {
                sp_mesh_context_corner_operation ( rc, MG_CORNER_COLOR_SMOOTH );
                ret = TRUE;
            }
            break;

        case GDK_KEY_k:  // Pick corner color
        case GDK_KEY_K:
            if (MOD__ALT && drag->isNonEmpty() && drag->hasSelection()) {
                sp_mesh_context_corner_operation ( rc, MG_CORNER_COLOR_PICK );
                ret = TRUE;
            }
            break;

        default:
            break;
        }

        break;

    case GDK_KEY_RELEASE:

#ifdef DEBUG_MESH
        std::cout << "sp_mesh_context_root_handler: GDK_KEY_RELEASE" << std::endl;
#endif
        switch (get_group0_keyval (&event->key)) {
        case GDK_KEY_Alt_L:
        case GDK_KEY_Alt_R:
        case GDK_KEY_Control_L:
        case GDK_KEY_Control_R:
        case GDK_KEY_Shift_L:
        case GDK_KEY_Shift_R:
        case GDK_KEY_Meta_L:  // Meta is when you press Shift+Alt
        case GDK_KEY_Meta_R:
            event_context->defaultMessageContext()->clear();
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }

    if (!ret) {
        if (((SPEventContextClass *) parent_class)->root_handler) {
            ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event);
        }
    }

    return ret;
}
Пример #15
0
static void tweak_toggle_doo(GtkToggleAction *act, gpointer /*data*/) {
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    prefs->setBool("/tools/tweak/doo", gtk_toggle_action_get_active(act));
}
Пример #16
0
void SPShape::print(SPPrintContext* ctx) {
	if (!this->_curve) {
    	return;
    }

    Geom::PathVector const & pathv = this->_curve->get_pathvector();
    
    if (pathv.empty()) {
    	return;
    }

	Inkscape::Preferences *prefs = Inkscape::Preferences::get();
	gint add_comments = prefs->getBool("/printing/debug/add-label-comments");
	
	if (add_comments) {
		gchar * comment = g_strdup_printf("begin '%s'", this->defaultLabel());
		sp_print_comment(ctx, comment);
		g_free(comment);
	}

    /* fixme: Think (Lauris) */
	Geom::OptRect pbox, dbox, bbox;
    pbox = this->geometricBounds();
    bbox = this->desktopVisualBounds();
    dbox = Geom::Rect::from_xywh(Geom::Point(0,0), this->document->getDimensions());
    
    Geom::Affine const i2dt(this->i2dt_affine());

    SPStyle* style = this->style;

    if (!style->fill.isNone()) {
        sp_print_fill (ctx, pathv, i2dt, style, pbox, dbox, bbox);
    }

    if (!style->stroke.isNone()) {
        sp_print_stroke (ctx, pathv, i2dt, style, pbox, dbox, bbox);
    }

    /** \todo make code prettier */
    // START marker
    for (int i = 0; i < 2; i++) {  // SP_MARKER_LOC and SP_MARKER_LOC_START    
        if ( this->_marker[i] ) {
            Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front()));
            sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx);
        }
    }
    
    // MID marker
    for (int i = 0; i < 3; i += 2) {  // SP_MARKER_LOC and SP_MARKER_LOC_MID
        if (this->_marker[i]) {
            for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
                // START position
                if ( path_it != pathv.begin() 
                     && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there
                {
                    Geom::Affine tr(sp_shape_marker_get_transform_at_start(path_it->front()));
                    sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx);
                }
                
                // MID position
                if ( path_it->size_default() > 1) {
                    Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
                    Geom::Path::const_iterator curve_it2 = ++(path_it->begin());  // outgoing curve
                    
                    while (curve_it2 != path_it->end_default())
                    {
                        /* Put marker between curve_it1 and curve_it2.
                         * Loop to end_default (so including closing segment), because when a path is closed,
                         * there should be a midpoint marker between last segment and closing straight line segment */
                        Geom::Affine tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2));

                        sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx);

                        ++curve_it1;
                        ++curve_it2;
                    }
                }
                
                if ( path_it != (pathv.end()-1) && !path_it->empty()) {
                    Geom::Curve const &lastcurve = path_it->back_default();
                    Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve);
                    sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx);
                }
            }
        }
    }
    
    // END marker
    if ( this->_marker[SP_MARKER_LOC_END] || this->_marker[SP_MARKER_LOC]) {
        /* Get reference to last curve in the path.
         * For moveto-only path, this returns the "closing line segment". */
        Geom::Path const &path_last = pathv.back();
        unsigned int index = path_last.size_default();
        
        if (index > 0) {
            index--;
        }
        
        Geom::Curve const &lastcurve = path_last[index];

        Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve);

        for (int i = 0; i < 4; i += 3) {  // SP_MARKER_LOC and SP_MARKER_LOC_END
            if (this->_marker[i]) {
                sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx);
            }
        }
    }

	if (add_comments) {
		gchar * comment = g_strdup_printf("end '%s'",
										  this->defaultLabel());
		sp_print_comment(ctx, comment);
		g_free(comment);
	}
}
Пример #17
0
void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
    Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    {
        /* Width */
        gchar const* labels[] = {_("(pinch tweak)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad tweak)")};
        gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "TweakWidthAction",
                                                              _("Width"), _("Width:"), _("The width of the tweak area (relative to the visible canvas area)"),
                                                              "/tools/tweak/width", 15,
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-tweak",
                                                              1, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_tweak_width_value_changed,  0.01, 0, 100 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    }


    {
        /* Force */
        gchar const* labels[] = {_("(minimum force)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum force)")};
        gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "TweakForceAction",
                                                              _("Force"), _("Force:"), _("The force of the tweak action"),
                                                              "/tools/tweak/force", 20,
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-force",
                                                              1, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_tweak_force_value_changed,  0.01, 0, 100 );
        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    }

    /* Mode */
    {
        GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );

        GtkTreeIter iter;
        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Move mode"),
                            1, _("Move objects in any direction"),
                            2, INKSCAPE_ICON("object-tweak-push"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Move in/out mode"),
                            1, _("Move objects towards cursor; with Shift from cursor"),
                            2, INKSCAPE_ICON("object-tweak-attract"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Move jitter mode"),
                            1, _("Move objects in random directions"),
                            2, INKSCAPE_ICON("object-tweak-randomize"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Scale mode"),
                            1, _("Shrink objects, with Shift enlarge"),
                            2, INKSCAPE_ICON("object-tweak-shrink"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Rotate mode"),
                            1, _("Rotate objects, with Shift counterclockwise"),
                            2, INKSCAPE_ICON("object-tweak-rotate"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Duplicate/delete mode"),
                            1, _("Duplicate objects, with Shift delete"),
                            2, INKSCAPE_ICON("object-tweak-duplicate"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Push mode"),
                            1, _("Push parts of paths in any direction"),
                            2, INKSCAPE_ICON("path-tweak-push"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Shrink/grow mode"),
                            1, _("Shrink (inset) parts of paths; with Shift grow (outset)"),
                            2, INKSCAPE_ICON("path-tweak-shrink"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Attract/repel mode"),
                            1, _("Attract parts of paths towards cursor; with Shift from cursor"),
                            2, INKSCAPE_ICON("path-tweak-attract"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Roughen mode"),
                            1, _("Roughen parts of paths"),
                            2, INKSCAPE_ICON("path-tweak-roughen"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Color paint mode"),
                            1, _("Paint the tool's color upon selected objects"),
                            2, INKSCAPE_ICON("object-tweak-paint"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Color jitter mode"),
                            1, _("Jitter the colors of selected objects"),
                            2, INKSCAPE_ICON("object-tweak-jitter-color"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Blur mode"),
                            1, _("Blur selected objects more; with Shift, blur less"),
                            2, INKSCAPE_ICON("object-tweak-blur"),
                            -1 );


        EgeSelectOneAction* act = ege_select_one_action_new( "TweakModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) );
        g_object_set( act, "short_label", _("Mode:"), NULL );
        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
        g_object_set_data( holder, "mode_action", act );

        ege_select_one_action_set_appearance( act, "full" );
        ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
        g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
        ege_select_one_action_set_icon_column( act, 2 );
        ege_select_one_action_set_icon_size( act, secondarySize );
        ege_select_one_action_set_tooltip_column( act, 1  );

        gint mode = prefs->getInt("/tools/tweak/mode", 0);
        ege_select_one_action_set_active( act, mode );
        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_tweak_mode_changed), holder );

        g_object_set_data( G_OBJECT(holder), "tweak_tool_mode", act);
    }

    guint mode = prefs->getInt("/tools/tweak/mode", 0);

    {
        EgeOutputAction* act = ege_output_action_new( "TweakChannelsLabel", _("Channels:"), "", 0 );
        ege_output_action_set_use_markup( act, TRUE );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) {
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
        }
        g_object_set_data( holder, "tweak_channels_label", act);
    }

    {
        InkToggleAction* act = ink_toggle_action_new( "TweakDoH",
                                                      _("Hue"),
                                                      _("In color mode, act on objects' hue"),
                                                      NULL,
                                                      Inkscape::ICON_SIZE_DECORATION );
        //TRANSLATORS:  "H" here stands for hue
        g_object_set( act, "short_label", _("H"), NULL );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doh", true) );
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) {
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
        }
        g_object_set_data( holder, "tweak_doh", act);
    }
    {
        InkToggleAction* act = ink_toggle_action_new( "TweakDoS",
                                                      _("Saturation"),
                                                      _("In color mode, act on objects' saturation"),
                                                      NULL,
                                                      Inkscape::ICON_SIZE_DECORATION );
        //TRANSLATORS: "S" here stands for Saturation
        g_object_set( act, "short_label", _("S"), NULL );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dos", true) );
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) {
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
        }
        g_object_set_data( holder, "tweak_dos", act );
    }
    {
        InkToggleAction* act = ink_toggle_action_new( "TweakDoL",
                                                      _("Lightness"),
                                                      _("In color mode, act on objects' lightness"),
                                                      NULL,
                                                      Inkscape::ICON_SIZE_DECORATION );
        //TRANSLATORS: "L" here stands for Lightness
        g_object_set( act, "short_label", _("L"), NULL );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dol", true) );
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) {
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
        }
        g_object_set_data( holder, "tweak_dol", act );
    }
    {
        InkToggleAction* act = ink_toggle_action_new( "TweakDoO",
                                                      _("Opacity"),
                                                      _("In color mode, act on objects' opacity"),
                                                      NULL,
                                                      Inkscape::ICON_SIZE_DECORATION );
        //TRANSLATORS: "O" here stands for Opacity
        g_object_set( act, "short_label", _("O"), NULL );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doo", true) );
        if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) {
            gtk_action_set_sensitive (GTK_ACTION(act), FALSE);
        }
        g_object_set_data( holder, "tweak_doo", act );
    }

    {   /* Fidelity */
        gchar const* labels[] = {_("(rough, simplified)"), 0, 0, _("(default)"), 0, 0, _("(fine, but many nodes)")};
        gdouble values[] = {10, 25, 35, 50, 60, 80, 100};
        EgeAdjustmentAction *eact = create_adjustment_action( "TweakFidelityAction",
                                                              _("Fidelity"), _("Fidelity:"),
                                                              _("Low fidelity simplifies paths; high fidelity preserves path features but may generate a lot of new nodes"),
                                                              "/tools/tweak/fidelity", 50,
                                                              GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-fidelity",
                                                              1, 100, 1.0, 10.0,
                                                              labels, values, G_N_ELEMENTS(labels),
                                                              sp_tweak_fidelity_value_changed,  0.01, 0, 100 );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
        if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER) {
            gtk_action_set_sensitive (GTK_ACTION(eact), FALSE);
        }
        g_object_set_data( holder, "tweak_fidelity", eact );
    }


    /* Use Pressure button */
    {
        InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction",
                                                      _("Pressure"),
                                                      _("Use the pressure of the input device to alter the force of tweak action"),
                                                      INKSCAPE_ICON("draw-use-pressure"),
                                                      Inkscape::ICON_SIZE_DECORATION );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_tweak_pressure_state_changed), NULL);
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/usepressure", true) );
    }

}
Пример #18
0
void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    EgeAdjustmentAction* eact = 0;
    Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);


    {
        EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("<b>New:</b>"), "", 0 );
        ege_output_action_set_use_markup( act, TRUE );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_object_set_data( holder, "mode_action", act );
    }

    /* Start */
    {
        eact = create_adjustment_action( "ArcStartAction",
                                         _("Start"), _("Start:"),
                                         _("The angle (in degrees) from the horizontal to the arc's start point"),
                                         "/tools/shapes/arc/start", 0.0,
                                         GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc",
                                         -360.0, 360.0, 1.0, 10.0,
                                         0, 0, 0,
                                         sp_arctb_start_value_changed);
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
    }

    /* End */
    {
        eact = create_adjustment_action( "ArcEndAction",
                                         _("End"), _("End:"),
                                         _("The angle (in degrees) from the horizontal to the arc's end point"),
                                         "/tools/shapes/arc/end", 0.0,
                                         GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
                                         -360.0, 360.0, 1.0, 10.0,
                                         0, 0, 0,
                                         sp_arctb_end_value_changed);
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
    }

    /* Segments / Pie checkbox */
    {
        GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );

        GtkTreeIter iter;
        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Closed arc"),
                            1, _("Switch to segment (closed shape with two radii)"),
                            2, INKSCAPE_ICON("draw-ellipse-segment"),
                            -1 );

        gtk_list_store_append( model, &iter );
        gtk_list_store_set( model, &iter,
                            0, _("Open Arc"),
                            1, _("Switch to arc (unclosed shape)"),
                            2, INKSCAPE_ICON("draw-ellipse-arc"),
                            -1 );

        EgeSelectOneAction* act = ege_select_one_action_new( "ArcOpenAction", (""), (""), NULL, GTK_TREE_MODEL(model) );
        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
        g_object_set_data( holder, "open_action", act );

        ege_select_one_action_set_appearance( act, "full" );
        ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
        g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
        ege_select_one_action_set_icon_column( act, 2 );
        ege_select_one_action_set_icon_size( act, secondarySize );
        ege_select_one_action_set_tooltip_column( act, 1  );

        bool isClosed = !prefs->getBool("/tools/shapes/arc/open", false);
        ege_select_one_action_set_active( act, isClosed ? 0 : 1 );
        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_arctb_open_state_changed), holder );
    }

    /* Make Whole */
    {
        InkAction* inky = ink_action_new( "ArcResetAction",
                                          _("Make whole"),
                                          _("Make the shape a whole ellipse, not arc or segment"),
                                          INKSCAPE_ICON("draw-ellipse-whole"),
                                          secondarySize );
        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_arctb_defaults), holder );
        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
        gtk_action_set_sensitive( GTK_ACTION(inky), TRUE );
        g_object_set_data( holder, "make_whole", inky );
    }

    g_object_set_data( G_OBJECT(holder), "single", GINT_TO_POINTER(TRUE) );
    // sensitivize make whole and open checkbox
    {
        GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data( holder, "start" ) );
        GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data( holder, "end" ) );
        sp_arctb_sensitivize( holder, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) );
    }

    desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(arc_toolbox_check_ec), holder));
    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
}
Пример #19
0
static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ )
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    prefs->setBool("/tools/tweak/usepressure", gtk_toggle_action_get_active(act));
}
Пример #20
0
static gint
pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mevent)
{
    if ((mevent.state & GDK_CONTROL_MASK) && (mevent.state & GDK_BUTTON1_MASK)) {
        // mouse was accidentally moved during Ctrl+click;
        // ignore the motion and create a single point
        pc->is_drawing = false;
        return TRUE;
    }
    gint ret = FALSE;
    SPDesktop *const dt = pc->desktop;

    SPEventContext *event_context = SP_EVENT_CONTEXT(pc);
    if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
        // allow scrolling
        return FALSE;
    }

    if ( ( mevent.state & GDK_BUTTON1_MASK ) && !pc->grab && pc->is_drawing) {
        /* Grab mouse, so release will not pass unnoticed */
        pc->grab = SP_CANVAS_ITEM(dt->acetate);
        sp_canvas_item_grab(pc->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK   |
                                        GDK_BUTTON_RELEASE_MASK |
                                        GDK_POINTER_MOTION_MASK  ),
                            NULL, mevent.time);
    }

    /* Find desktop coordinates */
    Geom::Point p = dt->w2d(Geom::Point(mevent.x, mevent.y));

    /* Test whether we hit any anchor. */
    SPDrawAnchor *anchor = spdc_test_inside(pc, Geom::Point(mevent.x, mevent.y));

    if (pencil_within_tolerance) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
        if ( Geom::LInfty( Geom::Point(mevent.x,mevent.y) - pencil_drag_origin_w ) < tolerance ) {
            return FALSE;   // Do not drag if we're within tolerance from origin.
        }
    }

    // Once the user has moved farther than tolerance from the original location
    // (indicating they intend to move the object, not click), then always process the
    // motion notify coordinates as given (no snapping back to origin)
    pencil_within_tolerance = false;

    switch (pc->state) {
        case SP_PENCIL_CONTEXT_ADDLINE:
            /* Set red endpoint */
            if (anchor) {
                p = anchor->dp;
            } else {
                Geom::Point ptnr(p);
                spdc_endpoint_snap(pc, ptnr, mevent.state);
                p = ptnr;
            }
            spdc_set_endpoint(pc, p);
            ret = TRUE;
            break;
        default:
            /* We may be idle or already freehand */
            if ( mevent.state & GDK_BUTTON1_MASK && pc->is_drawing ) {
                pc->state = SP_PENCIL_CONTEXT_FREEHAND;
                if ( !pc->sa && !pc->green_anchor ) {
                    /* Create green anchor */
                    pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, pc->p[0]);
                }
                /** \todo
                 * fixme: I am not sure whether we want to snap to anchors
                 * in middle of freehand (Lauris)
                 */
                SnapManager &m = dt->namedview->snap_manager;
                
                if (anchor) {
                    p = anchor->dp;
                } else if ((mevent.state & GDK_SHIFT_MASK) == 0) {
                    m.setup(dt);
                    Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
                    if (s.getSnapped()) {
                    	s.getPoint(p);
                    	pc->prev_snap_was_succesful = true;
                    } else {
                    	pc->prev_snap_was_succesful = false;
                    }
                }
                if ( pc->npoints != 0) { // buttonpress may have happened before we entered draw context!
                	if (!(pc->prev_snap_was_succesful && m.snapprefs.getSnapPostponedGlobally())) {
	                    // When snapping is enabled but temporarily on hold because the mouse is moving 
                        // fast, then we don't want to add nodes off-grid
                        spdc_add_freehand_point(pc, p, mevent.state);
	                    ret = TRUE;
                	}
                }

                if (anchor && !pc->anchor_statusbar) {
                    pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Release</b> here to close and finish the path."));
                    pc->anchor_statusbar = true;
                } else if (!anchor && pc->anchor_statusbar) {
                    pc->_message_context->clear();
                    pc->anchor_statusbar = false;
                } else if (!anchor) {
                    pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Drawing a freehand path"));
                }

            } else {
                if (anchor && !pc->anchor_statusbar) {
                    pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to continue the path from this point."));
                    pc->anchor_statusbar = true;
                } else if (!anchor && pc->anchor_statusbar) {
                    pc->_message_context->clear();
                    pc->anchor_statusbar = false;
                }
            }
            break;
    }
    return ret;
}
Пример #21
0
static void toggle_dropper_set_alpha( GtkToggleAction* act, gpointer tbl )
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    prefs->setBool( "/tools/dropper/setalpha", gtk_toggle_action_get_active( act ) );
    spinbutton_defocus(GTK_WIDGET(tbl));
}
Пример #22
0
/* interpolates the sketched curve and tweaks the current sketch interpolation*/
static void
sketch_interpolate(SPPencilContext *pc)
{
    g_assert( pc->ps.size() > 1 );

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
    double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() * 
                                               tol) * exp(0.2*tol - 2);

    bool average_all_sketches = prefs->getBool("/tools/freehand/pencil/average_all_sketches", true);

    g_assert(is_zero(pc->req_tangent)
             || is_unit_vector(pc->req_tangent));
    Geom::Point const tHatEnd(0, 0);

    guint n_points  = pc->ps.size();
    pc->red_curve->reset();
    pc->red_curve_is_valid = false;

    Geom::Point * b = g_new(Geom::Point, 4*n_points);
    Geom::Point * points = g_new(Geom::Point, 4*n_points);
    for (unsigned i = 0; i < pc->ps.size(); i++) { 
        points[i] = pc->ps[i];
    }

    // worst case gives us a segment per point
    int max_segs = 4*n_points;

    int const n_segs = Geom::bezier_fit_cubic_r(b, points, n_points,
                                             tolerance_sq, max_segs);

    if ( n_segs > 0)
    {
        Geom::Path fit(b[0]);
        for (int c = 0; c < n_segs; c++) { 
            fit.appendNew<Geom::CubicBezier>(b[4*c+1], b[4*c+2], b[4*c+3]);
        }
        Geom::Piecewise<Geom::D2<Geom::SBasis> > fit_pwd2 = fit.toPwSb();

        double t =0.;
        if ( pc->sketch_n > 0 ) {
            if (average_all_sketches) {
                // Average = (sum of all) / n
                //         = (sum of all + new one) / n+1
                //         = ((old average)*n + new one) / n+1
                t = pc->sketch_n / (pc->sketch_n + 1.);
            } else {
                t = 0.5;
            }
            pc->sketch_interpolation = Geom::lerp(t, fit_pwd2, pc->sketch_interpolation);
        } else {
            pc->sketch_interpolation = fit_pwd2;
        }
        pc->sketch_n++;

        pc->green_curve->reset();
        pc->green_curve->set_pathvector(Geom::path_from_piecewise(pc->sketch_interpolation, 0.01));
        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve);

        /* Fit and draw and copy last point */
        g_assert(!pc->green_curve->is_empty());

        /* Set up direction of next curve. */
        {
            Geom::CubicBezier const * last_seg = dynamic_cast<Geom::CubicBezier const *>(pc->green_curve->last_segment());
            g_assert( last_seg );      // Relevance: validity of (*last_seg)[2]
            pc->p[0] = last_seg->finalPoint();
            pc->npoints = 1;
            Geom::Point const req_vec( pc->p[0] - (*last_seg)[2] );
            pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
                                ? Geom::Point(0, 0)
                                : Geom::unit_vector(req_vec) );
        }
    }
    g_free(b);
    g_free(points);
    pc->ps.clear();
}
Пример #23
0
static gint sp_zoom_context_root_handler(SPEventContext *event_context, GdkEvent *event)
{
    SPDesktop *desktop = event_context->desktop;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
	
	SPZoomContext *zc = SP_ZOOM_CONTEXT(event_context);
    tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
    double const zoom_inc = prefs->getDoubleLimited("/options/zoomincrement/value", M_SQRT2, 1.01, 10);

    gint ret = FALSE;

    switch (event->type) {
        case GDK_BUTTON_PRESS:
        {
            Geom::Point const button_w(event->button.x, event->button.y);
            Geom::Point const button_dt(desktop->w2d(button_w));
            if (event->button.button == 1 && !event_context->space_panning) {
                // save drag origin
                xp = (gint) event->button.x;
                yp = (gint) event->button.y;
                within_tolerance = true;

                Inkscape::Rubberband::get(desktop)->start(desktop, button_dt);

                escaped = false;

                ret = TRUE;
            } else if (event->button.button == 3) {
                double const zoom_rel( (event->button.state & GDK_SHIFT_MASK)
                                       ? zoom_inc
                                       : 1 / zoom_inc );
                desktop->zoom_relative_keep_point(button_dt, zoom_rel);
                ret = TRUE;
            }
			
			sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
								GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
								NULL, event->button.time);
			zc->grabbed = SP_CANVAS_ITEM(desktop->acetate);
				
            break;
        }

	case GDK_MOTION_NOTIFY:
            if (event->motion.state & GDK_BUTTON1_MASK && !event_context->space_panning) {
                ret = TRUE;

                if ( within_tolerance
                     && ( abs( (gint) event->motion.x - xp ) < tolerance )
                     && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) {
                    break; // do not drag if we're within tolerance from origin
                }
                // Once the user has moved farther than tolerance from the original location
                // (indicating they intend to move the object, not click), then always process the
                // motion notify coordinates as given (no snapping back to origin)
                within_tolerance = false;

                Geom::Point const motion_w(event->motion.x, event->motion.y);
                Geom::Point const motion_dt(desktop->w2d(motion_w));
                Inkscape::Rubberband::get(desktop)->move(motion_dt);
                gobble_motion_events(GDK_BUTTON1_MASK);
            }
            break;

      	case GDK_BUTTON_RELEASE:
        {
            Geom::Point const button_w(event->button.x, event->button.y);
            Geom::Point const button_dt(desktop->w2d(button_w));
            if ( event->button.button == 1  && !event_context->space_panning) {
                Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle();
                if (b && !within_tolerance) {
                    desktop->set_display_area(*b, 10);
                } else if (!escaped) {
                    double const zoom_rel( (event->button.state & GDK_SHIFT_MASK)
                                           ? 1 / zoom_inc
                                           : zoom_inc );
                    desktop->zoom_relative_keep_point(button_dt, zoom_rel);
                }
                ret = TRUE;
            } 
            Inkscape::Rubberband::get(desktop)->stop();
			
			if (zc->grabbed) {
				sp_canvas_item_ungrab(zc->grabbed, event->button.time);
				zc->grabbed = NULL;
			}
			
            xp = yp = 0;
            escaped = false;
            break;
        }
        case GDK_KEY_PRESS:
            switch (get_group0_keyval (&event->key)) {
                case GDK_Escape:
                    Inkscape::Rubberband::get(desktop)->stop();
                    xp = yp = 0;
                    escaped = true;
                    ret = TRUE;
                    break;
                case GDK_Up:
                case GDK_Down:
                case GDK_KP_Up:
                case GDK_KP_Down:
                    // prevent the zoom field from activation
                    if (!MOD__CTRL_ONLY)
                        ret = TRUE;
                    break;
                case GDK_Shift_L:
                case GDK_Shift_R:
                    event_context->cursor_shape = SP_ZOOM_OUT_CURSOR;
                    sp_event_context_update_cursor(event_context);
                    break;
                default:
			break;
		}
		break;
	case GDK_KEY_RELEASE:
            switch (get_group0_keyval (&event->key)) {
		case GDK_Shift_L:
		case GDK_Shift_R:
                    event_context->cursor_shape = SP_ZOOM_CURSOR;
                    sp_event_context_update_cursor(event_context);
                    break;
		default:
                    break;
		}
            break;
	default:
            break;
    }

    if (!ret) {
        if (((SPEventContextClass *) parent_class)->root_handler) {
            ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event);
        }
    }

    return ret;
}
Пример #24
0
GtkWidget *
sp_gradient_toolbox_new(SPDesktop *desktop)
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    GtkWidget *tbl = gtk_toolbar_new();

    gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
    gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);

    GtkTooltips *tt = gtk_tooltips_new();

    sp_toolbox_add_label(tbl, _("<b>New:</b>"));

    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);

    {
    GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
    GtkWidget *cbox = gtk_hbox_new (FALSE, 0);

    {
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                              SP_BUTTON_TYPE_TOGGLE,
                                              NULL,
                                              "fill_gradient",
                                              _("Create linear gradient"),
                                              tt);
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
    g_object_set_data(G_OBJECT(tbl), "linear", button);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
              prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
    }

    {
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                              SP_BUTTON_TYPE_TOGGLE,
                                              NULL,
                                              "fill_radial",
                                              _("Create radial (elliptic or circular) gradient"),
                                              tt);
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
    g_object_set_data(G_OBJECT(tbl), "radial", button);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
              prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
    }

    gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
    gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
    }

    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);

    sp_toolbox_add_label(tbl, _("on"), false);

    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);

    {
        GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
    GtkWidget *cbox = gtk_hbox_new (FALSE, 0);

    {
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                              SP_BUTTON_TYPE_TOGGLE,
                                              NULL,
                                              "controls_fill",
                                              _("Create gradient in the fill"),
                                              tt);
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
    g_object_set_data(G_OBJECT(tbl), "fill", button);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
                                  prefs->getBool("/tools/gradient/newfillorstroke", true));
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
    }

    {
    GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                              SP_BUTTON_TYPE_TOGGLE,
                                              NULL,
                                              "controls_stroke",
                                              _("Create gradient in the stroke"),
                                              tt);
    g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
    g_object_set_data(G_OBJECT(tbl), "stroke", button);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
                                  !prefs->getBool("/tools/gradient/newfillorstroke", true));
    gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
    }

    gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
    gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
    }


    sp_toolbox_add_label(tbl, _("<b>Change:</b>"));

    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);

    {
        GtkWidget *vectors = gr_change_widget (desktop);
        gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), vectors, "", "" );
    }

    gtk_widget_show_all(tbl);
    sp_set_font_size_smaller (tbl);

    return tbl;
}
Пример #25
0
void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed)
{
    // Concat RBG
    SPCurve *c = dc->green_curve;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    // Green
    dc->green_curve = new SPCurve();
    while (dc->green_bpaths) {
        sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data));
        dc->green_bpaths = g_slist_remove(dc->green_bpaths, dc->green_bpaths->data);
    }

    // Blue
    c->append_continuous(dc->blue_curve, 0.0625);
    dc->blue_curve->reset();
    sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue_bpath), NULL);

    // Red
    if (dc->red_curve_is_valid) {
        c->append_continuous(dc->red_curve, 0.0625);
    }
    dc->red_curve->reset();
    sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL);

    if (c->is_empty()) {
        c->unref();
        return;
    }

    // Step A - test, whether we ended on green anchor
    if ( forceclosed || ( dc->green_anchor && dc->green_anchor->active ) ) {
        // We hit green anchor, closing Green-Blue-Red
        dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed."));
        c->closepath_current();
        // Closed path, just flush
        spdc_flush_white(dc, c);
        c->unref();
        return;
    }

    // Step B - both start and end anchored to same curve
    if ( dc->sa && dc->ea
         && ( dc->sa->curve == dc->ea->curve )
         && ( ( dc->sa != dc->ea )
              || dc->sa->curve->is_closed() ) )
    {
        // We hit bot start and end of single curve, closing paths
        dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path."));
        if (dc->sa->start && !(dc->sa->curve->is_closed()) ) {
            c = reverse_then_unref(c);
        }
        if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || 
            prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
            dc->overwrite_curve->append_continuous(c, 0.0625);
            c->unref();
            dc->overwrite_curve->closepath_current();
            if(dc->sa){
                dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve);
                dc->white_curves = g_slist_append(dc->white_curves, dc->overwrite_curve);
            }
        }else{
            dc->sa->curve->append_continuous(c, 0.0625);
            c->unref();
            dc->sa->curve->closepath_current();
        }
        spdc_flush_white(dc, NULL);
        return;
    }

    // Step C - test start
    if (dc->sa) {
        SPCurve *s = dc->sa->curve;
        dc->white_curves = g_slist_remove(dc->white_curves, s);
        if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || 
            prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
                s = dc->overwrite_curve;
        }
        if (dc->sa->start) {
            s = reverse_then_unref(s);
        }
        s->append_continuous(c, 0.0625);
        c->unref();
        c = s;
    } else /* Step D - test end */ if (dc->ea) {
        SPCurve *e = dc->ea->curve;
        dc->white_curves = g_slist_remove(dc->white_curves, e);
        if (!dc->ea->start) {
            e = reverse_then_unref(e);
        }
        if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || 
            prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
                e = reverse_then_unref(e);
                Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*e->last_segment());
                SPCurve *lastSeg = new SPCurve();
                if(cubic){
                    lastSeg->moveto((*cubic)[0]);
                    lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
                    if( e->get_segment_count() == 1){
                        e = lastSeg;
                    }else{
                        //we eliminate the last segment
                        e->backspace();
                        //and we add it again with the recreation
                        e->append_continuous(lastSeg, 0.0625);
                    }
                }
                e = reverse_then_unref(e);
        }
        c->append_continuous(e, 0.0625);
        e->unref();
    }


    spdc_flush_white(dc, c);

    c->unref();
}
Пример #26
0
/**
* Takes a list of inkscape items, extracts the graph defined by
* connectors between them, and uses graph layout techniques to find
* a nice layout
*/
void graphlayout(std::vector<SPItem*> const &items) {
    if(items.empty()) {
        return;
    }

    list<SPItem *> selected;
    filterConnectors(items,selected);
    if (selected.empty()) return;

    const unsigned n=selected.size();
    //Check 2 or more selected objects
    if (n < 2) return;

    // add the connector spacing to the size of node bounding boxes
    // so that connectors can always be routed between shapes
    SPDesktop* desktop = SP_ACTIVE_DESKTOP;
    double spacing = 0;
    if(desktop) spacing = desktop->namedview->connector_spacing+0.1;

    map<string,unsigned> nodelookup;
    vector<Rectangle*> rs;
    vector<Edge> es;
    for (list<SPItem *>::iterator i(selected.begin());
         i != selected.end();
         ++i)
    {
        SPItem *u=*i;
        Geom::OptRect const item_box = u->desktopVisualBounds();
        if(item_box) {
            Geom::Point ll(item_box->min());
            Geom::Point ur(item_box->max());
            nodelookup[u->getId()]=rs.size();
            rs.push_back(new Rectangle(ll[0]-spacing,ur[0]+spacing,
                        ll[1]-spacing,ur[1]+spacing));
        } else {
            // I'm not actually sure if it's possible for something with a
            // NULL item-box to be attached to a connector in which case we
            // should never get to here... but if such a null box can occur it's
            // probably pretty safe to simply ignore
            //fprintf(stderr,"NULL item_box found in graphlayout, ignoring!\n");
        }
    }

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    SimpleConstraints scx,scy;
    double ideal_connector_length = prefs->getDouble("/tools/connector/length", 100.0);
    double directed_edge_height_modifier = 1.0;

    bool directed =       prefs->getBool("/tools/connector/directedlayout");
    bool avoid_overlaps = prefs->getBool("/tools/connector/avoidoverlaplayout");

    for (list<SPItem *>::iterator i(selected.begin());
         i != selected.end();
         ++i)
    {
        SPItem *iu=*i;
        map<string,unsigned>::iterator i_iter=nodelookup.find(iu->getId());
        map<string,unsigned>::iterator i_iter_end=nodelookup.end();
        if(i_iter==i_iter_end) {
            continue;
        }
        unsigned u=i_iter->second;
        std::vector<SPItem *> nlist=iu->avoidRef->getAttachedConnectors(Avoid::runningFrom);
        list<SPItem *> connectors;

        connectors.insert(connectors.end(), nlist.begin(), nlist.end());

        for (list<SPItem *>::iterator j(connectors.begin());
                j != connectors.end();
                ++j) {
            SPItem *conn=*j;
            SPItem *iv;
            SPItem *items[2];
            assert(isConnector(conn));
            SP_PATH(conn)->connEndPair.getAttachedItems(items);
            if(items[0]==iu) {
                iv=items[1];
            } else {
                iv=items[0];
            }

            if (iv == NULL) {
                // The connector is not attached to anything at the
                // other end so we should just ignore it.
                continue;
            }

            // If iv not in nodelookup we again treat the connector
            // as disconnected and continue
            map<string,unsigned>::iterator v_pair=nodelookup.find(iv->getId());
            if(v_pair!=nodelookup.end()) {
                unsigned v=v_pair->second;
                //cout << "Edge: (" << u <<","<<v<<")"<<endl;
                es.push_back(make_pair(u,v));
                if(conn->style->marker_end.set) {
                    if(directed && strcmp(conn->style->marker_end.value,"none")) {
                        scy.push_back(new SimpleConstraint(v, u,
                                    (ideal_connector_length * directed_edge_height_modifier)));
                    }
                }
            }
        }
    }
    const unsigned E = es.size();
    double eweights[E];
    fill(eweights,eweights+E,1);
    vector<Component*> cs;
    connectedComponents(rs,es,scx,scy,cs);
    for(unsigned i=0;i<cs.size();i++) {
        Component* c=cs[i];
        if(c->edges.size()<2) continue;
        CheckProgress test(0.0001,100,selected,rs,nodelookup);
        ConstrainedMajorizationLayout alg(c->rects,c->edges,eweights,ideal_connector_length,test);
        alg.setupConstraints(NULL,NULL,avoid_overlaps,
                NULL,NULL,&c->scx,&c->scy,NULL,NULL);
        alg.run();
    }
    separateComponents(cs);

    for (list<SPItem *>::iterator it(selected.begin());
         it != selected.end();
         ++it)
    {
        SPItem *u=*it;
        if(!isConnector(u)) {
            map<string,unsigned>::iterator i=nodelookup.find(u->getId());
            if(i!=nodelookup.end()) {
                Rectangle* r=rs[i->second];
                Geom::OptRect item_box = u->desktopVisualBounds();
                if (item_box) {
                    Geom::Point const curr(item_box->midpoint());
                    Geom::Point const dest(r->getCentreX(),r->getCentreY());
                    sp_item_move_rel(u, Geom::Translate(dest - curr));
                }
            }
        }
    }
    for(unsigned i=0;i<scx.size();i++) {
        delete scx[i];
    }
    for(unsigned i=0;i<scy.size();i++) {
        delete scy[i];
    }
    for(unsigned i=0;i<rs.size();i++) {
        delete rs[i];
    }
}
Пример #27
0
static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject * /*tbl*/ )
{
    int mode = ege_select_one_action_get_active( act );
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    prefs->setInt("/tools/spray/mode", mode);
}
Пример #28
0
void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    EgeAdjustmentAction* eact = 0;
    SPDocument *document = desktop->getDocument();
    Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl();

    EgeAdjustmentAction* box3d_angle_x = 0;
    EgeAdjustmentAction* box3d_angle_y = 0;
    EgeAdjustmentAction* box3d_angle_z = 0;

    /* Angle X */
    {
        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
        eact = create_adjustment_action( "3DBoxAngleXAction",
                                         _("Angle in X direction"), _("Angle X:"),
                                         // Translators: PL is short for 'perspective line'
                                         _("Angle of PLs in X direction"),
                                         "/tools/shapes/3dbox/box3d_angle_x", 30,
                                         GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-box3d",
                                         -360.0, 360.0, 1.0, 10.0,
                                         labels, values, G_N_ELEMENTS(labels),
                                         box3d_angle_x_value_changed );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        g_object_set_data( holder, "box3d_angle_x_action", eact );
        box3d_angle_x = eact;
    }

    if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::X)) {
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    } else {
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
    }


    /* VP X state */
    {
        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction",
                                                      // Translators: VP is short for 'vanishing point'
                                                      _("State of VP in X direction"),
                                                      _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"),
                                                      INKSCAPE_ICON("perspective-parallel"),
                                                      Inkscape::ICON_SIZE_DECORATION );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_object_set_data( holder, "box3d_vp_x_state_action", act );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x );
        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) );
    }

    /* Angle Y */
    {
        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
        eact = create_adjustment_action( "3DBoxAngleYAction",
                                         _("Angle in Y direction"), _("Angle Y:"),
                                         // Translators: PL is short for 'perspective line'
                                         _("Angle of PLs in Y direction"),
                                         "/tools/shapes/3dbox/box3d_angle_y", 30,
                                         GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
                                         -360.0, 360.0, 1.0, 10.0,
                                         labels, values, G_N_ELEMENTS(labels),
                                         box3d_angle_y_value_changed );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        g_object_set_data( holder, "box3d_angle_y_action", eact );
        box3d_angle_y = eact;
    }

    if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Y)) {
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    } else {
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
    }

    /* VP Y state */
    {
        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction",
                                                      // Translators: VP is short for 'vanishing point'
                                                      _("State of VP in Y direction"),
                                                      _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"),
                                                      INKSCAPE_ICON("perspective-parallel"),
                                                      Inkscape::ICON_SIZE_DECORATION );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_object_set_data( holder, "box3d_vp_y_state_action", act );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y );
        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) );
    }

    /* Angle Z */
    {
        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
        eact = create_adjustment_action( "3DBoxAngleZAction",
                                         _("Angle in Z direction"), _("Angle Z:"),
                                         // Translators: PL is short for 'perspective line'
                                         _("Angle of PLs in Z direction"),
                                         "/tools/shapes/3dbox/box3d_angle_z", 30,
                                         GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
                                         -360.0, 360.0, 1.0, 10.0,
                                         labels, values, G_N_ELEMENTS(labels),
                                         box3d_angle_z_value_changed );
        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
        g_object_set_data( holder, "box3d_angle_z_action", eact );
        box3d_angle_z = eact;
    }

    if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Z)) {
        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
    } else {
        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
    }

    /* VP Z state */
    {
        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction",
                                                      // Translators: VP is short for 'vanishing point'
                                                      _("State of VP in Z direction"),
                                                      _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"),
                                                      INKSCAPE_ICON("perspective-parallel"),
                                                      Inkscape::ICON_SIZE_DECORATION );
        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
        g_object_set_data( holder, "box3d_vp_z_state_action", act );
        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z );
        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) );
        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) );
    }

    desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_check_ec), holder));
    g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder);
}
void ColorNotebook::init()
{
    guint row = 0;
    guint i = 0;
    guint j = 0;
    GType *selector_types = 0;
    guint selector_type_count = 0;

    /* tempory hardcoding to get types loaded */
    SP_TYPE_COLOR_SCALES;
    SP_TYPE_COLOR_WHEEL_SELECTOR;
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
    SP_TYPE_COLOR_ICC_SELECTOR;
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)

    /* REJON: Comment out the next line to not use the normal GTK Color
           wheel. */

//        SP_TYPE_COLOR_GTKSELECTOR;

    _updating = FALSE;
    _updatingrgba = FALSE;
    _btn = 0;
    _popup = 0;
    _trackerList = g_ptr_array_new ();

    _book = gtk_notebook_new ();
    gtk_widget_show (_book);

    // Dont show the notebook tabs, use radiobuttons instead
    gtk_notebook_set_show_border (GTK_NOTEBOOK (_book), false);
    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (_book), false);

    selector_types = g_type_children (SP_TYPE_COLOR_SELECTOR, &selector_type_count);

    for ( i = 0; i < selector_type_count; i++ )
    {
        if (!g_type_is_a (selector_types[i], SP_TYPE_COLOR_NOTEBOOK))
        {
            guint howmany = 1;
            gpointer klass = g_type_class_ref (selector_types[i]);
            if ( klass && SP_IS_COLOR_SELECTOR_CLASS(klass) )
            {
                SPColorSelectorClass *ck = SP_COLOR_SELECTOR_CLASS (klass);
                howmany = MAX (1, ck->submode_count);
                for ( j = 0; j < howmany; j++ )
                {
                    SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (malloc(sizeof(SPColorNotebookTracker)));
                    if ( entry )
                    {
                        memset( entry, 0, sizeof(SPColorNotebookTracker) );
                        entry->name = ck->name[j];
                        entry->type = selector_types[i];
                        entry->submode = j;
                        entry->enabledFull = TRUE;
                        entry->enabledBrief = TRUE;
                        entry->backPointer = SP_COLOR_NOTEBOOK(_csel);

                        g_ptr_array_add (_trackerList, entry);
                    }
                }
            }
        }
    }

#if GTK_CHECK_VERSION(3,0,0)
    _buttonbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
    gtk_box_set_homogeneous(GTK_BOX(_buttonbox), TRUE);
#else
    _buttonbox = gtk_hbox_new (TRUE, 2);
#endif

    gtk_widget_show (_buttonbox);
    _buttons = new GtkWidget *[_trackerList->len];

    for ( i = 0; i < _trackerList->len; i++ )
    {
        SPColorNotebookTracker *entry =
            reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i));
        if ( entry )
        {
            addPage(entry->type, entry->submode);
        }
    }

#if GTK_CHECK_VERSION(3,0,0)
    GtkWidget* table = gtk_grid_new();
#else
    GtkWidget* table = gtk_table_new(2, 3, FALSE);
#endif

    gtk_widget_show (table);

    gtk_box_pack_start (GTK_BOX (_csel), table, TRUE, TRUE, 0);

    sp_set_font_size_smaller (_buttonbox);

#if GTK_CHECK_VERSION(3,0,0)
    gtk_widget_set_margin_left(_buttonbox, XPAD);
    gtk_widget_set_margin_right(_buttonbox, XPAD);
    gtk_widget_set_margin_top(_buttonbox, YPAD);
    gtk_widget_set_margin_bottom(_buttonbox, YPAD);
    gtk_widget_set_hexpand(_buttonbox, TRUE);
    gtk_widget_set_valign(_buttonbox, GTK_ALIGN_CENTER);
    gtk_grid_attach(GTK_GRID(table), _buttonbox, 0, row, 2, 1);
#else
    gtk_table_attach (GTK_TABLE (table), _buttonbox, 0, 2, row, row + 1,
                      static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL),
                      static_cast<GtkAttachOptions>(0),
                      XPAD, YPAD);
#endif

    row++;

#if GTK_CHECK_VERSION(3,0,0)
    gtk_widget_set_margin_left(_book, XPAD*2);
    gtk_widget_set_margin_right(_book, XPAD*2);
    gtk_widget_set_margin_top(_book, YPAD);
    gtk_widget_set_margin_bottom(_book, YPAD);
    gtk_widget_set_hexpand(_book, TRUE);
    gtk_widget_set_vexpand(_book, TRUE);
    gtk_grid_attach(GTK_GRID(table), _book, 0, row, 2, 1);
#else
    gtk_table_attach (GTK_TABLE (table), _book, 0, 2, row, row + 1,
                      static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL),
                      static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL),
                      XPAD*2, YPAD);
#endif

    // restore the last active page
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    _setCurrentPage(prefs->getInt("/colorselector/page", 0));

    {
        gboolean found = FALSE;

        _popup = gtk_menu_new();
        GtkMenu *menu = GTK_MENU (_popup);

        for ( i = 0; i < _trackerList->len; i++ )
        {
            SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i));
            if ( entry )
            {
                GtkWidget *item = gtk_check_menu_item_new_with_label (_(entry->name));
                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), entry->enabledFull);
                gtk_widget_show (item);
                gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);

                g_signal_connect (G_OBJECT (item), "activate",
                                  G_CALLBACK (sp_color_notebook_menuitem_response),
                                  reinterpret_cast< gpointer > (entry) );
                found = TRUE;
            }
        }

        GtkWidget *arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
        gtk_widget_show (arrow);

        _btn = gtk_button_new ();
        gtk_widget_show (_btn);
        gtk_container_add (GTK_CONTAINER (_btn), arrow);

        GtkWidget *align = gtk_alignment_new (1.0, 0.0, 0.0, 0.0);
        gtk_widget_show (align);
        gtk_container_add (GTK_CONTAINER (align), _btn);

        // uncomment to reenable the "show/hide modes" menu,
        // but first fix it so it remembers its settings in prefs and does not take that much space (entire vertical column!)
        //gtk_table_attach (GTK_TABLE (table), align, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);

        g_signal_connect_swapped(G_OBJECT(_btn), "event", G_CALLBACK (sp_color_notebook_menu_handler), G_OBJECT(_csel));
        if ( !found )
        {
            gtk_widget_set_sensitive (_btn, FALSE);
        }
    }

    row++;

#if GTK_CHECK_VERSION(3,0,0)
    GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
#else
    GtkWidget *rgbabox = gtk_hbox_new (FALSE, 0);
#endif

#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
    /* Create color management icons */
    _box_colormanaged = gtk_event_box_new ();
    GtkWidget *colormanaged = gtk_image_new_from_icon_name ("color-management-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
    gtk_container_add (GTK_CONTAINER (_box_colormanaged), colormanaged);
    gtk_widget_set_tooltip_text (_box_colormanaged, _("Color Managed"));
    gtk_widget_set_sensitive (_box_colormanaged, false);
    gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2);

    _box_outofgamut = gtk_event_box_new ();
    GtkWidget *outofgamut = gtk_image_new_from_icon_name ("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
    gtk_container_add (GTK_CONTAINER (_box_outofgamut), outofgamut);
    gtk_widget_set_tooltip_text (_box_outofgamut, _("Out of gamut!"));
    gtk_widget_set_sensitive (_box_outofgamut, false);
    gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2);

    _box_toomuchink = gtk_event_box_new ();
    GtkWidget *toomuchink = gtk_image_new_from_icon_name ("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
    gtk_container_add (GTK_CONTAINER (_box_toomuchink), toomuchink);
    gtk_widget_set_tooltip_text (_box_toomuchink, _("Too much ink!"));
    gtk_widget_set_sensitive (_box_toomuchink, false);
    gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2);
#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)


    /* Color picker */
    GtkWidget *picker = gtk_image_new_from_icon_name ("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR);
    _btn_picker = gtk_button_new ();
    gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE);
    gtk_widget_show (_btn);
    gtk_container_add (GTK_CONTAINER (_btn_picker), picker);
    gtk_widget_set_tooltip_text (_btn_picker, _("Pick colors from image"));
    gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2);
    g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_picker_clicked), _csel);

    /* Create RGBA entry and color preview */
    _rgbal = gtk_label_new_with_mnemonic (_("RGBA_:"));
    gtk_misc_set_alignment (GTK_MISC (_rgbal), 1.0, 0.5);
    gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2);

    _rgbae = gtk_entry_new ();
    sp_dialog_defocus_on_enter (_rgbae);
    gtk_entry_set_max_length (GTK_ENTRY (_rgbae), 8);
    gtk_entry_set_width_chars (GTK_ENTRY (_rgbae), 8);
    gtk_widget_set_tooltip_text (_rgbae, _("Hexadecimal RGBA value of the color"));
    gtk_box_pack_start(GTK_BOX(rgbabox), _rgbae, FALSE, FALSE, 0);
    gtk_label_set_mnemonic_widget (GTK_LABEL(_rgbal), _rgbae);

    sp_set_font_size_smaller (rgbabox);
    gtk_widget_show_all (rgbabox);

#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
    //the "too much ink" icon is initially hidden
    gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)

#if GTK_CHECK_VERSION(3,0,0)
    gtk_widget_set_margin_left(rgbabox, XPAD);
    gtk_widget_set_margin_right(rgbabox, XPAD);
    gtk_widget_set_margin_top(rgbabox, YPAD);
    gtk_widget_set_margin_bottom(rgbabox, YPAD);
    gtk_grid_attach(GTK_GRID(table), rgbabox, 0, row, 2, 1);
#else
    gtk_table_attach (GTK_TABLE (table), rgbabox, 0, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD);
#endif

#ifdef SPCS_PREVIEW
    _p = sp_color_preview_new (0xffffffff);
    gtk_widget_show (_p);
    gtk_table_attach (GTK_TABLE (table), _p, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
#endif

    _switchId = g_signal_connect(G_OBJECT (_book), "switch-page",
                                 G_CALLBACK (sp_color_notebook_switch_page), SP_COLOR_NOTEBOOK(_csel));

    _entryId = g_signal_connect (G_OBJECT (_rgbae), "changed", G_CALLBACK (ColorNotebook::_rgbaEntryChangedHook), _csel);
}
Пример #30
0
ParamComboBox::ParamComboBox(const gchar *name, const gchar *guitext, const gchar *desc,
                             const Parameter::_scope_t scope, bool gui_hidden, const gchar *gui_tip,
                             Inkscape::Extension::Extension *ext, Inkscape::XML::Node *xml)
    : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
    , _value(NULL)
    , _indent(0)
    , choices(NULL)
{
    const char *xmlval = NULL; // the value stored in XML

    if (xml != NULL) {
        // Read XML tree to add enumeration items:
        for (Inkscape::XML::Node *node = xml->firstChild(); node; node = node->next()) {
            char const * chname = node->name();
            if (!strcmp(chname, INKSCAPE_EXTENSION_NS "item") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) {
                Glib::ustring newguitext, newvalue;
                const char * contents = NULL;
                if (node->firstChild()) {
                    contents = node->firstChild()->content();
                }
                if (contents != NULL) {
                    // don't translate when 'item' but do translate when '_item'
                    // NOTE: internal extensions use build_from_mem and don't need _item but
                    //       still need to include if are to be localized
                    if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) {
                        if (node->attribute("msgctxt") != NULL) {
                            newguitext =  g_dpgettext2(NULL, node->attribute("msgctxt"), contents);
                        } else {
                            newguitext =  _(contents);
                        }
                    } else {
                        newguitext =  contents;
                    }
                } else
                    continue;

                const char * val = node->attribute("value");
                if (val != NULL) {
                    newvalue = val;
                } else {
                    newvalue = contents;
                }

                if ( (!newguitext.empty()) && (!newvalue.empty()) ) {   // logical error if this is not true here
                    choices = g_slist_append( choices, new enumentry(newvalue, newguitext) );
                }
            }
        }
    
        // Initialize _value with the default value from xml
        // for simplicity : default to the contents of the first xml-child
        if (xml->firstChild() && xml->firstChild()->firstChild()) {
            xmlval = xml->firstChild()->attribute("value");
        }

        const char *indent = xml->attribute("indent");
        if (indent != NULL) {
            _indent = atoi(indent) * 12;
        }
    }

    gchar * pref_name = this->pref_name();
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    Glib::ustring paramval = prefs ? prefs->getString(extension_pref_root + pref_name) : "";
    g_free(pref_name);

    if (!paramval.empty()) {
        _value = g_strdup(paramval.data());
    } else if (xmlval) {
        _value = g_strdup(xmlval);
    }
}