summaryrefslogtreecommitdiffstats
path: root/src/sp-item.h
blob: 326ea27593e4b73be12cd83470e9a73b8d32b9de (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#ifndef __SP_ITEM_H__
#define __SP_ITEM_H__

/** \file
 * Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx, SPItemClass, SPEvent.
 */

/*
 * Authors:
 *   Lauris Kaplinski <lauris@kaplinski.com>
 *   bulia byak <buliabyak@users.sf.net>
 *
 * Copyright (C) 1999-2005 authors
 * Copyright (C) 2001-2002 Ximian, Inc.
 * Copyright (C) 2004 Monash University
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

#include <libnr/nr-matrix.h>
#include <libnr/nr-rect.h>

#include "display/nr-arena-forward.h"
#include "forward.h"
#include "sp-object.h"
#include <vector>

namespace Inkscape { class URIReference; }
class SPGuideConstraint;

enum {
    SP_EVENT_INVALID,
    SP_EVENT_NONE,
    SP_EVENT_ACTIVATE,
    SP_EVENT_MOUSEOVER,
    SP_EVENT_MOUSEOUT
};

/**
 * Event structure.
 *
 * \todo This is just placeholder. Plan:
 * We do extensible event structure, that hold applicable (ui, non-ui)
 * data pointers. So it is up to given object/arena implementation
 * to process correct ones in meaningful way.
 * Also, this probably goes to SPObject base class.
 *
 */
struct SPEvent {
    unsigned int type;
    gpointer data;
};

class SPItemView;

/// SPItemView
struct SPItemView {
    SPItemView *next;
    unsigned int flags;
    unsigned int key;
    NRArenaItem *arenaitem;
};

/* flags */

#define SP_ITEM_BBOX_VISUAL 1

#define SP_ITEM_SHOW_DISPLAY (1 << 0)

/**
 * Flag for referenced views (i.e. clippaths, masks and patterns); always display
 */
#define SP_ITEM_REFERENCE_FLAGS SP_ITEM_SHOW_DISPLAY

class SPItemCtx;

/// Contains transformations to document/viewport and the viewport size.
struct SPItemCtx {
    SPCtx ctx;
    /** Item to document transformation */
    NR::Matrix i2doc;
    /** Viewport size */
    NRRect vp;
    /** Item to viewport transformation */
    NR::Matrix i2vp;
};

/** Abstract base class for all visible shapes. */
struct SPItem : public SPObject {
    unsigned int sensitive : 1;
    unsigned int stop_paint: 1;
    double r_cx;
    double r_cy;
    
    NR::Matrix transform;
    
    SPClipPathReference *clip_ref;
    SPMaskReference *mask_ref;
    
    // Used for object-avoiding connectors
    SPAvoidRef *avoidRef;
    
    SPItemView *display;
    
    std::vector<SPGuideConstraint> constraints;
    
    sigc::signal<void, NR::Matrix const *, SPItem *> _transformed_signal;
    
    bool isLocked() const;
    void setLocked(bool lock);
    
    bool isHidden() const;
    void setHidden(bool hidden);
    
    bool isHidden(unsigned display_key) const;
    
    bool isExplicitlyHidden() const;
    
    void setExplicitlyHidden(bool val);
    
    bool isVisibleAndUnlocked() const;
    
    bool isVisibleAndUnlocked(unsigned display_key) const;
    
    NR::Matrix getRelativeTransform(SPObject const *obj) const;
    
    void raiseOne();
    void lowerOne();
    void raiseToTop();
    void lowerToBottom();

    NR::Rect invokeBbox(NR::Matrix const &transform) const;

    sigc::connection connectTransformed(sigc::slot<void, NR::Matrix const *, SPItem *> slot)  {
        return _transformed_signal.connect(slot);
    }
};

typedef std::back_insert_iterator<std::vector<NR::Point> > SnapPointsIter;

/// The SPItem vtable.
struct SPItemClass {
    SPObjectClass parent_class;

    /** BBox union in given coordinate system */
    void (* bbox) (SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags);
    
    /** Printing method. Assumes ctm is set to item affine matrix */
    /* \todo Think about it, and maybe implement generic export method instead (Lauris) */
    void (* print) (SPItem *item, SPPrintContext *ctx);
    
    /** Give short description of item (for status display) */
    gchar * (* description) (SPItem * item);
    
    NRArenaItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
    void (* hide) (SPItem *item, unsigned int key);
    
    /** Write to an iterator the points that should be considered for snapping
     * as the item's `nodes'.
     */
    void (* snappoints) (SPItem const *item, SnapPointsIter p);
    
    /** Apply the transform optimally, and return any residual transformation */
    NR::Matrix (* set_transform)(SPItem *item, NR::Matrix const &transform);
    
    /** Emit event, if applicable */
    gint (* event) (SPItem *item, SPEvent *event);
};

/* Flag testing macros */

#define SP_ITEM_STOP_PAINT(i) (SP_ITEM (i)->stop_paint)

/* Methods */

void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear);
void sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear);

unsigned sp_item_pos_in_parent(SPItem *item);

gchar *sp_item_description(SPItem * item);
void sp_item_invoke_print(SPItem *item, SPPrintContext *ctx);

/** Shows/Hides item on given arena display list */
unsigned int sp_item_display_key_new(unsigned int numkeys);
NRArenaItem *sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
void sp_item_invoke_hide(SPItem *item, unsigned int key);

void sp_item_snappoints(SPItem const *item, SnapPointsIter p);

void sp_item_adjust_pattern(SPItem *item, /* NR::Matrix const &premul, */ NR::Matrix const &postmul, bool set = false);
void sp_item_adjust_gradient(SPItem *item, /* NR::Matrix const &premul, */ NR::Matrix const &postmul, bool set = false);
void sp_item_adjust_stroke(SPItem *item, gdouble ex);
void sp_item_adjust_stroke_width_recursive(SPItem *item, gdouble ex);
void sp_item_adjust_paint_recursive(SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern);

void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NRMatrix const *transform, NR::Matrix const *adv = NULL);
void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const &transform, NR::Matrix const *adv = NULL);

void sp_item_set_item_transform(SPItem *item, NR::Matrix const &transform);

gint sp_item_event (SPItem *item, SPEvent *event);

/* Utility */

NRArenaItem *sp_item_get_arenaitem(SPItem *item, unsigned int key);

void sp_item_bbox_desktop(SPItem *item, NRRect *bbox) __attribute__ ((deprecated));
NR::Rect sp_item_bbox_desktop(SPItem *item);

NR::Matrix i2anc_affine(SPObject const *item, SPObject const *ancestor);
NR::Matrix i2i_affine(SPObject const *src, SPObject const *dest);

NR::Matrix sp_item_i2doc_affine(SPItem const *item);
NR::Matrix sp_item_i2root_affine(SPItem const *item);

NR::Matrix matrix_to_desktop (NR::Matrix m, SPItem const *item);
NR::Matrix matrix_from_desktop (NR::Matrix m, SPItem const *item);

/* fixme: - these are evil, but OK */

/* Fill *TRANSFORM with the item-to-desktop transform.  See doc/coordinates.txt
 * for a description of `Desktop coordinates'; though see also mental's comment
 * at the top of that file.
 *
 * \return TRANSFORM.
 */
NR::Matrix sp_item_i2d_affine(SPItem const *item);
NR::Matrix sp_item_i2r_affine(SPItem const *item);
void sp_item_set_i2d_affine(SPItem *item, NR::Matrix const &transform);
NR::Matrix sp_item_dt2i_affine(SPItem const *item);
int sp_item_repr_compare_position(SPItem *first, SPItem *second);
SPItem *sp_item_first_item_child (SPObject *obj);

#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:encoding=utf-8:textwidth=99 :