X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmainapp%2Fgraphicview.cpp;h=d29de4a7817b81689bea7c7d3cd50ad7991bfe3d;hb=bfd926cd5fd98e95b8b172fabd5340c9b1957e01;hp=4c8ba107be210da42b9afbcfab09937f1ea8ec5e;hpb=16354e0421b316a62c6b9f7b0b4f3b8cf6f06284;p=architektonas diff --git a/src/mainapp/graphicview.cpp b/src/mainapp/graphicview.cpp index 4c8ba10..d29de4a 100644 --- a/src/mainapp/graphicview.cpp +++ b/src/mainapp/graphicview.cpp @@ -35,13 +35,11 @@ GraphicView::GraphicView(): background(), foreground() printing = false; deleteMode = false; factor = Vector(1.0, 1.0); - offsetX = 0; - offsetY = 0; + offsetX = offsetY = 0; previousFactor = Vector(1.0, 1.0); - previousOffsetX = 0; - previousOffsetY = 0; + previousOffsetX = previousOffsetY = 0; container = NULL; - eventHandler = new EventHandler(this); + eventHandler = new EventHandler(); gridColor = Qt::gray; metaGridColor = Color(64, 64, 64); grid = new Grid(this); @@ -50,10 +48,7 @@ GraphicView::GraphicView(): background(), foreground() draftMode = false; painter = NULL; - borderLeft = 0; - borderTop = 0; - borderRight = 0; - borderBottom = 0; + borderLeft = borderTop = borderRight = borderBottom = 0; relativeZero = Vector(false); relativeZeroLocked = false; @@ -77,6 +72,24 @@ GraphicView::GraphicView(): background(), foreground() simulationSmooth = false; simulationRapid = false; simulationRunning = false; + + // Snapper settings... + snapEntity = NULL; + snapSpot = Vector(false); + snapCoord = Vector(false); + snapperVisible = false; + snapDistance = 1.0; + + settings.beginGroup("Snap"); + snapRange = settings.value("Range", 20).toInt(); + settings.endGroup(); + settings.beginGroup("Appearance"); + showCrosshairs = settings.value("ShowCrosshairs", true).toBool(); + settings.endGroup(); + + // Sanity check for snapRange + if (snapRange < 2) + snapRange = 20; } /** @@ -434,10 +447,10 @@ void GraphicView::updateView() */ ActionInterface * GraphicView::getDefaultAction() { - if (eventHandler != NULL) - return eventHandler->getDefaultAction(); - else - return NULL; + if (eventHandler) + return eventHandler->GetDefaultAction(); + + return NULL; } /** @@ -446,7 +459,7 @@ ActionInterface * GraphicView::getDefaultAction() void GraphicView::setDefaultAction(ActionInterface * action) { if (eventHandler) - eventHandler->setDefaultAction(action); + eventHandler->SetDefaultAction(action); } /** @@ -455,7 +468,7 @@ void GraphicView::setDefaultAction(ActionInterface * action) ActionInterface * GraphicView::getCurrentAction() { if (eventHandler) - return eventHandler->getCurrentAction(); + return eventHandler->GetCurrentAction(); else return NULL; } @@ -468,7 +481,7 @@ void GraphicView::setCurrentAction(ActionInterface * action) DEBUG->print("GraphicView::setCurrentAction"); if (eventHandler) - eventHandler->setCurrentAction(action); + eventHandler->SetCurrentAction(action); DEBUG->print("GraphicView::setCurrentAction: OK"); } @@ -480,7 +493,7 @@ void GraphicView::setCurrentAction(ActionInterface * action) void GraphicView::killSelectActions() { if (eventHandler) - eventHandler->killSelectActions(); + eventHandler->KillSelectActions(); } /** @@ -488,8 +501,9 @@ void GraphicView::killSelectActions() */ void GraphicView::killAllActions() { + //KillAll does nothing... if (eventHandler) - eventHandler->killAllActions(); + eventHandler->KillAllActions(); } /** @@ -497,8 +511,8 @@ void GraphicView::killAllActions() */ void GraphicView::back() { - if (eventHandler && eventHandler->hasAction()) - eventHandler->back(); + if (eventHandler && eventHandler->HasAction()) + eventHandler->Back(); else if (DIALOGFACTORY) DIALOGFACTORY->requestPreviousMenu(); } @@ -508,8 +522,8 @@ void GraphicView::back() */ void GraphicView::enter() { - if (eventHandler && eventHandler->hasAction()) - eventHandler->enter(); + if (eventHandler && eventHandler->HasAction()) + eventHandler->Enter(); } /** @@ -519,7 +533,7 @@ void GraphicView::enter() void GraphicView::mousePressEvent(QMouseEvent * e) { if (eventHandler) - eventHandler->mousePressEvent(e); + eventHandler->MousePressEvent(e); } /** @@ -533,9 +547,9 @@ void GraphicView::mouseReleaseEvent(QMouseEvent * e) if (!eventHandler) return; - if (e->button() != Qt::RightButton || eventHandler->hasAction()) + if (e->button() != Qt::RightButton || eventHandler->HasAction()) { - eventHandler->mouseReleaseEvent(e); + eventHandler->MouseReleaseEvent(e); } else { @@ -554,10 +568,10 @@ void GraphicView::mouseMoveEvent(QMouseEvent * e) { DEBUG->print("GraphicView::mouseMoveEvent begin"); - Drawing * graphic = NULL; + Drawing * drawing = NULL; if (container->rtti() == RS2::EntityGraphic) - graphic = (Drawing *)container; + drawing = (Drawing *)container; DEBUG->print("GraphicView::mouseMoveEvent 001"); @@ -570,17 +584,18 @@ void GraphicView::mouseMoveEvent(QMouseEvent * e) DEBUG->print("GraphicView::mouseMoveEvent 002"); if (eventHandler) - eventHandler->mouseMoveEvent(e); + eventHandler->MouseMoveEvent(e); DEBUG->print("GraphicView::mouseMoveEvent 003"); - if (!eventHandler || !eventHandler->hasAction() && graphic) + if (!eventHandler || !eventHandler->HasAction() && drawing) { - Vector mouse = toGraph(Vector(mx, my)); - Vector relMouse = mouse - getRelativeZero(); - if (DIALOGFACTORY) + { + Vector mouse = toGraph(Vector(mx, my)); + Vector relMouse = mouse - getRelativeZero(); DIALOGFACTORY->updateCoordinateWidget(mouse, relMouse); + } } DEBUG->print("GraphicView::mouseMoveEvent end"); @@ -593,7 +608,7 @@ void GraphicView::mouseMoveEvent(QMouseEvent * e) void GraphicView::mouseLeaveEvent() { if (eventHandler) - eventHandler->mouseLeaveEvent(); + eventHandler->MouseLeaveEvent(); } /** @@ -603,7 +618,7 @@ void GraphicView::mouseLeaveEvent() void GraphicView::mouseEnterEvent() { if (eventHandler) - eventHandler->mouseEnterEvent(); + eventHandler->MouseEnterEvent(); } /** @@ -613,7 +628,7 @@ void GraphicView::mouseEnterEvent() void GraphicView::keyPressEvent(QKeyEvent * e) { if (eventHandler) - eventHandler->keyPressEvent(e); + eventHandler->KeyPressEvent(e); } /** @@ -623,7 +638,7 @@ void GraphicView::keyPressEvent(QKeyEvent * e) void GraphicView::keyReleaseEvent(QKeyEvent * e) { if (eventHandler) - eventHandler->keyReleaseEvent(e); + eventHandler->KeyReleaseEvent(e); } /** @@ -632,7 +647,7 @@ void GraphicView::keyReleaseEvent(QKeyEvent * e) void GraphicView::commandEvent(CommandEvent * e) { if (eventHandler) - eventHandler->commandEvent(e); + eventHandler->HandleCommandEvent(this, e); } /** @@ -641,7 +656,7 @@ void GraphicView::commandEvent(CommandEvent * e) void GraphicView::enableCoordinateInput() { if (eventHandler) - eventHandler->enableCoordinateInput(); + eventHandler->EnableCoordinateInput(); } /** @@ -650,7 +665,7 @@ void GraphicView::enableCoordinateInput() void GraphicView::disableCoordinateInput() { if (eventHandler) - eventHandler->disableCoordinateInput(); + eventHandler->DisableCoordinateInput(); } /** @@ -668,6 +683,7 @@ void GraphicView::zoomIn(double f, const Vector & center) return; Vector c = center; + if (c.valid == false) c = toGraph(Vector(getWidth() / 2, getHeight() / 2)); @@ -919,7 +935,8 @@ void GraphicView::zoomAutoY(bool axis) x1 = toGuiX(l->getStartpoint().x); x2 = toGuiX(l->getEndpoint().x); - if (x1 > 0.0 && x1 < (double)getWidth() || x2 > 0.0 && x2 < (double)getWidth()) + if ((x1 > 0.0 && x1 < (double)getWidth()) + || (x2 > 0.0 && x2 < (double)getWidth())) { minY = std::min(minY, l->getStartpoint().y); minY = std::min(minY, l->getEndpoint().y); @@ -1176,7 +1193,8 @@ void GraphicView::drawWindow(Vector v1, Vector v2) /** * Draws the entities. If painter is NULL a new painter will - * be created and destroyed. + * be created and destroyed. [NB: Not any more, we don't let the programmer try + * to outsmart the toolkit anymore. :-P */ void GraphicView::drawIt() { @@ -2076,6 +2094,8 @@ void GraphicView::setDefaultSnapMode(RS2::SnapMode sm) { defaultSnapMode = sm; +// Don't need this shiaut anymore +#if 0 if (eventHandler) eventHandler->setSnapMode(sm); @@ -2084,6 +2104,7 @@ void GraphicView::setDefaultSnapMode(RS2::SnapMode sm) //us up, hm notwithstanding. [and it does. :-)] //hm. snapper.setSnapMode(sm); +#endif } /** @@ -2093,8 +2114,11 @@ void GraphicView::setSnapRestriction(RS2::SnapRestriction sr) { defaultSnapRes = sr; +// Don't need this shiaut anymore +#if 0 if (eventHandler != NULL) eventHandler->setSnapRestriction(sr); +#endif } /** @@ -2329,3 +2353,354 @@ bool GraphicView::getSimulationRapid() { return simulationRapid; } + +/** + * Catches an entity which is close to the given position 'pos'. + * + * @param pos A graphic coordinate. + * @param level The level of resolving for iterating through the entity + * container + * @return Pointer to the entity or NULL. + */ +Entity * GraphicView::CatchEntity(const Vector & pos, RS2::ResolveLevel level) +{ + DEBUG->print("GraphicView::CatchEntity"); + + // Set default distance for points inside solids + double dist = toGraphDX(snapRange) * 0.9; + Entity * entity = container->getNearestEntity(pos, &dist, level); + + // DEBUGGING INFO + int idx = -1; + + if (entity && entity->getParent()) + idx = entity->getParent()->findEntity(entity); + // END DEBUGGING INFO + + if (entity && dist <= toGraphDX(snapRange)) + { + // Highlight: + DEBUG->print("GraphicView::CatchEntity: found: idx=%d", idx); + return entity; + } + + DEBUG->print("GraphicView::CatchEntity: not found"); + return NULL; +} + +/** + * Catches an entity which is close to the mouse cursor. + * + * @param e A mouse event. + * @param level The level of resolving for iterating through the entity + * container + * @return Pointer to the entity or NULL. + */ +Entity * GraphicView::CatchEntity(QMouseEvent * e, RS2::ResolveLevel level) +{ + return CatchEntity(Vector(toGraphX(e->x()), toGraphY(e->y())), level); +} + +/** + * @return Pointer to the entity which was the key entity for the last + * successful snapping action. If the snap mode is "end point" the key entity + * is the entity whose end point was caught. If the snap mode didn't require an + * entity (e.g. free, grid) this method will return NULL. + */ +Entity * GraphicView::GetSnapperEntity() +{ + return snapEntity; +} + +/** + * Snap to a coordinate in the drawing using the current snap mode. + * + * @param e A mouse event. + * @return The coordinates of the point or an invalid vector. + */ +Vector GraphicView::SnapPoint(QMouseEvent * e) +{ + DEBUG->print("GraphicView::SnapPoint"); + /*Vector*/ snapSpot = Vector(false); + + if (!e) + { + DEBUG->print(Debug::D_WARNING, "GraphicView::SnapPoint: QMouseEvent is NULL"); + return snapSpot; + } + + Vector mouseCoord = toGraph(e->x(), e->y()); + +// switch (snapMode) + switch (defaultSnapMode) + { + case RS2::SnapFree: +// snapSpot = snapFree(mouseCoord); + snapEntity = NULL; + snapSpot = mouseCoord; + break; + + case RS2::SnapEndpoint: +// snapSpot = snapEndpoint(mouseCoord); + snapSpot = container->getNearestEndpoint(mouseCoord, NULL); + break; + + case RS2::SnapGrid: + snapSpot = SnapGrid(mouseCoord); + break; + + case RS2::SnapOnEntity: +// snapSpot = snapOnEntity(mouseCoord); + snapSpot = container->getNearestPointOnEntity(mouseCoord, true, NULL, &snapEntity); + break; + + case RS2::SnapCenter: +// snapSpot = snapCenter(mouseCoord); + snapSpot = container->getNearestCenter(mouseCoord, NULL); + break; + + case RS2::SnapMiddle: +// snapSpot = snapMiddle(mouseCoord); + snapSpot = container->getNearestMiddle(mouseCoord, NULL); + break; + + case RS2::SnapDist: +// snapSpot = snapDist(mouseCoord); + snapSpot = container->getNearestDist(snapDistance, mouseCoord, NULL); + break; + + case RS2::SnapIntersection: +// snapSpot = snapIntersection(mouseCoord); + snapSpot = container->getNearestIntersection(mouseCoord, NULL); + break; + + default: + break; + } + + // This is declared here because I really, really hate extraneous braces in + // my switch statements. :-P + Vector relZero = getRelativeZero(); + Vector restrictX = Vector(relZero.x, snapSpot.y); + Vector restrictY = Vector(snapSpot.x, relZero.y); +// Vector snapCoord; + // Handle snap restrictions that can be activated in addition to the ones above: +// switch (snapRes) + switch (defaultSnapRes) + { + case RS2::RestrictOrthogonal: +//// snapCoord = restrictOrthogonal(snapSpot); +// rz = graphicView->getRelativeZero(); +// retx = Vector(rz.x, snapSpot.y); +// rety = Vector(snapSpot.x, rz.y); + snapCoord = (restrictX.distanceTo(snapSpot) < restrictY.distanceTo(snapSpot) ? + restrictX : restrictY); + break; + case RS2::RestrictHorizontal: +//// snapCoord = restrictHorizontal(snapSpot); +// rz = graphicView->getRelativeZero(); +// snapCoord = Vector(snapSpot.x, rz.y); + snapCoord = restrictY; + break; + case RS2::RestrictVertical: +//// snapCoord = restrictVertical(snapSpot); +// rz = graphicView->getRelativeZero(); +// snapCoord = Vector(rz.x, snapSpot.y); + snapCoord = restrictX; + break; + default: + case RS2::RestrictNothing: + snapCoord = snapSpot; + break; + } + + if (DIALOGFACTORY) + DIALOGFACTORY->updateCoordinateWidget(snapCoord, snapCoord - relZero); + + DEBUG->print("GraphicView::SnapPoint: OK"); + + return snapCoord; +} + +/** + * Snaps to a grid point. + * + * @param coord The mouse coordinate. + * @return The coordinates of the point or an invalid vector. + */ +Vector GraphicView::SnapGrid(Vector coord) +{ + DEBUG->print("GraphicView::snapGrid begin"); + + Vector vec(false); + double dist = 0.0; + + DEBUG->print("GraphicView::snapGrid 001"); + + if (grid) + { + DEBUG->print("GraphicView::snapGrid 002"); + Vector * pts = grid->getPoints(); + DEBUG->print("GraphicView::snapGrid 003"); + int closest = -1; + dist = 32000.00; + DEBUG->print("GraphicView::snapGrid 004"); + + for(int i=0; icount(); ++i) + { + double d = pts[i].distanceTo(coord); + + if (d < dist) + { + closest = i; + dist = d; + } + } + + DEBUG->print("GraphicView::snapGrid 005"); + + if (closest >= 0) + vec = pts[closest]; + + DEBUG->print("GraphicView::snapGrid 006"); + } + + snapEntity = NULL; + + DEBUG->print("GraphicView::snapGrid end"); + + return vec; +} + +void GraphicView::DrawSnapper(PaintInterface * painter) +{ +//Is "finished" used at all? Seems it's used only in ActionInterface, and it's commented out +// if (finished || !snapSpot.valid || !snapCoord.valid) + if (!snapSpot.valid || !snapCoord.valid) +#if 1 +{ +printf("DrawSnapper: snapSpot=%s, snapCoord=%s...\n", (snapSpot.valid ? "valid" : "INVALID"), (snapCoord.valid ? "valid" : "INVALID")); +#endif + return; +#if 1 +} +#endif + + // Snap point (need to make sure the brush is NULL!) +// painter->setPen(Pen(Color(0, 127, 255), RS2::Width00, RS2::DashLine)); + painter->setPen(Pen(Color(255, 127, 0), RS2::Width00, RS2::DashLine)); + painter->drawCircle(toGui(snapCoord), 4); + + // Crosshairs + if (showCrosshairs) + { + painter->setPen(Pen(Color(0, 255, 255), RS2::Width00, RS2::DashLine)); + painter->drawLine(Vector(0, toGuiY(snapCoord.y)), + Vector(getWidth(), toGuiY(snapCoord.y))); + painter->drawLine(Vector(toGuiX(snapCoord.x), 0), + Vector(toGuiX(snapCoord.x), getHeight())); + } + + // Cursor + if (snapCoord != snapSpot) + { + painter->drawLine(toGui(snapSpot) + Vector(-5, 0), toGui(snapSpot) + Vector(-1, 4)); + painter->drawLine(toGui(snapSpot) + Vector(0, 5), toGui(snapSpot) + Vector(4, 1)); + painter->drawLine(toGui(snapSpot) + Vector(5, 0), toGui(snapSpot) + Vector(1, -4)); + painter->drawLine(toGui(snapSpot) + Vector(0, -5), toGui(snapSpot) + Vector(-4, -1)); + } +} + +void GraphicView::SetSnapperVisible(bool visibility/*= true*/) +{ + snapperVisible = visibility; +} + +bool GraphicView::SnapperVisible(void) +{ + return snapperVisible; +} + +#if 0 +/* +only place this is called is in ActionInterface. And its only function is to +have it not drawn anymore. But, the GraphicView seems to draw it anyway... So +some other approach is needed... +*/ +void Snapper::finish() +{ + finished = true; +} + +/** Sets a new snap mode. */ +void Snapper::setSnapMode(RS2::SnapMode snapMode) +{ + this->snapMode = snapMode; +} + +/** Sets a new snap restriction. */ +void Snapper::setSnapRestriction(RS2::SnapRestriction snapRes) +{ + this->snapRes = snapRes; +} + +RS2::SnapMode Snapper::getSnapMode(void) +{ + return snapMode; +} + +RS2::SnapRestriction Snapper::getSnapRestriction(void) +{ + return snapRes; +} + +/** + * Sets the snap range in pixels for catchEntity(). + * + * @see catchEntity() + */ +void Snapper::setSnapRange(int r) +{ + snapRange = r; +} + +#if 0 +I think that these suspend() & resume() functions are not used anymore... +#endif +/** + * Suspends this snapper while another action takes place. + */ +/*virtual*/ void Snapper::suspend() +{ +#warning "!!! This may need to have SetVisibility() called !!!" +// deleteSnapper(); + snapSpot = snapCoord = Vector(false); +} + +/** + * Resumes this snapper after it has been suspended. + */ +/*virtual*/ void Snapper::resume() +{ +#warning "!!! This may need to have SetVisibility() called !!!" +// drawSnapper(); +} + +/** + * Hides the snapper options. + */ +/*virtual*/ void Snapper::hideOptions() +{ + if (snapMode == RS2::SnapDist && DIALOGFACTORY) + DIALOGFACTORY->requestSnapDistOptions(distance, false); +} + +/** + * Shows the snapper options. + */ +/*virtual*/ void Snapper::showOptions() +{ + if (snapMode == RS2::SnapDist && DIALOGFACTORY) + DIALOGFACTORY->requestSnapDistOptions(distance, true); +} +#endif