Exemple #1
0
static void sp_grd_ed_del_stop(GtkWidget */*widget*/,  GtkWidget *vb)
{
    SPGradient *gradient = static_cast<SPGradient *>(g_object_get_data(G_OBJECT(vb), "gradient"));

    SPStop *stop = get_selected_stop(vb);
    if (!stop) {
        return;
    }

    if (gradient->vector.stops.size() > 2) { // 2 is the minimum

        // if we delete first or last stop, move the next/previous to the edge
        if (stop->offset == 0) {
            SPStop *next = stop->getNextStop();
            if (next) {
                next->offset = 0;
                sp_repr_set_css_double(next->getRepr(), "offset", 0);
            }
        } else if (stop->offset == 1) {
            SPStop *prev = stop->getPrevStop();
            if (prev) {
                prev->offset = 1;
                sp_repr_set_css_double(prev->getRepr(), "offset", 1);
            }
        }

        gradient->getRepr()->removeChild(stop->getRepr());
        sp_gradient_vector_widget_load_gradient(vb, gradient);
        update_stop_list(GTK_WIDGET(vb), gradient, NULL);
        DocumentUndo::done(gradient->document, SP_VERB_CONTEXT_GRADIENT,
                           _("Delete gradient stop"));
    }

}
Exemple #2
0
static void sp_grd_ed_add_stop(GtkWidget */*widget*/,  GtkWidget *vb)
{
    SPGradient *gradient = static_cast<SPGradient *>(g_object_get_data(G_OBJECT(vb), "gradient"));
    verify_grad(gradient);

    SPStop *stop = get_selected_stop(vb);
    if (!stop) {
        return;
    }

    Inkscape::XML::Node *new_stop_repr = NULL;

    SPStop *next = stop->getNextStop();

    if (next == NULL) {
        SPStop *prev = stop->getPrevStop();
        if (prev != NULL) {
            next = stop;
            stop = prev;
        }
    }

    if (next != NULL) {
        new_stop_repr = stop->getRepr()->duplicate(gradient->getRepr()->document());
        gradient->getRepr()->addChild(new_stop_repr, stop->getRepr());
    } else {
        next = stop;
        new_stop_repr = stop->getPrevStop()->getRepr()->duplicate(gradient->getRepr()->document());
        gradient->getRepr()->addChild(new_stop_repr, stop->getPrevStop()->getRepr());
    }

    SPStop *newstop = reinterpret_cast<SPStop *>(gradient->document->getObjectByRepr(new_stop_repr));

    newstop->offset = (stop->offset + next->offset) * 0.5 ;

    guint32 const c1 = stop->get_rgba32();
    guint32 const c2 = next->get_rgba32();
    guint32 cnew = sp_average_color(c1, c2);

    Inkscape::CSSOStringStream os;
    gchar c[64];
    sp_svg_write_color(c, sizeof(c), cnew);
    gdouble opacity = static_cast<gdouble>(SP_RGBA32_A_F(cnew));
    os << "stop-color:" << c << ";stop-opacity:" << opacity <<";";
    newstop->getRepr()->setAttribute("style", os.str().c_str());
    sp_repr_set_css_double( newstop->getRepr(), "offset", (double)newstop->offset);

    sp_gradient_vector_widget_load_gradient(vb, gradient);
    Inkscape::GC::release(new_stop_repr);
    update_stop_list(GTK_WIDGET(vb), gradient, newstop);
    GtkWidget *offspin = GTK_WIDGET(g_object_get_data(G_OBJECT(vb), "offspn"));
    GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(vb), "offslide"));
    gtk_widget_set_sensitive(offslide, TRUE);
    gtk_widget_set_sensitive(GTK_WIDGET(offspin), TRUE);
    DocumentUndo::done(gradient->document, SP_VERB_CONTEXT_GRADIENT,
                       _("Add gradient stop"));
}
Exemple #3
0
/**
 * return true if this gradient is "equivalent" to that gradient.
 * Equivalent meaning they have the same stop count, same stop colors and same stop opacity
 * @param that - A gradient to compare this to
 */
bool SPGradient::isEquivalent(SPGradient *that)
{
    //TODO Make this work for mesh gradients

    bool status = false;
    
    while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function
        if (this->getStopCount() != that->getStopCount()) { break; }
        if (this->hasStops() != that->hasStops()) { break; }
        if (!this->getVector() || !that->getVector()) { break; }
        if (this->isSwatch() != that->isSwatch()) {  break; }
        if ( this->isSwatch() ){
           // drop down to check stops.
        }
        else if (
            (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) ||
            (SP_IS_RADIALGRADIENT(this) && SP_IS_RADIALGRADIENT(that)) ||
            (SP_IS_MESH(this)           && SP_IS_MESH(that))) {
            if(!this->isAligned(that))break;
        }
        else { break; }  // this should never happen, some unhandled type of gradient

        SPStop *as = this->getVector()->getFirstStop();
        SPStop *bs = that->getVector()->getFirstStop();

        bool effective = true;
        while (effective && (as && bs)) {
            if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) ||
                    as->offset != bs->offset) {
                effective = false;
                break;
            } 
            else {
                as = as->getNextStop();
                bs = bs->getNextStop();
            }
        }
        if (!effective) break;

        status = true;
        break;
    }
    return status;
}
Exemple #4
0
int SPGradient::getStopCount() const
{
    int count = 0;

    for (SPStop *stop = const_cast<SPGradient*>(this)->getFirstStop(); stop && stop->getNextStop(); stop = stop->getNextStop()) {
        count++;
    }

    return count;
}
Exemple #5
0
// user selected existing stop from list
static void sp_grad_edit_combo_box_changed (GtkComboBox * /*widget*/, GtkWidget *tbl)
{
    SPStop *stop = get_selected_stop(tbl);
    if (!stop) {
        return;
    }

    blocked = TRUE;

    SelectedColor *csel = static_cast<SelectedColor*>(g_object_get_data(G_OBJECT(tbl), "cselector"));
    // set its color, from the stored array
    g_object_set_data(G_OBJECT(tbl), "updating_color", reinterpret_cast<void*>(1));
    csel->setColorAlpha(stop->getEffectiveColor(), stop->opacity);
    g_object_set_data(G_OBJECT(tbl), "updating_color", reinterpret_cast<void*>(0));
    GtkWidget *offspin = GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offspn"));
    GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offslide"));

    GtkAdjustment *adj = static_cast<GtkAdjustment*>(g_object_get_data(G_OBJECT(tbl), "offset"));

    bool isEndStop = false;

    SPStop *prev = NULL;
    prev = stop->getPrevStop();
    if (prev != NULL )  {
        gtk_adjustment_set_lower (adj, prev->offset);
    } else {
        isEndStop = true;
        gtk_adjustment_set_lower (adj, 0);
    }

    SPStop *next = NULL;
    next = stop->getNextStop();
    if (next != NULL ) {
        gtk_adjustment_set_upper (adj, next->offset);
    } else {
        isEndStop = true;
        gtk_adjustment_set_upper (adj, 1.0);
    }

    //fixme: does this work on all possible input gradients?
    if (!isEndStop) {
        gtk_widget_set_sensitive(offslide, TRUE);
        gtk_widget_set_sensitive(GTK_WIDGET(offspin), TRUE);
    } else {
        gtk_widget_set_sensitive(offslide, FALSE);
        gtk_widget_set_sensitive(GTK_WIDGET(offspin), FALSE);
    }

    gtk_adjustment_set_value(adj, stop->offset);

    gtk_adjustment_changed(adj);

    blocked = FALSE;
}
static void gr_stop_set_offset(GtkComboBox * /*widget*/, GtkWidget *data)
{
    SPStop *stop = get_selected_stop(data);
    if (!stop) {
        return;
    }

    EgeAdjustmentAction* act = (EgeAdjustmentAction *)g_object_get_data( G_OBJECT(data), "offset_action");
    if (!act) {
        return;
    }

    GtkAdjustment *adj = ege_adjustment_action_get_adjustment(act);

    bool isEndStop = false;

    SPStop *prev = NULL;
    prev = stop->getPrevStop();
    if (prev != NULL )  {
        gtk_adjustment_set_lower(adj, prev->offset);
    } else {
        isEndStop = true;
        gtk_adjustment_set_lower(adj, 0);
    }

    SPStop *next = NULL;
    next = stop->getNextStop();
    if (next != NULL ) {
        gtk_adjustment_set_upper(adj, next->offset);
    } else {
        isEndStop = true;
        gtk_adjustment_set_upper(adj, 1.0);
    }

    blocked = TRUE;
    gtk_adjustment_set_value(adj, stop->offset);
    gtk_action_set_sensitive( GTK_ACTION(act), !isEndStop );
    gtk_adjustment_changed(adj);
    blocked = FALSE;

}