-// spline.cpp: NURBS object
-//
-// Part of the Architektonas Project
-// (C) 2014 Underground Software
-// See the README and GPLv3 files for licensing and warranty information
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO WHEN WHAT
-// --- ---------- ------------------------------------------------------------
-// JLH 03/20/2014 Created this file
-//
-
-#include "spline.h"
-
-#include <QtGui>
-#include "geometry.h"
-#include "painter.h"
-
-#warning "!!! This class is NOT CORRECT !!! FIX !!!"
-Spline::Spline(Vector p1, double r, Object * p/*= NULL*/): Object(p1, p), radius(r),
- draggingEdge(false), draggingCenter(false), hitCenter(false), hitSpline(false)
-{
- type = OTSpline;
-}
-
-
-Spline::~Spline()
-{
-}
-
-
-/*virtual*/ void Spline::Draw(Painter * painter)
-{
- if (state == OSSelected || hitSpline || hitCenter)
- painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
- else
- painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
-
- // Hatch/Fill...
-// QBrush brush(Qt::DiagCrossPattern);
-// brush.setColor(QColor(255, 255, 0));
-// painter->SetBrush(brush);
- painter->SetBrush(QBrush(Qt::NoBrush));
-
- // Draw the object...
- painter->DrawEllipse(position, radius, radius);
-
- // & draw handles (if needed)
- if (state == OSSelected || hitCenter)
- painter->DrawHandle(position);
-
- if (state == OSSelected && draggingEdge && objectWasDragged)
- painter->DrawHandle(dragPoint);
-
- // If resizing the circle, draw an information panel showing the new radius.
- if (draggingEdge)
- {
- QString text = QObject::tr("Radius: %1\nScale: %2%");
- text = text.arg(radius, 0, 'd', 4).arg(radius / oldRadius * 100.0, 0, 'd', 0);
-#if 0
- QPen pen = QPen(QColor(0x00, 0xFF, 0x00), 1.0, Qt::SolidLine);
- painter->SetPen(pen);
- painter->SetBrush(QBrush(QColor(0x40, 0xFF, 0x40, 0x9F)));
- QRectF textRect(10.0, 10.0, 270.0, 70.0); // x, y, w, h
- painter->DrawRoundedRect(textRect, 7.0, 7.0);
-
- textRect.setLeft(textRect.left() + 14);
- painter->SetFont(*Object::font);
- pen = QPen(QColor(0x00, 0x5F, 0xDF));
- painter->SetPen(pen);
- painter->DrawText(textRect, Qt::AlignVCenter, text);
-#else
- painter->DrawInformativeText(text);
-#endif
- }
-}
-
-
-/*virtual*/ Vector Spline::Center(void)
-{
- return position;
-}
-
-
-/*virtual*/ bool Spline::Collided(Vector point)
-{
- // Someone told us to fuck off, so we'll fuck off. :-)
- if (ignoreClicks)
- return false;
-
- // We can assume this, since this is a mouse down event here.
- objectWasDragged = false;
- HitTest(point);
-
- // Now that we've done our hit testing on the non-snapped point, snap it if
- // necessary...
- if (snapToGrid)
- point = SnapPointToGrid(point);
-
- draggingCenter = hitCenter;
- draggingEdge = hitSpline;
-
- if (hitCenter || hitSpline)
- {
- dragPoint = point;
- oldState = state;
- state = OSSelected;
- oldRadius = radius;
- return true;
- }
-
- // We didn't hit anything, so deselect this object and report failure to hit
- state = OSInactive;
- return false;
-}
-
-
-/*virtual*/ bool Spline::PointerMoved(Vector point)
-{
- if (selectionInProgress)
- {
- // Check for whether or not the rect contains this circle
-// if (selection.normalized().contains(Extents()))
- if (selection.contains(Extents()))
- state = OSSelected;
- else
- state = OSInactive;
-
- return false;
- }
-
- // Hit test tells us what we hit (if anything) through boolean variables. It
- // also tells us whether or not the state changed.
- SaveHitState();
- bool hovered = HitTest(point);
- needUpdate = HitStateChanged();
- objectWasDragged = (draggingEdge | draggingCenter);
-
- if (objectWasDragged)
- needUpdate = true;
-
- if (draggingEdge)
- radius = Vector::Magnitude(point, position);
- else if (draggingCenter)
- position = point;
-
- // Save this point so the rendering code knows where to draw the handle...
- dragPoint = point;
- return hovered;
-}
-
-
-/*virtual*/ void Spline::PointerReleased(void)
-{
- // Mouse went up, so our dragging is done (if any *was* done, that is)
- draggingEdge = draggingCenter = false;
- hitCenter = hitSpline = false;
-
- // If the object was dragged, then revert to the old state.
- // Otherwise, we were probably just clicked, and want to stay in the selected state.
- if (objectWasDragged)
- state = oldState;
-}
-
-
-/*virtual*/ bool Spline::HitTest(Point point)
-{
-// SaveHitState();
- hitCenter = hitSpline = false;
- double length = Vector::Magnitude(position, point);
-//printf("Spline::length = %lf, radius = %lf\n", length, radius);
-//How to translate this into pixels from Document space???
-//Maybe we need to pass a scaling factor in here from the caller? That would make sense, as
-//the caller knows about the zoom factor and all that good kinda crap
-/*
-Document passes in the correct Cartesian coordinates being pointed to by the mouse.
-So all we have to be concerned with is properly scaling our hot zones/handle sizes,
-since we generally *don't* want those to scale with the zoom level. ;-)
-
-What is going on here?
-If we're zoomed out to, say, 50%, & our radius is 10.0 (absolute), then on screen
-the radius will be 5.0. By multiplying the length by the zoom factor, we align our
-pointed at length with our on screen length.
-*/
- if ((length * Painter::zoom) < 8.0)
- hitCenter = true;
-//wrong: else if ((length < (radius + 2.0)) && (length > (radius - 2.0)))
-/*NB: The following should be identical to what we have down below, but it doesn't work out that way... :-P */
-//close, but no else if (((length * Painter::zoom) < ((radius * Painter::zoom) + 2.0)) && ((length * Painter::zoom) > ((radius * Painter::zoom) - 2.0)))
-//really wrong! else if (((length * Painter::zoom) < (radius + 2.0)) && ((length * Painter::zoom) > (radius - 2.0)))
-// close again, but sill no else if (((length * Painter::zoom) < ((radius + 2.0) * Painter::zoom)) && ((length * Painter::zoom) > ((radius - 2.0) * Painter::zoom)))
- else if ((fabs(length - radius) * Painter::zoom) < 2.0)
- hitSpline = true;
-
-// return HitStateChanged();
- return (hitCenter || hitSpline ? true : false);
-}
-
-
-/*virtual*/ QRectF Spline::Extents(void)
-{
- return QRectF(QPointF(position.x - radius, position.y - radius), QPointF(position.x + radius, position.y + radius));
-}
-
-
-void Spline::SaveHitState(void)
-{
- oldHitCenter = hitCenter;
- oldHitSpline = hitSpline;
-}
-
-
-bool Spline::HitStateChanged(void)
-{
- if ((hitCenter != oldHitCenter) || (hitSpline != oldHitSpline))
- return true;
-
- return false;
-}
-
-
-/*virtual*/ void Spline::Enumerate(FILE * file)
-{
- fprintf(file, "SPLINE %i (%lf,%lf) %lf\n", layer, position.x, position.y, radius);
-}
-
-
-/*virtual*/ Object * Spline::Copy(void)
-{
-#warning "!!! This doesn't take care of attached Dimensions !!!"
-/*
-This is a real problem. While having a pointer in the Dimension to this line's points
-is fast & easy, it creates a huge problem when trying to replicate an object like this.
-
-Maybe a way to fix that then, is to have reference numbers instead of pointers. That
-way, if you copy them, ... you might still have problems. Because you can't be sure if
-a copy will be persistant or not, you then *definitely* do not want them to have the
-same reference number.
-*/
- return new Spline(position, radius, parent);
-}
-
-
-/*virtual*/ void Spline::Rotate(Point point, double angle)
-{
- Point c1 = Geometry::RotatePointAroundPoint(position, point, angle);
- position = c1;
-}
-
-
-/*virtual*/ void Spline::Mirror(Point p1, Point p2)
-{
- Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
- position = c1;
-}
-
-
-/*virtual*/ void Spline::Save(void)
-{
- Object::Save();
- oldRadius2 = radius;
-}
-
-
-/*virtual*/ void Spline::Restore(void)
-{
- Object::Restore();
- radius = oldRadius2;
-}
-