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 ) {
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 ); } }
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)); }
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; }
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(); } } }
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 ); }
/* 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); } }
/* * 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); }
/** * \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; }
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; }
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)); }
/** * 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; }
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.")); } }
/** 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; }
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)); }
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); } }
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) ); } }
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 ); }
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)); }
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; }
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)); }
/* 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(); }
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; }
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; }
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(); }
/** * 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]; } }
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); }
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); }
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); } }