summaryrefslogtreecommitdiffstats
path: root/src/ui/tools/pen-tool.h
blob: 4dec7b4fead5839a641f484f3fe3ea498d2d8770 (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
#ifndef SEEN_PEN_CONTEXT_H
#define SEEN_PEN_CONTEXT_H

/** \file 
 * PenTool: a context for pen tool events.
 */

#include "ui/tools/freehand-base.h"
#include "live_effects/effect.h"

#define SP_PEN_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::PenTool*>((Inkscape::UI::Tools::ToolBase*)obj))
#define SP_IS_PEN_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::PenTool*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL)

struct SPCtrlLine;

namespace Inkscape {
namespace UI {
namespace Tools {

/**
 * PenTool: a context for pen tool events.
 */
class PenTool : public FreehandBase {
public:
	PenTool();
	PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y);
	virtual ~PenTool();

	enum Mode {
	    MODE_CLICK,
	    MODE_DRAG
	};

	enum State {
	    POINT,
	    CONTROL,
	    CLOSE,
	    STOP
	};

    Geom::Point p[5];

    /** \invar npoints in {0, 2, 5}. */
    // npoints somehow determines the type of the node (what does it mean, exactly? the number of Bezier handles?)
    gint npoints;

    Mode mode;
    State state;

    bool polylines_only;
    bool polylines_paraxial;
    int num_clicks;

    unsigned int expecting_clicks_for_LPE; // if positive, finish the path after this many clicks
    Inkscape::LivePathEffect::Effect *waiting_LPE; // if NULL, waiting_LPE_type in SPDrawContext is taken into account
    SPLPEItem *waiting_item;

    SPCanvasItem *c0;
    SPCanvasItem *c1;

    SPCtrlLine *cl0;
    SPCtrlLine *cl1;
    
    bool events_disabled;

	static const std::string prefsPath;

	virtual const std::string& getPrefsPath();

	int nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const;
	void setPolylineMode();
	bool hasWaitingLPE();
    void waitForLPEMouseClicks(Inkscape::LivePathEffect::EffectType effect_type, unsigned int num_clicks, bool use_polylines = true);

protected:
	virtual void setup();
	virtual void finish();
	virtual void set(const Inkscape::Preferences::Entry& val);
	virtual bool root_handler(GdkEvent* event);
	virtual bool item_handler(SPItem* item, GdkEvent* event);

private:
	bool _handleButtonPress(GdkEventButton const &bevent);
	bool _handleMotionNotify(GdkEventMotion const &mevent);
	bool _handleButtonRelease(GdkEventButton const &revent);
	bool _handle2ButtonPress(GdkEventButton const &bevent);
	bool _handleKeyPress(GdkEvent *event);

	void _setInitialPoint(Geom::Point const p);
	void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0);
	void _setCtrl(Geom::Point const p, guint state);
	void _finishSegment(Geom::Point p, guint state);

	void _finish(gboolean closed);

	void _resetColors();

	void _disableEvents();
	void _enableEvents();

	void _setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const;

	void _setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message);

	void _lastpointToLine();
	void _lastpointToCurve();
	void _lastpointMoveScreen(gdouble x, gdouble y);
	void _lastpointMove(gdouble x, gdouble y);
	void _redrawAll();

	void _endpointSnapHandle(Geom::Point &p, guint const state) const;
	void _endpointSnap(Geom::Point &p, guint const state) const;

	void _cancel();
};

}
}
}

#endif /* !SEEN_PEN_CONTEXT_H */

/*
  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:fileencoding=utf-8:textwidth=99 :