#include "PathView.h" #include "LinePathBuilder.h" #include class ShapeLPB : public LinePathBuilder { BShape fShape; protected: virtual void MoveTo(BPoint p); virtual void LineTo(BPoint p); virtual void BezierTo(BPoint* p); virtual void ClosePath(void); public: ShapeLPB(SubPath *subPath, float penSize, cap_mode capMode, join_mode joinMode, float miterLimit); BShape *Shape() { return &fShape; } }; ShapeLPB::ShapeLPB(SubPath *subPath, float penSize, cap_mode capMode, join_mode joinMode, float miterLimit) : LinePathBuilder(subPath, penSize, capMode, joinMode, miterLimit) { } void ShapeLPB::MoveTo(BPoint p) { fShape.MoveTo(p); } void ShapeLPB::LineTo(BPoint p) { fShape.LineTo(p); } void ShapeLPB::BezierTo(BPoint p[3]) { fShape.BezierTo(p); } void ShapeLPB::ClosePath(void) { fShape.Close(); } PathView::PathView(BRect rect) : BView(rect, NULL, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE) { //SetViewColor(B_TRANSPARENT_COLOR); fMode = kStroke; fCurPoint = -1; fWidth = 16; } void PathView::Draw(BRect updateRect) { if (fMode == kDrawOutline) { } else if (fMode == kStroke) { const int n = fPath.CountPoints(); BShape shape; for (int i = 0; i < n; i++) { if (i == 0) shape.MoveTo(fPath.PointAt(i)); else shape.LineTo(fPath.PointAt(i)); } if (fPath.IsClosed()) shape.Close(); SetPenSize(fWidth); StrokeShape(&shape); ShapeLPB path(&fPath, fWidth, LineCapMode(), LineJoinMode(), LineMiterLimit()); path.CreateLinePath(); SetPenSize(1); BPicture picture; BeginPicture(&picture); FillShape(path.Shape()); EndPicture(); PushState(); ClipToPicture(&picture); SetHighColor(0, 255, 0); FillRect(Bounds()); PopState(); SetOrigin(200, 0); SetHighColor(255, 0, 0); StrokeShape(path.Shape()); Flush(); } } void PathView::MouseDown(BPoint point) { uint32 buttons; GetMouse(&point, &buttons, false); if (buttons == B_SECONDARY_MOUSE_BUTTON) { fCurPoint = fPath.CountPoints(); fPath.AddPoint(point); } else { float d = 100000000000.0; for (int i = 0; i < fPath.CountPoints(); i++) { BPoint p = point - fPath.PointAt(i); float e = p.x*p.x + p.y*p.y; if (e < d) { fCurPoint = i; d = e; } } fPath.AtPut(fCurPoint, point); } Invalidate(); } void PathView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) { if (fCurPoint != -1) { fPath.AtPut(fCurPoint, point); Invalidate(); } } void PathView::MouseUp(BPoint point) { fCurPoint = -1; } void PathView::SetClose(bool close) { if (close) fPath.Close(); else fPath.Open(); }