From ba8ac7dcd3b19044d3ce3321f8988ffc3b85ac17 Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Sun, 3 Jan 2010 16:35:28 -0800 Subject: [PATCH] Add a screen to edit the view parameters; scale, translation, rotation. Also clean up the handling of units, by putting the conversion factors in only one place, and clean up the expression-parsing but removing all the copies of the same error message. [git-p4: depot-paths = "//depot/solvespace/": change = 2093] --- Makefile | 1 + confscreen.cpp | 11 ++--- draw.cpp | 15 +++++-- expr.cpp | 5 ++- expr.h | 2 +- graphicswin.cpp | 2 + mouse.cpp | 42 ++++++++++++------- solvespace.cpp | 26 +++++++----- solvespace.h | 7 ++++ style.cpp | 37 ++++++---------- textscreens.cpp | 41 ++++++++++-------- textwin.cpp | 1 + ui.h | 16 +++++-- view.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ wishlist.txt | 2 - 15 files changed, 232 insertions(+), 85 deletions(-) create mode 100644 view.cpp diff --git a/Makefile b/Makefile index 3412c30a..b5e15249 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ SSOBJS = $(OBJDIR)\solvespace.obj \ $(OBJDIR)\graphicswin.obj \ $(OBJDIR)\modify.obj \ $(OBJDIR)\clipboard.obj \ + $(OBJDIR)\view.obj \ $(OBJDIR)\util.obj \ $(OBJDIR)\style.obj \ $(OBJDIR)\entity.obj \ diff --git a/confscreen.cpp b/confscreen.cpp index 77c9d71f..8de4a719 100644 --- a/confscreen.cpp +++ b/confscreen.cpp @@ -317,7 +317,7 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) { break; } case EDIT_EXPORT_SCALE: { - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(e) { double ev = e->Eval(); if(fabs(ev) < 0.001 || isnan(ev)) { @@ -325,13 +325,11 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) { } else { SS.exportScale = (float)ev; } - } else { - Error("Not a valid number or expression: '%s'", s); } break; } case EDIT_EXPORT_OFFSET: { - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(e) { double ev = SS.ExprToMm(e); if(isnan(ev) || ev < 0) { @@ -339,15 +337,12 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) { } else { SS.exportOffset = (float)ev; } - } else { - Error("Not a valid number or expression: '%s'", s); } break; } case EDIT_CANVAS_SIZE: { - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(!e) { - Error("Not a valid number or expression: '%s'", s); break; } float d = (float)SS.ExprToMm(e); diff --git a/draw.cpp b/draw.cpp index 183f224e..d4e5b210 100644 --- a/draw.cpp +++ b/draw.cpp @@ -429,7 +429,16 @@ Vector GraphicsWindow::UnProjectPoint(Point2d p) { } void GraphicsWindow::NormalizeProjectionVectors(void) { + if(projRight.Magnitude() < LENGTH_EPS) { + projRight = Vector::From(1, 0, 0); + } + Vector norm = projRight.Cross(projUp); + // If projRight and projUp somehow ended up parallel, then pick an + // arbitrary projUp normal to projRight. + if(norm.Magnitude() < LENGTH_EPS) { + norm = projRight.Normal(0); + } projUp = norm.Cross(projRight); projUp = projUp.WithMagnitude(1); @@ -762,12 +771,12 @@ nogrid:; glEnd(); } - if(pending.drawLine) { + if(SS.extraLine.draw) { glLineWidth(1); glxLockColorTo(Style::Color(Style::DATUM)); glBegin(GL_LINES); - glxVertex3v(pending.lnA); - glxVertex3v(pending.lnB); + glxVertex3v(SS.extraLine.ptA); + glxVertex3v(SS.extraLine.ptB); glEnd(); } diff --git a/expr.cpp b/expr.cpp index 6c046010..fe9df8e6 100644 --- a/expr.cpp +++ b/expr.cpp @@ -763,7 +763,7 @@ void Expr::Lex(char *in) { } } -Expr *Expr::From(char *in) { +Expr *Expr::From(char *in, bool popUpError) { UnparsedCnt = 0; UnparsedP = 0; OperandsP = 0; @@ -776,6 +776,9 @@ Expr *Expr::From(char *in) { r = PopOperand(); } catch (char *e) { dbp("exception: parse/lex error: %s", e); + if(popUpError) { + Error("Not a valid number or expression: '%s'", in); + } return NULL; } return r; diff --git a/expr.h b/expr.h index 06f47b2d..6e4564bb 100644 --- a/expr.h +++ b/expr.h @@ -105,7 +105,7 @@ public: Expr *DeepCopyWithParamsAsPointers(IdList *firstTry, IdList *thenTry); - static Expr *From(char *in); + static Expr *From(char *in, bool popUpError); static void Lex(char *in); static Expr *Next(void); static void Consume(void); diff --git a/graphicswin.cpp b/graphicswin.cpp index 82547411..a733ac3b 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -342,6 +342,7 @@ void GraphicsWindow::MenuView(int id) { case MNU_ZOOM_TO_FIT: SS.GW.ZoomToFit(false); + SS.later.showTW = true; break; case MNU_SHOW_GRID: @@ -521,6 +522,7 @@ void GraphicsWindow::EnsureValidActives(void) { break; default: SS.viewUnits = SolveSpace::UNIT_MM; + break; } CheckMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpace::UNIT_MM); CheckMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpace::UNIT_INCHES); diff --git a/mouse.cpp b/mouse.cpp index 8b8bbabd..8939a74a 100644 --- a/mouse.cpp +++ b/mouse.cpp @@ -79,7 +79,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, if(GraphicsEditControlIsVisible()) return; if(context.active) return; - pending.drawLine = false; + SS.extraLine.draw = false; if(!orig.mouseDown) { // If someone drags the mouse into our window with the left button @@ -133,9 +133,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, } else if(ctrlDown) { double theta = atan2(orig.mouse.y, orig.mouse.x); theta -= atan2(y, x); - pending.drawLine = true; - pending.lnA = UnProjectPoint(Point2d::From(0, 0)); - pending.lnB = UnProjectPoint(mp); + SS.extraLine.draw = true; + SS.extraLine.ptA = UnProjectPoint(Point2d::From(0, 0)); + SS.extraLine.ptB = UnProjectPoint(mp); Vector normal = orig.projRight.Cross(orig.projUp); projRight = orig.projRight.RotatedAbout(normal, theta); @@ -154,7 +154,13 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, orig.mouse.x = x; orig.mouse.y = y; + if(SS.TW.shown.screen == TextWindow::SCREEN_EDIT_VIEW) { + if(havePainted) { + SS.later.showTW = true; + } + } InvalidateGraphics(); + havePainted = false; return; } @@ -246,9 +252,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, // no sense solving a frame and not displaying it. if(!havePainted) { if(pending.operation == DRAGGING_POINTS && ctrlDown) { - pending.lnA = UnProjectPoint(orig.mouseOnButtonDown); - pending.lnB = UnProjectPoint(mp); - pending.drawLine = true; + SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown); + SS.extraLine.ptB = UnProjectPoint(mp); + SS.extraLine.draw = true; } return; } @@ -293,9 +299,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, Vector gn = projRight.Cross(projUp); qt = Quaternion::From(gn, -theta); - pending.drawLine = true; - pending.lnA = UnProjectPoint(orig.mouseOnButtonDown); - pending.lnB = UnProjectPoint(mp); + SS.extraLine.draw = true; + SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown); + SS.extraLine.ptB = UnProjectPoint(mp); } else { double dx = -(x - orig.mouse.x); double dy = -(y - orig.mouse.y); @@ -312,9 +318,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, if(e->type != Entity::POINT_N_ROT_TRANS) { if(ctrlDown) { Vector p = e->PointGetNum(); - p = p.Minus(pending.lnA); + p = p.Minus(SS.extraLine.ptA); p = qt.Rotate(p); - p = p.Plus(pending.lnA); + p = p.Plus(SS.extraLine.ptA); e->PointForceTo(p); SS.MarkGroupDirtyByEntity(e->h); } @@ -478,7 +484,7 @@ void GraphicsWindow::ContextMenuListStyles(void) { } void GraphicsWindow::MouseRightUp(double x, double y) { - pending.drawLine = false; + SS.extraLine.draw = false; InvalidateGraphics(); // Don't show a context menu if the user is right-clicking the toolbar, @@ -1134,7 +1140,7 @@ void GraphicsWindow::EditControlDone(char *s) { return; } - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(e) { SS.UndoRemember(); @@ -1167,8 +1173,6 @@ void GraphicsWindow::EditControlDone(char *s) { } SS.MarkGroupDirty(c->group); SS.GenerateAll(); - } else { - Error("Not a valid number or expression: '%s'", s); } } @@ -1201,6 +1205,12 @@ void GraphicsWindow::MouseScroll(double x, double y, int delta) { offset = offset.Plus(projRight.ScaledBy(rightf - righti)); offset = offset.Plus(projUp.ScaledBy(upf - upi)); + if(SS.TW.shown.screen == TextWindow::SCREEN_EDIT_VIEW) { + if(havePainted) { + SS.later.showTW = true; + } + } + havePainted = false; InvalidateGraphics(); } diff --git a/solvespace.cpp b/solvespace.cpp index 377e9f9d..2e8eb5a7 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -199,6 +199,20 @@ void SolveSpace::DoLater(void) { ZERO(&later); } +double SolveSpace::MmPerUnit(void) { + if(viewUnits == UNIT_INCHES) { + return 25.4; + } else { + return 1.0; + } +} +char *SolveSpace::UnitName(void) { + if(viewUnits == UNIT_INCHES) { + return "inch"; + } else { + return "mm"; + } +} char *SolveSpace::MmToString(double v) { static int WhichBuf; static char Bufs[8][128]; @@ -215,18 +229,10 @@ char *SolveSpace::MmToString(double v) { return s; } double SolveSpace::ExprToMm(Expr *e) { - if(viewUnits == UNIT_INCHES) { - return (e->Eval())*25.4; - } else { - return e->Eval(); - } + return (e->Eval()) * MmPerUnit(); } double SolveSpace::StringToMm(char *str) { - if(viewUnits == UNIT_INCHES) { - return atof(str)*25.4; - } else { - return atof(str); - } + return atof(str) * MmPerUnit(); } double SolveSpace::ChordTolMm(void) { return SS.chordTol / SS.GW.scale; diff --git a/solvespace.h b/solvespace.h index 139bbea4..c281f323 100644 --- a/solvespace.h +++ b/solvespace.h @@ -609,6 +609,8 @@ public: char *MmToString(double v); double ExprToMm(Expr *e); double StringToMm(char *s); + char *UnitName(void); + double MmPerUnit(void); double ChordTolMm(void); bool forceParallelProj; double CameraTangent(void); @@ -677,6 +679,11 @@ public: hEntity point; } traced; SEdgeList nakedEdges; + struct { + bool draw; + Vector ptA; + Vector ptB; + } extraLine; struct { BYTE *fromFile; int w, h; diff --git a/style.cpp b/style.cpp index f3bd5aa0..372e5f69 100644 --- a/style.cpp +++ b/style.cpp @@ -404,9 +404,7 @@ err: void TextWindow::ScreenChangeBackgroundImageScale(int link, DWORD v) { char str[300]; - sprintf(str, "%.3f", - (SS.viewUnits == SolveSpace::UNIT_MM) ? SS.bgImage.scale : - SS.bgImage.scale * 25.4); + sprintf(str, "%.3f", SS.bgImage.scale * SS.MmPerUnit()); SS.TW.edit.meaning = EDIT_BACKGROUND_IMG_SCALE; ShowTextEditControl(v, 10, str); } @@ -443,15 +441,12 @@ void TextWindow::ShowListOfStyles(void) { if(SS.bgImage.fromFile) { Printf(false, "%Ba %Ftwidth:%E %dpx %Ftheight:%E %dpx", SS.bgImage.w, SS.bgImage.h); - if(SS.viewUnits == SolveSpace::UNIT_MM) { - Printf(false, " %Ftscale:%E %# px/mm %Fl%Ll%f%D[change]%E", - SS.bgImage.scale, - &ScreenChangeBackgroundImageScale, top[rows-1] + 2); - } else { - Printf(false, " %Ftscale:%E %# px/inch %Fl%Ll%f%D[change]%E", - SS.bgImage.scale*25.4, - &ScreenChangeBackgroundImageScale, top[rows-1] + 2); - } + + Printf(false, " %Ftscale:%E %# px/%s %Fl%Ll%f%D[change]%E", + SS.bgImage.scale*SS.MmPerUnit(), + SS.UnitName(), + &ScreenChangeBackgroundImageScale, top[rows-1] + 2); + Printf(false, "%Ba %Fl%Lc%fclear background image%E", &ScreenBackgroundImage); } else { @@ -682,18 +677,14 @@ bool TextWindow::EditControlDoneForStyles(char *str) { break; case EDIT_BACKGROUND_IMG_SCALE: { - Expr *e = Expr::From(str); + Expr *e = Expr::From(str, true); if(e) { double ev = e->Eval(); if(ev < 0.001 || isnan(ev)) { Error("Scale must not be zero or negative!"); } else { - SS.bgImage.scale = - (SS.viewUnits == SolveSpace::UNIT_MM) ? ev : - ev / 25.4; + SS.bgImage.scale = ev / SS.MmPerUnit(); } - } else { - Error("Not a valid number or expression: '%s'", str); } break; } @@ -722,8 +713,6 @@ void TextWindow::ShowStyleInfo(void) { REDf(s->color), GREENf(s->color), BLUEf(s->color), s->h.v, ScreenChangeStyleColor); - char *unit = (SS.viewUnits == SolveSpace::UNIT_INCHES) ? "inches" : "mm"; - // The line width, and its units if(s->widthAs == Style::UNITS_AS_PIXELS) { Printf(true, "%FtLINE WIDTH %E%@ %D%f%Lp%Fl[change]%E", @@ -747,8 +736,8 @@ void TextWindow::ShowStyleInfo(void) { ( widthpx ? "" : "pixels"), ( widthpx ? "pixels" : ""), s->h.v, &ScreenChangeStyleYesNo, - (!widthpx ? "" : unit), - (!widthpx ? unit : "")); + (!widthpx ? "" : SS.UnitName()), + (!widthpx ? SS.UnitName() : "")); } if(s->h.v >= Style::FIRST_CUSTOM) { @@ -793,8 +782,8 @@ void TextWindow::ShowStyleInfo(void) { ( textHeightpx ? "" : "pixels"), ( textHeightpx ? "pixels" : ""), s->h.v, &ScreenChangeStyleYesNo, - (!textHeightpx ? "" : unit), - (!textHeightpx ? unit : "")); + (!textHeightpx ? "" : SS.UnitName()), + (!textHeightpx ? SS.UnitName() : "")); } if(s->h.v >= Style::FIRST_CUSTOM) { diff --git a/textscreens.cpp b/textscreens.cpp index a2e96f17..8d66ecc6 100644 --- a/textscreens.cpp +++ b/textscreens.cpp @@ -100,6 +100,9 @@ void TextWindow::ScreenHowGroupSolved(int link, DWORD v) { void TextWindow::ScreenShowConfiguration(int link, DWORD v) { SS.TW.GoToScreen(SCREEN_CONFIGURATION); } +void TextWindow::ScreenShowEditView(int link, DWORD v) { + SS.TW.GoToScreen(SCREEN_EDIT_VIEW); +} void TextWindow::ScreenGoToWebsite(int link, DWORD v) { OpenWebsite("http://solvespace.com/txtlink"); } @@ -143,8 +146,11 @@ void TextWindow::ShowListOfGroups(void) { Printf(true, " %Fl%Ls%fshow all%E / %Fl%Lh%fhide all%E", &(TextWindow::ScreenShowGroupsSpecial), &(TextWindow::ScreenShowGroupsSpecial)); - Printf(true, " %Fl%Ls%fline styles%E / %Fl%Ls%fconfiguration%E", + Printf(true, " %Fl%Ls%fline styles%E /" + " %Fl%Ls%fview%E /" + " %Fl%Ls%fconfiguration%E", &(TextWindow::ScreenShowListOfStyles), + &(TextWindow::ScreenShowEditView), &(TextWindow::ScreenShowConfiguration)); // Show license info @@ -674,10 +680,11 @@ void TextWindow::ShowStepDimension(void) { void TextWindow::ShowMeshVolume(void) { Printf(true, "%FtMESH VOLUME"); - if(SS.viewUnits == SolveSpace::UNIT_INCHES) { - Printf(true, " %3 in^3", shown.volume/(25.4*25.4*25.4)); - } else { - Printf(true, " %2 mm^3", shown.volume); + Printf(true, " %3 %s^3", + shown.volume / pow(SS.MmPerUnit(), 3), + SS.UnitName()); + + if(SS.viewUnits == SolveSpace::UNIT_MM) { Printf(false, " %2 mL", shown.volume/(10*10*10)); } @@ -688,9 +695,11 @@ void TextWindow::ShowMeshVolume(void) { // The edit control is visible, and the user just pressed enter. //----------------------------------------------------------------------------- void TextWindow::EditControlDone(char *s) { + edit.showAgain = false; + switch(edit.meaning) { case EDIT_TIMES_REPEATED: { - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(e) { SS.UndoRemember(); @@ -721,8 +730,6 @@ void TextWindow::EditControlDone(char *s) { SS.MarkGroupDirty(g->h); SS.later.generateAll = true; - } else { - Error("Not a valid number or expression: '%s'", s); } break; } @@ -738,7 +745,7 @@ void TextWindow::EditControlDone(char *s) { break; } case EDIT_GROUP_SCALE: { - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(e) { double ev = e->Eval(); if(fabs(ev) < 1e-6) { @@ -749,8 +756,6 @@ void TextWindow::EditControlDone(char *s) { SS.MarkGroupDirty(g->h); SS.later.generateAll = true; } - } else { - Error("Not a valid number or expression: '%s'", s); } break; } @@ -759,9 +764,8 @@ void TextWindow::EditControlDone(char *s) { case EDIT_HELIX_DRADIUS: { SS.UndoRemember(); Group *g = SK.GetGroup(edit.group); - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(!e) { - Error("Not a valid number or expression: '%s'", s); break; } if(edit.meaning == EDIT_HELIX_TURNS) { @@ -786,9 +790,8 @@ void TextWindow::EditControlDone(char *s) { break; } case EDIT_STEP_DIM_FINISH: { - Expr *e = Expr::From(s); + Expr *e = Expr::From(s, true); if(!e) { - Error("Not a valid number or expression: '%s'", s); break; } if(shown.dimIsDistance) { @@ -807,6 +810,7 @@ void TextWindow::EditControlDone(char *s) { if(EditControlDoneForStyles(s)) cnt++; if(EditControlDoneForConfiguration(s)) cnt++; if(EditControlDoneForPaste(s)) cnt++; + if(EditControlDoneForView(s)) cnt++; if(cnt > 1) { // The identifiers were somehow assigned not uniquely? oops(); @@ -816,7 +820,10 @@ void TextWindow::EditControlDone(char *s) { } InvalidateGraphics(); SS.later.showTW = true; - HideTextEditControl(); - edit.meaning = EDIT_NOTHING; + + if(!edit.showAgain) { + HideTextEditControl(); + edit.meaning = EDIT_NOTHING; + } } diff --git a/textwin.cpp b/textwin.cpp index ea8bf6e5..d1140d73 100644 --- a/textwin.cpp +++ b/textwin.cpp @@ -238,6 +238,7 @@ void TextWindow::Show(void) { case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break; case SCREEN_STYLE_INFO: ShowStyleInfo(); break; case SCREEN_PASTE_TRANSFORMED: ShowPasteTransformed(); break; + case SCREEN_EDIT_VIEW: ShowEditView(); break; } } Printf(false, ""); diff --git a/ui.h b/ui.h index 31b38218..c57e1bdc 100644 --- a/ui.h +++ b/ui.h @@ -55,6 +55,7 @@ public: static const int SCREEN_LIST_OF_STYLES = 6; static const int SCREEN_STYLE_INFO = 7; static const int SCREEN_PASTE_TRANSFORMED = 8; + static const int SCREEN_EDIT_VIEW = 9; typedef struct { int screen; @@ -116,7 +117,13 @@ public: static const int EDIT_PASTE_TIMES_REPEATED = 60; static const int EDIT_PASTE_ANGLE = 61; static const int EDIT_PASTE_SCALE = 62; + // For view + static const int EDIT_VIEW_SCALE = 70; + static const int EDIT_VIEW_ORIGIN = 71; + static const int EDIT_VIEW_PROJ_RIGHT = 72; + static const int EDIT_VIEW_PROJ_UP = 73; struct { + bool showAgain; int meaning; int i; hGroup group; @@ -140,6 +147,7 @@ public: void ShowStepDimension(void); void ShowMeshVolume(void); void ShowPasteTransformed(void); + void ShowEditView(void); // Special screen, based on selection void DescribeSelection(void); @@ -179,6 +187,7 @@ public: static void ScreenBackgroundImage(int link, DWORD v); static void ScreenShowConfiguration(int link, DWORD v); + static void ScreenShowEditView(int link, DWORD v); static void ScreenGoToWebsite(int link, DWORD v); static void ScreenChangeFixExportColors(int link, DWORD v); @@ -217,10 +226,14 @@ public: static void ScreenChangeBackgroundColor(int link, DWORD v); static void ScreenChangeBackgroundImageScale(int link, DWORD v); static void ScreenChangePasteTransformed(int link, DWORD v); + static void ScreenChangeViewScale(int link, DWORD v); + static void ScreenChangeViewOrigin(int link, DWORD v); + static void ScreenChangeViewProjection(int link, DWORD v); bool EditControlDoneForStyles(char *s); bool EditControlDoneForConfiguration(char *s); bool EditControlDoneForPaste(char *s); + bool EditControlDoneForView(char *s); void EditControlDone(char *s); }; @@ -413,9 +426,6 @@ public: hEntity normal; hConstraint constraint; - bool drawLine; - Vector lnA, lnB; - char *description; } pending; void ClearPending(void); diff --git a/view.cpp b/view.cpp new file mode 100644 index 00000000..fd247662 --- /dev/null +++ b/view.cpp @@ -0,0 +1,109 @@ +#include "solvespace.h" + +void TextWindow::ShowEditView(void) { + Printf(true, "%Ft3D VIEW PARAMETERS%E"); + + Printf(true, "%Bd %Ftoverall scale factor%E"); + Printf(false, "%Ba %# px/%s %Fl%Ll%f[edit]%E", + SS.GW.scale * SS.MmPerUnit(), + SS.UnitName(), + &ScreenChangeViewScale); + Printf(false, ""); + + Printf(false, "%Bd %Ftorigin (maps to center of screen)%E"); + Printf(false, "%Ba (%s, %s, %s) %Fl%Ll%f[edit]%E", + SS.MmToString(-SS.GW.offset.x), + SS.MmToString(-SS.GW.offset.y), + SS.MmToString(-SS.GW.offset.z), + &ScreenChangeViewOrigin); + Printf(false, ""); + + Vector n = (SS.GW.projRight).Cross(SS.GW.projUp); + Printf(false, "%Bd %Ftprojection onto screen%E"); + Printf(false, "%Ba %Ftright%E (%3, %3, %3) %Fl%Ll%f[edit]%E", + CO(SS.GW.projRight), + &ScreenChangeViewProjection); + Printf(false, "%Ba %Ftup%E (%3, %3, %3)", CO(SS.GW.projUp)); + Printf(false, "%Ba %Ftout%E (%3, %3, %3)", CO(n)); + Printf(false, ""); + + Printf(false, "The perspective may be changed in the"); + Printf(false, "configuration screen."); +} + +void TextWindow::ScreenChangeViewScale(int link, DWORD v) { + char buf[1024]; + sprintf(buf, "%.3f", SS.GW.scale * SS.MmPerUnit()); + + SS.TW.edit.meaning = EDIT_VIEW_SCALE; + ShowTextEditControl(12, 3, buf); +} + +void TextWindow::ScreenChangeViewOrigin(int link, DWORD v) { + char buf[1024]; + sprintf(buf, "%s, %s, %s", + SS.MmToString(-SS.GW.offset.x), + SS.MmToString(-SS.GW.offset.y), + SS.MmToString(-SS.GW.offset.z)); + + SS.TW.edit.meaning = EDIT_VIEW_ORIGIN; + ShowTextEditControl(18, 3, buf); +} + +void TextWindow::ScreenChangeViewProjection(int link, DWORD v) { + char buf[1024]; + sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projRight)); + SS.TW.edit.meaning = EDIT_VIEW_PROJ_RIGHT; + ShowTextEditControl(24, 10, buf); +} + +bool TextWindow::EditControlDoneForView(char *s) { + switch(edit.meaning) { + case EDIT_VIEW_SCALE: { + Expr *e = Expr::From(s, true); + if(e) { + SS.GW.scale = e->Eval() / SS.MmPerUnit(); + } + break; + } + + case EDIT_VIEW_ORIGIN: { + Vector pt; + if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) { + pt = pt.ScaledBy(SS.MmPerUnit()); + SS.GW.offset = pt.ScaledBy(-1); + } else { + Error("Bad format: specify x, y, z"); + } + break; + } + + case EDIT_VIEW_PROJ_RIGHT: + case EDIT_VIEW_PROJ_UP: { + Vector pt; + if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) { + Error("Bad format: specify x, y, z"); + break; + } + if(edit.meaning == EDIT_VIEW_PROJ_RIGHT) { + SS.GW.projRight = pt; + SS.GW.NormalizeProjectionVectors(); + edit.meaning = EDIT_VIEW_PROJ_UP; + char buf[1024]; + sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projUp)); + HideTextEditControl(); + ShowTextEditControl(26, 10, buf); + edit.showAgain = true; + } else { + SS.GW.projUp = pt; + SS.GW.NormalizeProjectionVectors(); + } + break; + } + + default: + return false; + } + return true; +} + diff --git a/wishlist.txt b/wishlist.txt index 7fb36790..339bf0d3 100644 --- a/wishlist.txt +++ b/wishlist.txt @@ -1,6 +1,4 @@ -show and modify view parameters (translate, rotate, scale) - ----- associative entities from solid model, as a special group some kind of import