From a0e78e0da2f5b9d325b58076344f1a91cd2003fc Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Sun, 13 Apr 2008 02:57:41 -0800 Subject: [PATCH] Tweak the handles to make more space in the request ID, so that I can use the high bits as an "import ID" for imported parts, for hierarchy (that retains parametric capabilities). Implement enought that I can draw a datum point or a line segment, and drag points around in three-space. Still so much to do. [git-p4: depot-paths = "//depot/solvespace/": change = 1665] --- cmdline.cpp | 46 ++++++--- dsc.h | 18 +++- entity.cpp | 29 ++++-- graphicswin.cpp | 246 +++++++++++++++++++++++++++++++++++++----------- sketch.cpp | 24 ++--- sketch.h | 68 ++++++++----- solvespace.cpp | 21 +++-- solvespace.h | 2 +- ui.h | 21 ++++- 9 files changed, 352 insertions(+), 123 deletions(-) diff --git a/cmdline.cpp b/cmdline.cpp index 9f3595d0..d6b892dd 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -143,18 +143,28 @@ done: } void TextWindow::Show(void) { - ShowHeader(); - switch(shown->screen) { - default: - shown->screen = SCREEN_GROUP_LIST; - // fall through - case SCREEN_GROUP_LIST: - ShowGroupList(); - break; + if(!(SS.GW.pendingOperation)) SS.GW.pendingDescription = NULL; - case SCREEN_REQUEST_LIST: - ShowRequestList(); - break; + ShowHeader(); + + if(SS.GW.pendingDescription) { + // A pending operation (that must be completed with the mouse in + // the graphics window) will preempt our usual display. + Printf(""); + Printf("%s", SS.GW.pendingDescription); + } else { + switch(shown->screen) { + default: + shown->screen = SCREEN_GROUP_LIST; + // fall through + case SCREEN_GROUP_LIST: + ShowGroupList(); + break; + + case SCREEN_REQUEST_LIST: + ShowRequestList(); + break; + } } InvalidateText(); } @@ -192,9 +202,17 @@ void TextWindow::ScreenNavigaton(int link, DWORD v) { void TextWindow::ShowHeader(void) { ClearScreen(); - Printf(" %Lb%f<<%E %Lh%fhome%E", - (DWORD)(&TextWindow::ScreenNavigaton), - (DWORD)(&TextWindow::ScreenNavigaton)); + SS.GW.EnsureValidActiveGroup(); + + if(SS.GW.pendingDescription) { + Printf(""); + } else { + // Navigation buttons + Printf(" %Lb%f<<%E %Lh%fhome%E group:%s", + (DWORD)(&TextWindow::ScreenNavigaton), + (DWORD)(&TextWindow::ScreenNavigaton), + SS.group.FindById(SS.GW.activeGroup)->DescriptionString()); + } int datumColor; if(SS.GW.show2dCsyss && SS.GW.showAxes && SS.GW.showPoints) { diff --git a/dsc.h b/dsc.h index 249fc4cf..ea77cc31 100644 --- a/dsc.h +++ b/dsc.h @@ -78,14 +78,22 @@ public: } T *FindById(H h) { + T *t = FindByIdNoOops(h); + if(!t) { + dbp("failed to look up item %16lx, searched %d items", h.v, elems); + oops(); + } + return t; + } + + T *FindByIdNoOops(H h) { int i; for(i = 0; i < elems; i++) { if(elem[i].t.h.v == h.v) { return &(elem[i].t); } } - dbp("failed to look up item %16lx, searched %d items", h.v, elems); - oops(); + return NULL; } void ClearTags(void) { @@ -112,6 +120,12 @@ public: // and elemsAllocated is untouched, because we didn't resize } + void MoveSelfInto(IdList *l) { + memcpy(l, this, sizeof(*this)); + elemsAllocated = elems = 0; + elem = NULL; + } + void Clear(void) { elemsAllocated = elems = 0; if(elem) free(elem); diff --git a/entity.cpp b/entity.cpp index 55b64223..73a443ea 100644 --- a/entity.cpp +++ b/entity.cpp @@ -31,7 +31,6 @@ double Entity::GetDistance(Point2d mp) { } void Entity::DrawOrGetDistance(void) { - if(!visible) return; switch(type) { case CSYS_2D: { Vector p; @@ -45,16 +44,15 @@ void Entity::DrawOrGetDistance(void) { Vector u = Vector::RotationU(q[0], q[1], q[2], q[3]); Vector v = Vector::RotationV(q[0], q[1], q[2], q[3]); - double s = (min(SS.GW.width, SS.GW.height))*0.4; + double s = (min(SS.GW.width, SS.GW.height))*0.4/SS.GW.scale; - Vector pp = p.Plus (u).Plus (v); - Vector pm = p.Plus (u).Minus(v); - Vector mm = p.Minus(u).Minus(v); - Vector mp = p.Minus(u).Plus (v); - pp = pp.ScaledBy(s); - pm = pm.ScaledBy(s); - mm = mm.ScaledBy(s); - mp = mp.ScaledBy(s); + Vector us = u.ScaledBy(s); + Vector vs = v.ScaledBy(s); + + Vector pp = p.Plus (us).Plus (vs); + Vector pm = p.Plus (us).Minus(vs); + Vector mm = p.Minus(us).Minus(vs); + Vector mp = p.Minus(us).Plus (vs); LineDrawOrGetDistance(pp, pm); LineDrawOrGetDistance(pm, mm); @@ -71,6 +69,17 @@ void Entity::DrawOrGetDistance(void) { } break; } + case DATUM_POINT: + // All display is handled by the generated point. + break; + + case LINE_SEGMENT: { + Vector a = SS.point.FindById(point(16))->GetCoords(); + Vector b = SS.point.FindById(point(16+3))->GetCoords(); + LineDrawOrGetDistance(a, b); + break; + } + default: oops(); } diff --git a/graphicswin.cpp b/graphicswin.cpp index ca75c443..bf7415a5 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -4,40 +4,73 @@ #define mView (&GraphicsWindow::MenuView) #define mEdit (&GraphicsWindow::MenuEdit) +#define mReq (&GraphicsWindow::MenuRequest) +#define S 0x100 const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { -{ 0, "&File", 0, NULL }, -{ 1, "&New\tCtrl+N", 0, NULL }, -{ 1, "&Open...\tCtrl+O", 0, NULL }, -{ 1, "&Save\tCtrl+S", 0, NULL }, -{ 1, "Save &As...", 0, NULL }, -{ 1, NULL, 0, NULL }, -{ 1, "E&xit", 0, NULL }, +{ 0, "&File", 0, NULL }, +{ 1, "&New\tCtrl+N", 0, NULL }, +{ 1, "&Open...\tCtrl+O", 0, NULL }, +{ 1, "&Save\tCtrl+S", 0, NULL }, +{ 1, "Save &As...", 0, NULL }, +{ 1, NULL, 0, NULL }, +{ 1, "E&xit", 0, NULL }, -{ 0, "&Edit", 0, NULL }, -{ 1, "&Undo\tCtrl+Z", 0, NULL }, -{ 1, "&Redo\tCtrl+Y", 0, NULL }, -{ 1, NULL, 0, NULL }, -{ 1, "&Unselect All\tEsc", MNU_UNSELECT_ALL, 27, mEdit }, +{ 0, "&Edit", 0, NULL }, +{ 1, "&Undo\tCtrl+Z", 0, NULL }, +{ 1, "&Redo\tCtrl+Y", 0, NULL }, +{ 1, NULL, 0, NULL }, +{ 1, "&Unselect All\tEsc", MNU_UNSELECT_ALL, 27, mEdit }, -{ 0, "&View", 0, NULL }, -{ 1, "Zoom &In\t+", MNU_ZOOM_IN, '+', mView }, -{ 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView }, -{ 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView }, -{ 1, NULL, 0, NULL }, -{ 1, "Onto Plane/Csys\tO", MNU_ORIENT_ONTO, 'O', mView }, -{ 1, NULL, 0, NULL }, -{ 1, "Dimensions in &Inches", 0, NULL }, -{ 1, "Dimensions in &Millimeters", 0, NULL }, +{ 0, "&View", 0, NULL }, +{ 1, "Zoom &In\t+", MNU_ZOOM_IN, '+', mView }, +{ 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView }, +{ 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView }, +{ 1, NULL, 0, NULL }, +{ 1, "&Onto Plane / Coordinate System\tO", MNU_ORIENT_ONTO, 'O', mView }, +{ 1, "&Lock Orientation\tL", 0, 'L', mView }, +{ 1, NULL, 0, NULL }, +{ 1, "Dimensions in &Inches", 0, NULL }, +{ 1, "Dimensions in &Millimeters", 0, NULL }, -{ 0, "&Sketch", 0, NULL }, -{ 1, NULL, 0, NULL }, -{ 1, "To&ggle Construction\tG", 0, NULL }, +{ 0, "&Request", 0, NULL }, +{ 1, "Datum &Point\tP", MNU_DATUM_POINT, 'P', mReq }, +{ 1, "Datum A&xis\tX", 0, 'X', mReq }, +{ 1, "Datum Pla&ne\tN", 0, 'N', mReq }, +{ 1, "2d Coordinate S&ystem\tY", 0, 'Y', mReq }, +{ 1, NULL, 0, NULL }, +{ 1, "Line &Segment\tS", MNU_LINE_SEGMENT, 'S', mReq }, +{ 1, "&Circle\tC", 0, 'C', mReq }, +{ 1, "&Arc of a Circle\tA", 0, 'A', mReq }, +{ 1, "&Cubic Segment\t3", 0, '3', mReq }, +{ 1, NULL, 0, NULL }, +{ 1, "Boolean &Union\tU", 0, 'U', mReq }, +{ 1, "Boolean &Difference\tD", 0, 'D', mReq }, +{ 1, "Step and Repeat &Translate\tT", 0, 'T', mReq }, +{ 1, "Step and Repeat &Rotate\tR", 0, 'R', mReq }, +{ 1, NULL, 0, NULL }, +{ 1, "Sym&bolic Variable\tB", 0, 'B', mReq }, +{ 1, "&Import From File...\tI", 0, 'I', mReq }, +{ 1, NULL, 0, NULL }, +{ 1, "To&ggle Construction\tG", 0, 'G', NULL }, -{ 0, "&Constrain", 0, NULL }, -{ 1, "S&ymmetric\tY", 0, NULL }, +{ 0, "&Constrain", 0, NULL }, +{ 1, "&Distance / Diameter\tShift+D", 0, 'D'|S, NULL }, +{ 1, "A&ngle\tShift+N", 0, 'N'|S, NULL }, +{ 1, "Other S&upplementary Angle\tShift+U", 0, 'U'|S, NULL }, +{ 1, NULL, 0, NULL }, +{ 1, "&Horizontal\tShift+H", 0, 'H'|S, NULL }, +{ 1, "&Vertical\tShift+V", 0, 'V'|S, NULL }, +{ 1, NULL, 0, NULL }, +{ 1, "Coincident / &On Curve\tShift+O", 0, 'O'|S, NULL }, +{ 1, "E&qual Length / Radius\tShift+Q", 0, 'Q'|S, NULL }, +{ 1, "At &Midpoint\tShift+M", 0, 'M'|S, NULL }, +{ 1, "S&ymmetric\tShift+Y", 0, 'Y'|S, NULL }, +{ 1, NULL, 0, NULL }, +{ 1, "Sym&bolic Equation\tShift+B", 0, 'B'|S, NULL }, -{ 0, "&Help", 0, NULL }, -{ 1, "&About\t", 0, NULL }, + +{ 0, "&Help", 0, NULL }, +{ 1, "&About\t", 0, NULL }, { -1 }, }; @@ -49,6 +82,8 @@ void GraphicsWindow::Init(void) { projRight.x = 1; projRight.y = projRight.z = 0; projUp.y = 1; projUp.z = projUp.x = 0; + EnsureValidActiveGroup(); + show2dCsyss = true; showAxes = true; showPoints = true; @@ -109,16 +144,62 @@ void GraphicsWindow::MenuView(MenuId id) { InvalidateGraphics(); } +void GraphicsWindow::EnsureValidActiveGroup(void) { + Group *g = SS.group.FindByIdNoOops(activeGroup); + if(g && g->h.v != Group::HGROUP_REFERENCES.v) { + return; + } + + int i; + for(i = 0; i < SS.group.elems; i++) { + if(SS.group.elem[i].t.h.v != Group::HGROUP_REFERENCES.v) { + break; + } + } + if(i >= SS.group.elems) oops(); + activeGroup = SS.group.elem[i].t.h; +} + void GraphicsWindow::MenuEdit(MenuId id) { switch(id) { case MNU_UNSELECT_ALL: SS.GW.ClearSelection(); + SS.GW.pendingOperation = 0; + SS.GW.pendingDescription = NULL; + SS.TW.Show(); break; default: oops(); } } +void GraphicsWindow::MenuRequest(MenuId id) { + char *s; + switch(id) { + case MNU_DATUM_POINT: s = "click to place datum point"; goto c; + case MNU_LINE_SEGMENT: s = "click first point of line segment"; goto c; +c: + SS.GW.pendingOperation = id; + SS.GW.pendingDescription = s; + SS.TW.Show(); + break; + + default: oops(); + } +} + +void GraphicsWindow::UpdateDraggedPoint(hPoint hp, double mx, double my) { + Point *p = SS.point.FindById(hp); + Vector pos = p->GetCoords(); + pos = pos.Plus(projRight.ScaledBy((mx - orig.mouse.x)/scale)); + pos = pos.Plus(projUp.ScaledBy((my - orig.mouse.y)/scale)); + p->ForceTo(pos); + + orig.mouse.x = mx; + orig.mouse.y = my; + InvalidateGraphics(); +} + void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown) { @@ -158,14 +239,23 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, orig.mouse.y = y; InvalidateGraphics(); + } else if(leftDown) { + // We are left-dragging. This is often used to drag points. + if(hover.point.v && !hover.point.isFromReferences()) { + ClearSelection(); + UpdateDraggedPoint(hover.point, x, y); + } } else { - // No mouse buttons are pressed. We just need to do our usual hit - // testing, to see if anything ought to be hovered. - Selection s; - HitTestMakeSelection(mp, &s); - if(!s.Equals(&hover)) { - hover = s; - InvalidateGraphics(); + if(pendingOperation == PENDING_OPERATION_DRAGGING_POINT) { + UpdateDraggedPoint(pendingPoint, x, y); + } else { + // Do our usual hit testing, for the selection. + Selection s; + HitTestMakeSelection(mp, &s); + if(!s.Equals(&hover)) { + hover = s; + InvalidateGraphics(); + } } } } @@ -252,28 +342,76 @@ void GraphicsWindow::MouseMiddleDown(double x, double y) { orig.mouse.y = y; } -void GraphicsWindow::MouseLeftDown(double x, double y) { - // Make sure the hover is up to date. - MouseMoved(x, y, false, false, false, false, false); +hRequest GraphicsWindow::AddRequest(int type) { + Request r; + memset(&r, 0, sizeof(r)); + r.group = activeGroup; + r.type = type; + SS.request.AddAndAssignId(&r); + SS.GenerateAll(); + return r.h; +} - if(!hover.IsEmpty()) { - int i; - for(i = 0; i < MAX_SELECTED; i++) { - if(selection[i].Equals(&hover)) { - selection[i].Clear(); - goto done; +void GraphicsWindow::MouseLeftDown(double mx, double my) { + // Make sure the hover is up to date. + MouseMoved(mx, my, false, false, false, false, false); + orig.mouse.x = mx; + orig.mouse.y = my; + + // The current mouse location + Vector v = offset.ScaledBy(-1); + v = v.Plus(projRight.ScaledBy(mx/scale)); + v = v.Plus(projUp.ScaledBy(my/scale)); + + hRequest hr; + switch(pendingOperation) { + case MNU_DATUM_POINT: + hr = AddRequest(Request::DATUM_POINT); + SS.point.FindById(hr.entity(0).point(16))->ForceTo(v); + pendingOperation = 0; + break; + + case MNU_LINE_SEGMENT: + hr = AddRequest(Request::LINE_SEGMENT); + SS.point.FindById(hr.entity(0).point(16))->ForceTo(v); + pendingOperation = PENDING_OPERATION_DRAGGING_POINT; + pendingPoint = hr.entity(0).point(16+3); + SS.point.FindById(pendingPoint)->ForceTo(v); + break; + + case PENDING_OPERATION_DRAGGING_POINT: + pendingOperation = 0; + break; + + case 0: + default: { + pendingOperation = 0; + + if(hover.IsEmpty()) break; + + // If an item is hovered, then by clicking on it, we toggle its + // selection state. + int i; + for(i = 0; i < MAX_SELECTED; i++) { + if(selection[i].Equals(&hover)) { + selection[i].Clear(); + break; + } } - } - for(i = 0; i < MAX_SELECTED; i++) { - if(selection[i].IsEmpty()) { - selection[i] = hover; - goto done; + if(i != MAX_SELECTED) break; + + for(i = 0; i < MAX_SELECTED; i++) { + if(selection[i].IsEmpty()) { + selection[i] = hover; + break; + } } + break; } - // I guess we ran out of slots, oh well. -done: - InvalidateGraphics(); } + + SS.TW.Show(); + InvalidateGraphics(); } void GraphicsWindow::MouseScroll(double x, double y, int delta) { @@ -302,7 +440,7 @@ void GraphicsWindow::ToggleBool(int link, DWORD v) { bool *vb = (bool *)v; *vb = !*vb; - SS.GenerateForUserInterface(); + SS.GenerateAll(); InvalidateGraphics(); SS.TW.Show(); } @@ -313,7 +451,7 @@ void GraphicsWindow::ToggleAnyDatumShown(int link, DWORD v) { SS.GW.showAxes = t; SS.GW.showPoints = t; - SS.GenerateForUserInterface(); + SS.GenerateAll(); InvalidateGraphics(); SS.TW.Show(); } diff --git a/sketch.cpp b/sketch.cpp index 397e933e..959de35d 100644 --- a/sketch.cpp +++ b/sketch.cpp @@ -10,9 +10,9 @@ const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 }; char *Group::DescriptionString(void) { static char ret[100]; if(name.str[0]) { - sprintf(ret, "g%03x-%s", h.v, name.str); + sprintf(ret, "g%04x-%s", h.v, name.str); } else { - sprintf(ret, "g%03x-(unnamed)", h.v); + sprintf(ret, "g%04x-(unnamed)", h.v); } return ret; } @@ -30,7 +30,7 @@ void Request::Generate(IdList *entity, { int points = 0; int params = 0; - int type = 0; + int et = 0; int i; Group *g = SS.group.FindById(group); @@ -42,11 +42,13 @@ void Request::Generate(IdList *entity, bool shown = true; switch(type) { case Request::CSYS_2D: - type = Entity::CSYS_2D; points = 1; params = 4; - if(!SS.GW.show2dCsyss) shown = false; - goto c; + et = Entity::CSYS_2D; points = 1; params = 4; goto c; + + case Request::DATUM_POINT: + et = Entity::DATUM_POINT; points = 1; params = 0; goto c; + case Request::LINE_SEGMENT: - type = Entity::LINE_SEGMENT; points = 2; params = 0; goto c; + et = Entity::LINE_SEGMENT; points = 2; params = 0; goto c; c: { // Common routines, for all the requests that generate a single // entity that's defined by a simple combination of pts and params. @@ -70,12 +72,10 @@ c: { AddParam(param, &e, 16 + 3*i + 0); AddParam(param, &e, 16 + 3*i + 1); } - pt.visible = shown; point->Add(&pt); } - e.type = type; - e.visible = shown; + e.type = et; entity->Add(&e); break; } @@ -130,8 +130,6 @@ Vector Point::GetCoords(void) { } void Point::Draw(void) { - if(!visible) return; - Vector v = GetCoords(); double s = 4; @@ -147,8 +145,6 @@ void Point::Draw(void) { } double Point::GetDistance(Point2d mp) { - if(!visible) return 1e12; - Vector v = GetCoords(); Point2d pp = SS.GW.ProjectPoint(v); diff --git a/sketch.h b/sketch.h index 0f98a38a..6d24337f 100644 --- a/sketch.h +++ b/sketch.h @@ -21,28 +21,36 @@ public: }; class hRequest { public: - // bits 10: 0 -- request index + // bits 14: 0 -- request index (the high bits may be used as an import ID) DWORD v; + + inline hEntity entity(int i); }; class hEntity { public: - // bits 10: 0 -- entity index - // 21:11 -- request index + // bits 9: 0 -- entity index + // 24:10 -- request index DWORD v; + + inline hRequest request(void); + inline hParam param(int i); + inline hPoint point(int i); }; class hParam { public: - // bits 7: 0 -- param index - // 18: 8 -- entity index - // 29:19 -- request index + // bits 6: 0 -- param index + // 16: 7 -- entity index + // 31:17 -- request index DWORD v; }; class hPoint { - // bits 7: 0 -- point index - // 18: 8 -- entity index - // 29:19 -- request index + // bits 6: 0 -- point index + // 16: 7 -- entity index + // 31:17 -- request index public: DWORD v; + + inline bool isFromReferences(void); }; // A set of requests. Every request must have an associated group. A group @@ -71,8 +79,9 @@ public: static const hRequest HREQUEST_REFERENCE_ZX; // Types of requests - static const int CSYS_2D = 0; - static const int LINE_SEGMENT = 1; + static const int CSYS_2D = 0; + static const int DATUM_POINT = 1; + static const int LINE_SEGMENT = 10; int type; @@ -83,7 +92,7 @@ public: NameStr name; inline hEntity entity(int i) - { hEntity r; r.v = ((this->h.v) << 11) | i; return r; } + { hEntity r; r.v = ((this->h.v) << 10) | i; return r; } void AddParam(IdList *param, Entity *e, int index); void Generate(IdList *entity, @@ -97,22 +106,21 @@ class Entity { public: static const hEntity NO_CSYS; - static const int CSYS_2D = 100; - static const int LINE_SEGMENT = 101; + static const int CSYS_2D = 1000; + static const int DATUM_POINT = 1001; + static const int LINE_SEGMENT = 1010; int type; hEntity h; - bool visible; - Expr *expr[16]; inline hRequest request(void) - { hRequest r; r.v = (this->h.v >> 11); return r; } + { hRequest r; r.v = (this->h.v >> 10); return r; } inline hParam param(int i) - { hParam r; r.v = ((this->h.v) << 8) | i; return r; } + { hParam r; r.v = ((this->h.v) << 7) | i; return r; } inline hPoint point(int i) - { hPoint r; r.v = ((this->h.v) << 8) | i; return r; } + { hPoint r; r.v = ((this->h.v) << 7) | i; return r; } struct { bool drawing; @@ -145,10 +153,9 @@ public: static const int BY_EXPR = 2; // three Expr *, could be anything hEntity csys; - bool visible; inline hEntity entity(void) - { hEntity r; r.v = (h.v >> 8); return r; } + { hEntity r; r.v = (h.v >> 7); return r; } inline hParam param(int i) { hParam r; r.v = h.v + i; return r; } @@ -164,4 +171,23 @@ public: double GetDistance(Point2d mp); }; + +inline hEntity hRequest::entity(int i) + { hEntity r; r.v = (v << 10) | i; return r; } + +inline hRequest hEntity::request(void) + { hRequest r; r.v = (v >> 10); return r; } +inline hParam hEntity::param(int i) + { hParam r; r.v = (v << 7) | i; return r; } +inline hPoint hEntity::point(int i) + { hPoint r; r.v = (v << 7) | i; return r; } + +inline bool hPoint::isFromReferences(void) { + DWORD d = v >> 17; + if(d == Request::HREQUEST_REFERENCE_XY.v) return true; + if(d == Request::HREQUEST_REFERENCE_YZ.v) return true; + if(d == Request::HREQUEST_REFERENCE_ZX.v) return true; + return false; +} + #endif diff --git a/solvespace.cpp b/solvespace.cpp index 90ce6d84..6c265d5a 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -7,9 +7,6 @@ template IdList; SolveSpace SS; void SolveSpace::Init(void) { - TW.Init(); - GW.Init(); - request.Clear(); entity.Clear(); point.Clear(); @@ -48,20 +45,32 @@ void SolveSpace::Init(void) { r.h = Request::HREQUEST_REFERENCE_ZX; request.Add(&r); + TW.Init(); + GW.Init(); + TW.Show(); - GenerateForUserInterface(); + GenerateAll(); } -void SolveSpace::GenerateForUserInterface(void) { +void SolveSpace::GenerateAll(void) { int i; + IdList prev; + param.MoveSelfInto(&prev); + entity.Clear(); - param.Clear(); point.Clear(); for(i = 0; i < request.elems; i++) { request.elem[i].t.Generate(&entity, &point, ¶m); } + for(i = 0; i < param.elems; i++) { + Param *p = prev.FindByIdNoOops(param.elem[i].t.h); + if(p) { + param.elem[i].t.val = p->val; + } + } + ForceReferences(); } diff --git a/solvespace.h b/solvespace.h index 6a99a1a7..4d7ab315 100644 --- a/solvespace.h +++ b/solvespace.h @@ -60,7 +60,7 @@ public: hGroup activeGroup; - void GenerateForUserInterface(void); + void GenerateAll(void); void ForceReferences(void); void Init(void); diff --git a/ui.h b/ui.h index 56a56690..5370e6e9 100644 --- a/ui.h +++ b/ui.h @@ -41,7 +41,7 @@ public: void Init(void); void Printf(char *fmt, ...); void ClearScreen(void); - + void Show(void); // State for the screen that we are showing in the text window. @@ -73,11 +73,15 @@ public: // This table describes the top-level menus in the graphics winodw. typedef enum { + // View MNU_ZOOM_IN = 100, MNU_ZOOM_OUT, MNU_ZOOM_TO_FIT, MNU_ORIENT_ONTO, MNU_UNSELECT_ALL, + // Request + MNU_DATUM_POINT, + MNU_LINE_SEGMENT, } MenuId; typedef void MenuHandler(MenuId id); typedef struct { @@ -90,6 +94,7 @@ public: static const MenuEntry menu[]; static void MenuView(MenuId id); static void MenuEdit(MenuId id); + static void MenuRequest(MenuId id); // The width and height (in pixels) of the window. double width, height; @@ -109,6 +114,18 @@ public: void NormalizeProjectionVectors(void); Point2d ProjectPoint(Vector p); + + hGroup activeGroup; + void EnsureValidActiveGroup(); + + // Operations that must be completed by doing something with the mouse + // are noted here. + static const int PENDING_OPERATION_DRAGGING_POINT = 0x0f000000; + hPoint pendingPoint; + int pendingOperation; + char *pendingDescription; + hRequest AddRequest(int type); + // The current selection. class Selection { @@ -146,6 +163,8 @@ public: static void ToggleBool(int link, DWORD v); static void ToggleAnyDatumShown(int link, DWORD v); + void UpdateDraggedPoint(hPoint hp, double mx, double my); + // These are called by the platform-specific code. void Paint(int w, int h); void MouseMoved(double x, double y, bool leftDown, bool middleDown,