1#include "PathView.h"
2#include "LinePathBuilder.h"
3#include <InterfaceKit.h>
4
5class ShapeLPB : public LinePathBuilder
6{
7	BShape fShape;
8
9protected:
10	virtual void MoveTo(BPoint p);
11	virtual void LineTo(BPoint p);
12	virtual void BezierTo(BPoint* p);
13	virtual void ClosePath(void);
14
15public:
16	ShapeLPB(SubPath *subPath, float penSize, cap_mode capMode, join_mode joinMode, float miterLimit);
17	BShape *Shape() { return &fShape; }
18};
19
20ShapeLPB::ShapeLPB(SubPath *subPath, float penSize, cap_mode capMode, join_mode joinMode, float miterLimit)
21	: LinePathBuilder(subPath, penSize, capMode, joinMode, miterLimit)
22{
23}
24
25void ShapeLPB::MoveTo(BPoint p)
26{
27	fShape.MoveTo(p);
28}
29
30void ShapeLPB::LineTo(BPoint p)
31{
32	fShape.LineTo(p);
33}
34
35void ShapeLPB::BezierTo(BPoint p[3])
36{
37	fShape.BezierTo(p);
38}
39
40void ShapeLPB::ClosePath(void)
41{
42	fShape.Close();
43}
44
45PathView::PathView(BRect rect)
46	: BView(rect, NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE) {
47	//SetViewColor(B_TRANSPARENT_COLOR);
48	fMode = kStroke;
49	fCurPoint = -1;
50	fWidth = 16;
51}
52
53void PathView::Draw(BRect updateRect) {
54	if (fMode == kDrawOutline) {
55
56	} else if (fMode == kStroke) {
57		const int n = fPath.CountPoints();
58		BShape shape;
59		for (int i = 0; i < n; i++) {
60			if (i == 0)
61				shape.MoveTo(fPath.PointAt(i));
62			else
63				shape.LineTo(fPath.PointAt(i));
64		}
65		if (fPath.IsClosed()) shape.Close();
66		SetPenSize(fWidth);
67		StrokeShape(&shape);
68
69		ShapeLPB path(&fPath, fWidth, LineCapMode(), LineJoinMode(), LineMiterLimit());
70		path.CreateLinePath();
71		SetPenSize(1);
72
73		BPicture picture;
74		BeginPicture(&picture);
75		FillShape(path.Shape());
76		EndPicture();
77
78		PushState();
79		ClipToPicture(&picture);
80		SetHighColor(0, 255, 0);
81		FillRect(Bounds());
82		PopState();
83
84		SetOrigin(200, 0);
85		SetHighColor(255, 0, 0);
86		StrokeShape(path.Shape());
87		Flush();
88	}
89}
90
91void PathView::MouseDown(BPoint point) {
92	uint32 buttons;
93	GetMouse(&point, &buttons, false);
94
95	if (buttons == B_SECONDARY_MOUSE_BUTTON) {
96		fCurPoint = fPath.CountPoints();
97		fPath.AddPoint(point);
98	} else {
99		float d = 100000000000.0;
100		for (int i = 0; i < fPath.CountPoints(); i++) {
101			BPoint p = point - fPath.PointAt(i);
102			float e = p.x*p.x + p.y*p.y;
103			if (e < d) { fCurPoint = i; d = e; }
104		}
105		fPath.AtPut(fCurPoint, point);
106	}
107	Invalidate();
108}
109
110void PathView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) {
111	if (fCurPoint != -1) {
112		fPath.AtPut(fCurPoint, point);
113		Invalidate();
114	}
115}
116
117void PathView::MouseUp(BPoint point) {
118	fCurPoint = -1;
119}
120
121void PathView::SetClose(bool close) {
122	if (close) fPath.Close();
123	else fPath.Open();
124}
125