summaryrefslogtreecommitdiffstats
path: root/src/seltrans.h
blob: 3ba56ffb4ce18223a5821073c7dacb71f6feab48 (plain)
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
#ifndef __SELTRANS_H__
#define __SELTRANS_H__

/*
 * Helper object for transforming selected items
 *
 * Author:
 *   Lauris Kaplinski <lauris@kaplinski.com>
 *   Carl Hetherington <inkscape@carlh.net>
 *
 * Copyright (C) 2006      Johan Engelen <johan@shouraizou.nl>
 * Copyright (C) 1999-2002 Lauris Kaplinski
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

#include <sigc++/sigc++.h>
#include <libnr/nr-point.h>
#include <libnr/nr-matrix.h>
#include <libnr/nr-rect.h>
#include "forward.h"
#include "selcue.h"
#include "message-context.h"
#include <vector>

struct SPKnot;
class SPDesktop;
class SPCanvasItem;
class SPSelTransHandle;

namespace Inkscape
{

namespace XML
{
  class Node;
}

class SelTrans
{
public:
    SelTrans(SPDesktop *desktop);
    ~SelTrans();

    Inkscape::MessageContext &messageContext() {
        return _message_context;
    }

    void increaseState();
    void resetState();
    void setCenter(NR::Point const &p);
    void grab(NR::Point const &p, gdouble x, gdouble y, bool show_handles);
    void transform(NR::Matrix const &rel_affine, NR::Point const &norm);
    void ungrab();
    void stamp();
    void moveTo(NR::Point const &xy, guint state);
    void stretch(SPSelTransHandle const &handle, NR::Point &pt, guint state);
    void scale(NR::Point &pt, guint state);
    void skew(SPSelTransHandle const &handle, NR::Point &pt, guint state);
    void rotate(NR::Point &pt, guint state);
    gboolean scaleRequest(NR::Point &pt, guint state);
    gboolean stretchRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state);
    gboolean skewRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state);
    gboolean rotateRequest(NR::Point &pt, guint state);
    gboolean centerRequest(NR::Point &pt, guint state);

    gboolean handleRequest(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle);
    void handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle);
    void handleClick(SPKnot *knot, guint state, SPSelTransHandle const &handle);
    void handleNewEvent(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle);

    enum Show
    {
        SHOW_CONTENT,
        SHOW_OUTLINE
    };

    void setShow(Show s) {
        _show = s;
    }
    bool isEmpty() {
        return _empty;
    }
    bool isGrabbed() {
        return _grabbed;    
    }
    
private:
    void _updateHandles();
    void _updateVolatileState();
    void _selChanged(Inkscape::Selection *selection);
    void _selModified(Inkscape::Selection *selection, guint flags);
    void _showHandles(SPKnot *knot[], SPSelTransHandle const handle[], gint num,
                      gchar const *even_tip, gchar const *odd_tip);

    enum State {
        STATE_SCALE,
	STATE_ROTATE
    };
    
    SPDesktop *_desktop;

    std::vector<std::pair<SPItem *, NR::Matrix> > _items;
    std::vector<std::pair<SPItem *, NR::Point> > _items_centers;
    
    std::vector<NR::Point> _snap_points;
    std::vector<NR::Point> _bbox_points;
    
    Inkscape::SelCue _selcue;

    Inkscape::Selection *_selection;
    State _state;
    Show _show;

    bool _grabbed;
    bool _show_handles;
    bool _empty;
    bool _changed;

    NR::Rect _box;
    gdouble _strokewidth;
    NR::Matrix _current;
    NR::Point _opposite; ///< opposite point to where a scale is taking place

    NR::Point _center;
    bool _center_is_set; ///< we've already set _center, no need to reread it from items

    SPKnot *_shandle[8];
    SPKnot *_rhandle[8];
    SPKnot *_chandle;
    SPCanvasItem *_norm;
    SPCanvasItem *_grip;
    SPCanvasItem *_l[4];
    guint _sel_changed_id;
    guint _sel_modified_id;
    GSList *_stamp_cache;    

    NR::Point _origin; ///< position of origin for transforms
    NR::Point _point; ///< original position of the knot being used for the current transform
    Inkscape::MessageContext _message_context;
    SigC::Connection _sel_changed_connection;
    SigC::Connection _sel_modified_connection;
};

}

#endif


/*
  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 :