Allow displaying and editing diameter constraints as radius.

The savefile format is not changed; the display option is
stored in Constraint::other.
pull/3/head
whitequark 2015-03-22 16:07:49 +03:00
parent f62e95d7b6
commit 1b69032d99
4 changed files with 63 additions and 19 deletions

View File

@ -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");

View File

@ -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;
}

View File

@ -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));

View File

@ -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);