~h-e-6/inkscape/connector-wip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * SVG Connector draft <point> implementation
 *
 * Authors:
 *   Sebastian Götte <inkscape@jaseg.net>
 *
 * Copyright (C) 2013 Authors
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 *
 */

#include "sp-point.h"
#include "attributes.h"
#include <glibmm/i18n.h>
#include "sp-item.h"
#include "xml/repr.h"
#include "sp-factory.h"

namespace {
	SPObject* createPoint() {
		return new SPPoint();
	}

	bool pointRegistered = SPFactory::instance().registerObject("inkscape:point", createPoint);
}

void SPPoint::build(SPDocument *doc, Inkscape::XML::Node *repr)
{
    SPItem::build(doc, repr);

    readAttr("x");
    readAttr("y");
}


void SPPoint::updateWithConnectors()
{
    _updated_signal.emit(this);
    updateRepr();
}


Geom::OptRect SPPoint::bbox(Geom::Affine const &transform, SPItem::BBoxType type)
{
    /* FIXME check that the 0 width/height does not wreak havoc to other parts of the code */
    return Geom::Rect::from_xywh(_x.computed, _y.computed, 0, 0) * transform;
}


char* SPPoint::description()
{
    return g_strdup(_("<b>Point</b>"));
}


Geom::Affine SPPoint::setTransform(Geom::Affine const &xform)
{
    Geom::Point newpos(Geom::Point(_x.computed, _y.computed) * xform);
    /* FIXME is requestDisplayUpdate being called redundantly from here and SPItem? */
    /* FIXME does that matter? */
    setPosition(newpos);
    /* This return value should not matter anyway since it does not make a whole lot of sense to add
     * anything as a child of a point */
    return Geom::Affine(Geom::Affine(xform).withoutTranslation());
}


void SPPoint::update(SPCtx *ctx, guint flags)
{
    SPItem::update(ctx, flags);

    _moved_signal.emit(this, getPosition());
}


/* FIXME are these pixels?! */
void SPPoint::setPosition(double nx, double ny, bool propagate)
{
    setPosition(Geom::Point(nx, ny), propagate);
}


void SPPoint::setPosition(Geom::Point p, bool propagate)
{
    p = p * i2doc_affine().inverse();
    _x.computed = p.x();
    _y.computed = p.y();
    /* FIXME Do we really need our own signal? Can this not be handled by some of SPItem's signals? */
    if(propagate)
        _moved_signal.emit(this, p * i2doc_affine());
}


Geom::Point SPPoint::getPosition(void) const
{
    return Geom::Point(_x.computed, _y.computed) * i2doc_affine();
}


sigc::connection SPPoint::connectMoved(sigc::slot<void, SPPoint*, Geom::Point> slot)
{
    return _moved_signal.connect(slot);
}


sigc::connection SPPoint::connectUpdated(sigc::slot<void, SPPoint*> slot)
{
    return _updated_signal.connect(slot);
}


Inkscape::XML::Node *SPPoint::write (Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, unsigned int flags)
{
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = doc->createElement("inkscape:point");
    }

    sp_repr_set_svg_double(repr, "x", _x.computed);
    sp_repr_set_svg_double(repr, "y", _y.computed);

    SPItem::write(doc, repr, flags);

    return repr;
}


/* TODO this looks kind of boilerplate-ish to me. This should really be done in some parent class */
void SPPoint::setAttr(unsigned int key, const char *value)
{
    switch (key) {
        case SP_ATTR_X:
            _x.readOrUnset(value);
            _moved_signal.emit(this, getPosition());
            requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
            break;
        case SP_ATTR_Y:
            _y.readOrUnset(value);
            _moved_signal.emit(this, getPosition());
            requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
            break;
        default:
            /* Call parent class */
            SPItem::set(key, value);
            break;
    }
}


/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=100:colorcolumn=100 :