1#include "BezierBounds.h"
2#include "BBView.h"
3#include <InterfaceKit.h>
4
5BBView::BBView(BRect rect)
6	: BView(rect, NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE) {
7	//SetViewColor(B_TRANSPARENT_COLOR);
8	fMode = kStroke;
9	fCurPoint = -1;
10	fWidth = 16;
11}
12
13void BBView::Draw(BRect updateRect) {
14	if (fMode == kDrawOutline) {
15
16	} else if (fMode == kStroke) {
17		int i;
18		if (fPath.CountPoints() > 3) {
19			const int n = 3 * ((fPath.CountPoints()-1) / 3);
20			BShape shape;
21			shape.MoveTo(fPath.PointAt(0));
22			for (i = 1; i < n; i += 3) {
23				BPoint bezier[3] = { fPath.PointAt(i), fPath.PointAt(i+1), fPath.PointAt(i+2) };
24				shape.BezierTo(bezier);
25			}
26			if (fPath.IsClosed()) shape.Close();
27			SetPenSize(fWidth);
28			StrokeShape(&shape);
29
30			BRect bounds[2];
31			SetPenSize(1);
32			SetHighColor(255, 0, 0);
33			SetLowColor(0, 255, 0);
34			for (i = 0; i < n; i += 3) {
35				BPoint bezier[4] = { fPath.PointAt(i), fPath.PointAt(i+1), fPath.PointAt(i+2), fPath.PointAt(i+3) };
36				BRect r = BezierBounds(bezier, 4);
37				StrokeRect(r);
38				if (i == 0) bounds[0] = r; else bounds[0] = bounds[0] | r;
39				r = BezierBounds(bezier, 4, fWidth, LineCapMode(), LineJoinMode(), LineMiterLimit());
40				StrokeRect(r, B_SOLID_LOW);
41				if (i == 0) bounds[1] = r; else bounds[1] = bounds[1] | r;
42			}
43			if (fPath.IsClosed()) {
44				StrokeRect(bounds[0]);
45				StrokeRect(bounds[1], B_SOLID_LOW);
46			}
47		}
48
49		SetHighColor(0, 0, 255);
50		for (i = 0; i < fPath.CountPoints(); i++) {
51			BPoint p = fPath.PointAt(i);
52			StrokeLine(BPoint(p.x-2, p.y), BPoint(p.x+2, p.y));
53			StrokeLine(BPoint(p.x, p.y-2), BPoint(p.x, p.y+2));
54		}
55	}
56}
57
58void BBView::MouseDown(BPoint point) {
59	uint32 buttons;
60	GetMouse(&point, &buttons, false);
61
62	if (buttons == B_SECONDARY_MOUSE_BUTTON) {
63		fCurPoint = fPath.CountPoints();
64		fPath.AddPoint(point);
65	} else {
66		float d = 100000000000.0;
67		for (int i = 0; i < fPath.CountPoints(); i++) {
68			BPoint p = point - fPath.PointAt(i);
69			float e = p.x*p.x + p.y*p.y;
70			if (e < d) { fCurPoint = i; d = e; }
71		}
72		fPath.AtPut(fCurPoint, point);
73	}
74	Invalidate();
75}
76
77void BBView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) {
78	if (fCurPoint != -1) {
79		fPath.AtPut(fCurPoint, point);
80		Invalidate();
81	}
82}
83
84void BBView::MouseUp(BPoint point) {
85	fCurPoint = -1;
86}
87
88void BBView::SetClose(bool close) {
89	if (close) fPath.Close();
90	else fPath.Open();
91}
92