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]
This commit is contained in:
Jonathan Westhues 2008-04-13 02:57:41 -08:00
parent d76e708c17
commit a0e78e0da2
9 changed files with 352 additions and 123 deletions

View File

@ -143,7 +143,16 @@ done:
} }
void TextWindow::Show(void) { void TextWindow::Show(void) {
if(!(SS.GW.pendingOperation)) SS.GW.pendingDescription = NULL;
ShowHeader(); 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) { switch(shown->screen) {
default: default:
shown->screen = SCREEN_GROUP_LIST; shown->screen = SCREEN_GROUP_LIST;
@ -156,6 +165,7 @@ void TextWindow::Show(void) {
ShowRequestList(); ShowRequestList();
break; break;
} }
}
InvalidateText(); InvalidateText();
} }
@ -192,9 +202,17 @@ void TextWindow::ScreenNavigaton(int link, DWORD v) {
void TextWindow::ShowHeader(void) { void TextWindow::ShowHeader(void) {
ClearScreen(); ClearScreen();
Printf(" %Lb%f<<%E %Lh%fhome%E", 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),
(DWORD)(&TextWindow::ScreenNavigaton)); (DWORD)(&TextWindow::ScreenNavigaton),
SS.group.FindById(SS.GW.activeGroup)->DescriptionString());
}
int datumColor; int datumColor;
if(SS.GW.show2dCsyss && SS.GW.showAxes && SS.GW.showPoints) { if(SS.GW.show2dCsyss && SS.GW.showAxes && SS.GW.showPoints) {

18
dsc.h
View File

@ -78,14 +78,22 @@ public:
} }
T *FindById(H h) { 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; int i;
for(i = 0; i < elems; i++) { for(i = 0; i < elems; i++) {
if(elem[i].t.h.v == h.v) { if(elem[i].t.h.v == h.v) {
return &(elem[i].t); return &(elem[i].t);
} }
} }
dbp("failed to look up item %16lx, searched %d items", h.v, elems); return NULL;
oops();
} }
void ClearTags(void) { void ClearTags(void) {
@ -112,6 +120,12 @@ public:
// and elemsAllocated is untouched, because we didn't resize // and elemsAllocated is untouched, because we didn't resize
} }
void MoveSelfInto(IdList<T,H> *l) {
memcpy(l, this, sizeof(*this));
elemsAllocated = elems = 0;
elem = NULL;
}
void Clear(void) { void Clear(void) {
elemsAllocated = elems = 0; elemsAllocated = elems = 0;
if(elem) free(elem); if(elem) free(elem);

View File

@ -31,7 +31,6 @@ double Entity::GetDistance(Point2d mp) {
} }
void Entity::DrawOrGetDistance(void) { void Entity::DrawOrGetDistance(void) {
if(!visible) return;
switch(type) { switch(type) {
case CSYS_2D: { case CSYS_2D: {
Vector p; Vector p;
@ -45,16 +44,15 @@ void Entity::DrawOrGetDistance(void) {
Vector u = Vector::RotationU(q[0], q[1], q[2], q[3]); Vector u = Vector::RotationU(q[0], q[1], q[2], q[3]);
Vector v = Vector::RotationV(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 us = u.ScaledBy(s);
Vector pm = p.Plus (u).Minus(v); Vector vs = v.ScaledBy(s);
Vector mm = p.Minus(u).Minus(v);
Vector mp = p.Minus(u).Plus (v); Vector pp = p.Plus (us).Plus (vs);
pp = pp.ScaledBy(s); Vector pm = p.Plus (us).Minus(vs);
pm = pm.ScaledBy(s); Vector mm = p.Minus(us).Minus(vs);
mm = mm.ScaledBy(s); Vector mp = p.Minus(us).Plus (vs);
mp = mp.ScaledBy(s);
LineDrawOrGetDistance(pp, pm); LineDrawOrGetDistance(pp, pm);
LineDrawOrGetDistance(pm, mm); LineDrawOrGetDistance(pm, mm);
@ -71,6 +69,17 @@ void Entity::DrawOrGetDistance(void) {
} }
break; 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: default:
oops(); oops();
} }

View File

@ -4,6 +4,8 @@
#define mView (&GraphicsWindow::MenuView) #define mView (&GraphicsWindow::MenuView)
#define mEdit (&GraphicsWindow::MenuEdit) #define mEdit (&GraphicsWindow::MenuEdit)
#define mReq (&GraphicsWindow::MenuRequest)
#define S 0x100
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 0, "&File", 0, NULL }, { 0, "&File", 0, NULL },
{ 1, "&New\tCtrl+N", 0, NULL }, { 1, "&New\tCtrl+N", 0, NULL },
@ -24,17 +26,48 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView }, { 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView },
{ 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView }, { 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView },
{ 1, NULL, 0, NULL }, { 1, NULL, 0, NULL },
{ 1, "Onto Plane/Csys\tO", MNU_ORIENT_ONTO, 'O', mView }, { 1, "&Onto Plane / Coordinate System\tO", MNU_ORIENT_ONTO, 'O', mView },
{ 1, "&Lock Orientation\tL", 0, 'L', mView },
{ 1, NULL, 0, NULL }, { 1, NULL, 0, NULL },
{ 1, "Dimensions in &Inches", 0, NULL }, { 1, "Dimensions in &Inches", 0, NULL },
{ 1, "Dimensions in &Millimeters", 0, NULL }, { 1, "Dimensions in &Millimeters", 0, NULL },
{ 0, "&Sketch", 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, NULL, 0, NULL },
{ 1, "To&ggle Construction\tG", 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 }, { 0, "&Constrain", 0, NULL },
{ 1, "S&ymmetric\tY", 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 }, { 0, "&Help", 0, NULL },
{ 1, "&About\t", 0, NULL }, { 1, "&About\t", 0, NULL },
@ -49,6 +82,8 @@ void GraphicsWindow::Init(void) {
projRight.x = 1; projRight.y = projRight.z = 0; projRight.x = 1; projRight.y = projRight.z = 0;
projUp.y = 1; projUp.z = projUp.x = 0; projUp.y = 1; projUp.z = projUp.x = 0;
EnsureValidActiveGroup();
show2dCsyss = true; show2dCsyss = true;
showAxes = true; showAxes = true;
showPoints = true; showPoints = true;
@ -109,16 +144,62 @@ void GraphicsWindow::MenuView(MenuId id) {
InvalidateGraphics(); 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) { void GraphicsWindow::MenuEdit(MenuId id) {
switch(id) { switch(id) {
case MNU_UNSELECT_ALL: case MNU_UNSELECT_ALL:
SS.GW.ClearSelection(); SS.GW.ClearSelection();
SS.GW.pendingOperation = 0;
SS.GW.pendingDescription = NULL;
SS.TW.Show();
break; break;
default: oops(); 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, void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown) bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown)
{ {
@ -158,9 +239,17 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
orig.mouse.y = y; orig.mouse.y = y;
InvalidateGraphics(); 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 { } else {
// No mouse buttons are pressed. We just need to do our usual hit if(pendingOperation == PENDING_OPERATION_DRAGGING_POINT) {
// testing, to see if anything ought to be hovered. UpdateDraggedPoint(pendingPoint, x, y);
} else {
// Do our usual hit testing, for the selection.
Selection s; Selection s;
HitTestMakeSelection(mp, &s); HitTestMakeSelection(mp, &s);
if(!s.Equals(&hover)) { if(!s.Equals(&hover)) {
@ -169,6 +258,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
} }
} }
} }
}
bool GraphicsWindow::Selection::Equals(Selection *b) { bool GraphicsWindow::Selection::Equals(Selection *b) {
if(point.v != b->point.v) return false; if(point.v != b->point.v) return false;
@ -252,29 +342,77 @@ void GraphicsWindow::MouseMiddleDown(double x, double y) {
orig.mouse.y = y; orig.mouse.y = y;
} }
void GraphicsWindow::MouseLeftDown(double x, double y) { hRequest GraphicsWindow::AddRequest(int type) {
// Make sure the hover is up to date. Request r;
MouseMoved(x, y, false, false, false, false, false); memset(&r, 0, sizeof(r));
r.group = activeGroup;
r.type = type;
SS.request.AddAndAssignId(&r);
SS.GenerateAll();
return r.h;
}
if(!hover.IsEmpty()) { 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; int i;
for(i = 0; i < MAX_SELECTED; i++) { for(i = 0; i < MAX_SELECTED; i++) {
if(selection[i].Equals(&hover)) { if(selection[i].Equals(&hover)) {
selection[i].Clear(); selection[i].Clear();
goto done; break;
} }
} }
if(i != MAX_SELECTED) break;
for(i = 0; i < MAX_SELECTED; i++) { for(i = 0; i < MAX_SELECTED; i++) {
if(selection[i].IsEmpty()) { if(selection[i].IsEmpty()) {
selection[i] = hover; selection[i] = hover;
goto done; break;
} }
} }
// I guess we ran out of slots, oh well. break;
done: }
}
SS.TW.Show();
InvalidateGraphics(); InvalidateGraphics();
} }
}
void GraphicsWindow::MouseScroll(double x, double y, int delta) { void GraphicsWindow::MouseScroll(double x, double y, int delta) {
double offsetRight = offset.Dot(projRight); double offsetRight = offset.Dot(projRight);
@ -302,7 +440,7 @@ void GraphicsWindow::ToggleBool(int link, DWORD v) {
bool *vb = (bool *)v; bool *vb = (bool *)v;
*vb = !*vb; *vb = !*vb;
SS.GenerateForUserInterface(); SS.GenerateAll();
InvalidateGraphics(); InvalidateGraphics();
SS.TW.Show(); SS.TW.Show();
} }
@ -313,7 +451,7 @@ void GraphicsWindow::ToggleAnyDatumShown(int link, DWORD v) {
SS.GW.showAxes = t; SS.GW.showAxes = t;
SS.GW.showPoints = t; SS.GW.showPoints = t;
SS.GenerateForUserInterface(); SS.GenerateAll();
InvalidateGraphics(); InvalidateGraphics();
SS.TW.Show(); SS.TW.Show();
} }

View File

@ -10,9 +10,9 @@ const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 };
char *Group::DescriptionString(void) { char *Group::DescriptionString(void) {
static char ret[100]; static char ret[100];
if(name.str[0]) { if(name.str[0]) {
sprintf(ret, "g%03x-%s", h.v, name.str); sprintf(ret, "g%04x-%s", h.v, name.str);
} else { } else {
sprintf(ret, "g%03x-(unnamed)", h.v); sprintf(ret, "g%04x-(unnamed)", h.v);
} }
return ret; return ret;
} }
@ -30,7 +30,7 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
{ {
int points = 0; int points = 0;
int params = 0; int params = 0;
int type = 0; int et = 0;
int i; int i;
Group *g = SS.group.FindById(group); Group *g = SS.group.FindById(group);
@ -42,11 +42,13 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
bool shown = true; bool shown = true;
switch(type) { switch(type) {
case Request::CSYS_2D: case Request::CSYS_2D:
type = Entity::CSYS_2D; points = 1; params = 4; et = Entity::CSYS_2D; points = 1; params = 4; goto c;
if(!SS.GW.show2dCsyss) shown = false;
goto c; case Request::DATUM_POINT:
et = Entity::DATUM_POINT; points = 1; params = 0; goto c;
case Request::LINE_SEGMENT: 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: { c: {
// Common routines, for all the requests that generate a single // Common routines, for all the requests that generate a single
// entity that's defined by a simple combination of pts and params. // 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 + 0);
AddParam(param, &e, 16 + 3*i + 1); AddParam(param, &e, 16 + 3*i + 1);
} }
pt.visible = shown;
point->Add(&pt); point->Add(&pt);
} }
e.type = type; e.type = et;
e.visible = shown;
entity->Add(&e); entity->Add(&e);
break; break;
} }
@ -130,8 +130,6 @@ Vector Point::GetCoords(void) {
} }
void Point::Draw(void) { void Point::Draw(void) {
if(!visible) return;
Vector v = GetCoords(); Vector v = GetCoords();
double s = 4; double s = 4;
@ -147,8 +145,6 @@ void Point::Draw(void) {
} }
double Point::GetDistance(Point2d mp) { double Point::GetDistance(Point2d mp) {
if(!visible) return 1e12;
Vector v = GetCoords(); Vector v = GetCoords();
Point2d pp = SS.GW.ProjectPoint(v); Point2d pp = SS.GW.ProjectPoint(v);

View File

@ -21,28 +21,36 @@ public:
}; };
class hRequest { class hRequest {
public: public:
// bits 10: 0 -- request index // bits 14: 0 -- request index (the high bits may be used as an import ID)
DWORD v; DWORD v;
inline hEntity entity(int i);
}; };
class hEntity { class hEntity {
public: public:
// bits 10: 0 -- entity index // bits 9: 0 -- entity index
// 21:11 -- request index // 24:10 -- request index
DWORD v; DWORD v;
inline hRequest request(void);
inline hParam param(int i);
inline hPoint point(int i);
}; };
class hParam { class hParam {
public: public:
// bits 7: 0 -- param index // bits 6: 0 -- param index
// 18: 8 -- entity index // 16: 7 -- entity index
// 29:19 -- request index // 31:17 -- request index
DWORD v; DWORD v;
}; };
class hPoint { class hPoint {
// bits 7: 0 -- point index // bits 6: 0 -- point index
// 18: 8 -- entity index // 16: 7 -- entity index
// 29:19 -- request index // 31:17 -- request index
public: public:
DWORD v; DWORD v;
inline bool isFromReferences(void);
}; };
// A set of requests. Every request must have an associated group. A group // A set of requests. Every request must have an associated group. A group
@ -72,7 +80,8 @@ public:
// Types of requests // Types of requests
static const int CSYS_2D = 0; static const int CSYS_2D = 0;
static const int LINE_SEGMENT = 1; static const int DATUM_POINT = 1;
static const int LINE_SEGMENT = 10;
int type; int type;
@ -83,7 +92,7 @@ public:
NameStr name; NameStr name;
inline hEntity entity(int i) 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,hParam> *param, Entity *e, int index); void AddParam(IdList<Param,hParam> *param, Entity *e, int index);
void Generate(IdList<Entity,hEntity> *entity, void Generate(IdList<Entity,hEntity> *entity,
@ -97,22 +106,21 @@ class Entity {
public: public:
static const hEntity NO_CSYS; static const hEntity NO_CSYS;
static const int CSYS_2D = 100; static const int CSYS_2D = 1000;
static const int LINE_SEGMENT = 101; static const int DATUM_POINT = 1001;
static const int LINE_SEGMENT = 1010;
int type; int type;
hEntity h; hEntity h;
bool visible;
Expr *expr[16]; Expr *expr[16];
inline hRequest request(void) 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) 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) 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 { struct {
bool drawing; bool drawing;
@ -145,10 +153,9 @@ public:
static const int BY_EXPR = 2; // three Expr *, could be anything static const int BY_EXPR = 2; // three Expr *, could be anything
hEntity csys; hEntity csys;
bool visible;
inline hEntity entity(void) 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) inline hParam param(int i)
{ hParam r; r.v = h.v + i; return r; } { hParam r; r.v = h.v + i; return r; }
@ -164,4 +171,23 @@ public:
double GetDistance(Point2d mp); 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 #endif

View File

@ -7,9 +7,6 @@ template IdList<Point,hPoint>;
SolveSpace SS; SolveSpace SS;
void SolveSpace::Init(void) { void SolveSpace::Init(void) {
TW.Init();
GW.Init();
request.Clear(); request.Clear();
entity.Clear(); entity.Clear();
point.Clear(); point.Clear();
@ -48,20 +45,32 @@ void SolveSpace::Init(void) {
r.h = Request::HREQUEST_REFERENCE_ZX; r.h = Request::HREQUEST_REFERENCE_ZX;
request.Add(&r); request.Add(&r);
TW.Init();
GW.Init();
TW.Show(); TW.Show();
GenerateForUserInterface(); GenerateAll();
} }
void SolveSpace::GenerateForUserInterface(void) { void SolveSpace::GenerateAll(void) {
int i; int i;
IdList<Param,hParam> prev;
param.MoveSelfInto(&prev);
entity.Clear(); entity.Clear();
param.Clear();
point.Clear(); point.Clear();
for(i = 0; i < request.elems; i++) { for(i = 0; i < request.elems; i++) {
request.elem[i].t.Generate(&entity, &point, &param); request.elem[i].t.Generate(&entity, &point, &param);
} }
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(); ForceReferences();
} }

View File

@ -60,7 +60,7 @@ public:
hGroup activeGroup; hGroup activeGroup;
void GenerateForUserInterface(void); void GenerateAll(void);
void ForceReferences(void); void ForceReferences(void);
void Init(void); void Init(void);

19
ui.h
View File

@ -73,11 +73,15 @@ public:
// This table describes the top-level menus in the graphics winodw. // This table describes the top-level menus in the graphics winodw.
typedef enum { typedef enum {
// View
MNU_ZOOM_IN = 100, MNU_ZOOM_IN = 100,
MNU_ZOOM_OUT, MNU_ZOOM_OUT,
MNU_ZOOM_TO_FIT, MNU_ZOOM_TO_FIT,
MNU_ORIENT_ONTO, MNU_ORIENT_ONTO,
MNU_UNSELECT_ALL, MNU_UNSELECT_ALL,
// Request
MNU_DATUM_POINT,
MNU_LINE_SEGMENT,
} MenuId; } MenuId;
typedef void MenuHandler(MenuId id); typedef void MenuHandler(MenuId id);
typedef struct { typedef struct {
@ -90,6 +94,7 @@ public:
static const MenuEntry menu[]; static const MenuEntry menu[];
static void MenuView(MenuId id); static void MenuView(MenuId id);
static void MenuEdit(MenuId id); static void MenuEdit(MenuId id);
static void MenuRequest(MenuId id);
// The width and height (in pixels) of the window. // The width and height (in pixels) of the window.
double width, height; double width, height;
@ -110,6 +115,18 @@ public:
void NormalizeProjectionVectors(void); void NormalizeProjectionVectors(void);
Point2d ProjectPoint(Vector p); 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. // The current selection.
class Selection { class Selection {
public: public:
@ -146,6 +163,8 @@ public:
static void ToggleBool(int link, DWORD v); static void ToggleBool(int link, DWORD v);
static void ToggleAnyDatumShown(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. // These are called by the platform-specific code.
void Paint(int w, int h); void Paint(int w, int h);
void MouseMoved(double x, double y, bool leftDown, bool middleDown, void MouseMoved(double x, double y, bool leftDown, bool middleDown,