From 1b69032d991e461bcce4d1624784d7e5eadfaee2 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 22 Mar 2015 16:07:49 +0300 Subject: [PATCH] Allow displaying and editing diameter constraints as radius. The savefile format is not changed; the display option is stored in Constraint::other. --- src/describescreen.cpp | 24 ++++++++++++++++++++++-- src/drawconstraint.cpp | 41 ++++++++++++++++++++++++----------------- src/mouse.cpp | 14 ++++++++++++++ src/ui.h | 3 +++ 4 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/describescreen.cpp b/src/describescreen.cpp index 1ace25af..952afbf2 100644 --- a/src/describescreen.cpp +++ b/src/describescreen.cpp @@ -41,6 +41,16 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) { SS.ScheduleShowTW(); } +void TextWindow::ScreenConstraintShowAsRadius(int link, uint32_t v) { + hConstraint hc = { v }; + Constraint *c = SK.GetConstraint(hc); + + SS.UndoRemember(); + c->other = !c->other; + + SS.ScheduleShowTW(); +} + void TextWindow::DescribeSelection(void) { Entity *e; Vector p; @@ -291,8 +301,18 @@ void TextWindow::DescribeSelection(void) { } else if(gs.n == 0 && gs.stylables > 0) { Printf(false, "%FtSELECTED:%E comment text"); } else if(gs.n == 0 && gs.constraints == 1) { - Printf(false, "%FtSELECTED:%E %s", - SK.GetConstraint(gs.constraint[0])->DescriptionString()); + Constraint *c = SK.GetConstraint(gs.constraint[0]); + + if(c->type == Constraint::DIAMETER) { + Printf(false, "%FtDIAMETER CONSTRAINT"); + + Printf(true, " %Fd%f%D%Ll%c show as radius", + &ScreenConstraintShowAsRadius, gs.constraint[0], + c->other ? CHECK_TRUE : CHECK_FALSE); + } else { + Printf(false, "%FtSELECTED:%E %s", + c->DescriptionString()); + } } else { int n = SS.GW.selection.n; Printf(false, "%FtSELECTED:%E %d item%s", n, n == 1 ? "" : "s"); diff --git a/src/drawconstraint.cpp b/src/drawconstraint.cpp index da2e9990..77170ff8 100644 --- a/src/drawconstraint.cpp +++ b/src/drawconstraint.cpp @@ -66,8 +66,12 @@ char *Constraint::Label(void) { } else if(type == COMMENT) { strcpy(Ret, comment.str); } else if(type == DIAMETER) { - // leading spaces for diameter symbol - sprintf(Ret, " %s", SS.MmToString(valA)); + if(!other) { + // leading spaces for diameter symbol + sprintf(Ret, " %s", SS.MmToString(valA)); + } else { + sprintf(Ret, "R%s", SS.MmToString(valA / 2)); + } } else { // valA has units of distance strcpy(Ret, SS.MmToString(fabs(valA))); @@ -521,27 +525,30 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) { DoLabel(ref, &topLeft, gr, gu); if(labelPos) *labelPos = topLeft; - // Draw the diameter symbol - Vector dc = topLeft; - dc = dc.Plus(gu.WithMagnitude(5/SS.GW.scale)); - dc = dc.Plus(gr.WithMagnitude(9/SS.GW.scale)); - double dr = 5/SS.GW.scale; - double theta, dtheta = (2*PI)/12; - for(theta = 0; theta < 2*PI-0.01; theta += dtheta) { + // Show this as diameter or radius? + if(!other) { + // Draw the diameter symbol + Vector dc = topLeft; + dc = dc.Plus(gu.WithMagnitude(5/SS.GW.scale)); + dc = dc.Plus(gr.WithMagnitude(9/SS.GW.scale)); + double dr = 5/SS.GW.scale; + double theta, dtheta = (2*PI)/12; + for(theta = 0; theta < 2*PI-0.01; theta += dtheta) { + LineDrawOrGetDistance( + dc.Plus(gu.WithMagnitude(cos(theta)*dr)).Plus( + gr.WithMagnitude(sin(theta)*dr)), + dc.Plus(gu.WithMagnitude(cos(theta+dtheta)*dr)).Plus( + gr.WithMagnitude(sin(theta+dtheta)*dr))); + } + theta = 25*(PI/180); + dr *= 1.7; + dtheta = PI; LineDrawOrGetDistance( dc.Plus(gu.WithMagnitude(cos(theta)*dr)).Plus( gr.WithMagnitude(sin(theta)*dr)), dc.Plus(gu.WithMagnitude(cos(theta+dtheta)*dr)).Plus( gr.WithMagnitude(sin(theta+dtheta)*dr))); } - theta = 25*(PI/180); - dr *= 1.7; - dtheta = PI; - LineDrawOrGetDistance( - dc.Plus(gu.WithMagnitude(cos(theta)*dr)).Plus( - gr.WithMagnitude(sin(theta)*dr)), - dc.Plus(gu.WithMagnitude(cos(theta+dtheta)*dr)).Plus( - gr.WithMagnitude(sin(theta+dtheta)*dr))); break; } diff --git a/src/mouse.cpp b/src/mouse.cpp index ef8a4afa..08cbf72b 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -1157,6 +1157,11 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) { default: { double v = fabs(c->valA); + + // If displayed as radius, also edit as radius. + if(c->type == Constraint::DIAMETER && c->other) + v /= 2; + char *def = SS.MmToString(v); double eps = 1e-12; if(fabs(SS.StringToMm(def) - v) < eps) { @@ -1217,6 +1222,15 @@ void GraphicsWindow::EditControlDone(const char *s) { c->valA = fabs(e->Eval()); break; + case Constraint::DIAMETER: + c->valA = fabs(SS.ExprToMm(e)); + + // If displayed and edited as radius, convert back + // to diameter + if(c->other) + c->valA *= 2; + break; + default: // These are always positive, and they get the units conversion. c->valA = fabs(SS.ExprToMm(e)); diff --git a/src/ui.h b/src/ui.h index f176219d..0dc299f8 100644 --- a/src/ui.h +++ b/src/ui.h @@ -236,6 +236,9 @@ public: static void ScreenSetTtfFont(int link, uint32_t v); static void ScreenUnselectAll(int link, uint32_t v); + // when we're describing a constraint + static void ScreenConstraintShowAsRadius(int link, uint32_t v); + // and the rest from the stuff in textscreens.cpp static void ScreenSelectGroup(int link, uint32_t v); static void ScreenActivateGroup(int link, uint32_t v);