Now I can display the edit control in the graphics window, and edit

the label associated with a constraint. And that even works,
changes the length of the line.

[git-p4: depot-paths = "//depot/solvespace/": change = 1678]
solver
Jonathan Westhues 2008-04-21 02:12:04 -08:00
parent 2926fa95d9
commit 9b1b255e85
8 changed files with 135 additions and 16 deletions

View File

@ -25,7 +25,7 @@ void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
} }
} }
void Constraint::DrawOrGetDistance(void) { void Constraint::DrawOrGetDistance(Vector *labelPos) {
if(!SS.GW.showConstraints) return; if(!SS.GW.showConstraints) return;
// Unit vectors that describe our current view of the scene. // Unit vectors that describe our current view of the scene.
@ -40,6 +40,7 @@ void Constraint::DrawOrGetDistance(void) {
Vector bp = SS.GetEntity(ptB)->PointGetCoords(); Vector bp = SS.GetEntity(ptB)->PointGetCoords();
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset); Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
if(labelPos) *labelPos = ref;
Vector ab = ap.Minus(bp); Vector ab = ap.Minus(bp);
Vector ar = ap.Minus(ref); Vector ar = ap.Minus(ref);
@ -103,7 +104,7 @@ void Constraint::DrawOrGetDistance(void) {
void Constraint::Draw(void) { void Constraint::Draw(void) {
dogd.drawing = true; dogd.drawing = true;
DrawOrGetDistance(); DrawOrGetDistance(NULL);
} }
double Constraint::GetDistance(Point2d mp) { double Constraint::GetDistance(Point2d mp) {
@ -111,8 +112,18 @@ double Constraint::GetDistance(Point2d mp) {
dogd.mp = mp; dogd.mp = mp;
dogd.dmin = 1e12; dogd.dmin = 1e12;
DrawOrGetDistance(); DrawOrGetDistance(NULL);
return dogd.dmin; return dogd.dmin;
} }
Vector Constraint::GetLabelPos(void) {
dogd.drawing = false;
dogd.mp.x = 0; dogd.mp.y = 0;
dogd.dmin = 1e12;
Vector p;
DrawOrGetDistance(&p);
return p;
}

View File

@ -49,6 +49,7 @@ int Expr::Children(void) {
Expr *Expr::DeepCopy(void) { Expr *Expr::DeepCopy(void) {
Expr *n = AllocExpr(); Expr *n = AllocExpr();
*n = *this; *n = *this;
n->marker = 0;
int c = n->Children(); int c = n->Children();
if(c > 0) n->a = a->DeepCopy(); if(c > 0) n->a = a->DeepCopy();
if(c > 1) n->b = b->DeepCopy(); if(c > 1) n->b = b->DeepCopy();
@ -58,6 +59,7 @@ Expr *Expr::DeepCopy(void) {
Expr *Expr::DeepCopyKeep(void) { Expr *Expr::DeepCopyKeep(void) {
Expr *n = (Expr *)MemAlloc(sizeof(Expr)); Expr *n = (Expr *)MemAlloc(sizeof(Expr));
*n = *this; *n = *this;
n->marker = 0xbad2feed;
n->a = n->b = NULL; n->a = n->b = NULL;
int c = n->Children(); int c = n->Children();
if(c > 0) n->a = a->DeepCopyKeep(); if(c > 0) n->a = a->DeepCopyKeep();
@ -65,6 +67,17 @@ Expr *Expr::DeepCopyKeep(void) {
return n; return n;
} }
void Expr::FreeKeep(Expr **e) {
if(!(*e)) oops();
int c = (*e)->Children();
if(c > 0) FreeKeep(&((*e)->a));
if(c > 1) FreeKeep(&((*e)->b));
if((*e)->marker != 0xbad2feed) oops();
MemFree(*e);
*e = NULL;
}
Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry, Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
IdList<Param,hParam> *thenTry) IdList<Param,hParam> *thenTry)
{ {

5
expr.h
View File

@ -6,6 +6,8 @@ class Expr;
class Expr { class Expr {
public: public:
DWORD marker;
// A parameter, by the hParam handle // A parameter, by the hParam handle
static const int PARAM = 0; static const int PARAM = 0;
// A parameter, by a pointer straight in to the param table (faster, // A parameter, by a pointer straight in to the param table (faster,
@ -76,8 +78,9 @@ public:
void PrintW(void); // worker void PrintW(void); // worker
// Make a copy of an expression that won't get blown away when we // Make a copy of an expression that won't get blown away when we
// do a FreeAllExprs() // do a FreeAllExprs(), or free it later.
Expr *DeepCopyKeep(void); Expr *DeepCopyKeep(void);
static void FreeKeep(Expr **f);
// or a copy that will // or a copy that will
Expr *DeepCopy(void); Expr *DeepCopy(void);
// number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+) // number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+)

View File

@ -229,6 +229,7 @@ void GraphicsWindow::EnsureValidActives(void) {
void GraphicsWindow::MenuEdit(int id) { void GraphicsWindow::MenuEdit(int id) {
switch(id) { switch(id) {
case MNU_UNSELECT_ALL: case MNU_UNSELECT_ALL:
HideGraphicsEditControl();
SS.GW.ClearSelection(); SS.GW.ClearSelection();
SS.GW.pendingOperation = 0; SS.GW.pendingOperation = 0;
SS.GW.pendingDescription = NULL; SS.GW.pendingDescription = NULL;
@ -316,6 +317,8 @@ void GraphicsWindow::UpdateDraggedPoint(Vector *pos, double mx, double my) {
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)
{ {
if(GraphicsEditControlIsVisible()) return;
Point2d mp = { x, y }; Point2d mp = { x, y };
if(middleDown) { if(middleDown) {
@ -460,6 +463,8 @@ void GraphicsWindow::GroupSelection(void) {
} }
void GraphicsWindow::MouseMiddleDown(double x, double y) { void GraphicsWindow::MouseMiddleDown(double x, double y) {
if(GraphicsEditControlIsVisible()) return;
orig.offset = offset; orig.offset = offset;
orig.projUp = projUp; orig.projUp = projUp;
orig.projRight = projRight; orig.projRight = projRight;
@ -479,6 +484,8 @@ hRequest GraphicsWindow::AddRequest(int type) {
} }
void GraphicsWindow::MouseLeftDown(double mx, double my) { void GraphicsWindow::MouseLeftDown(double mx, double my) {
if(GraphicsEditControlIsVisible()) return;
// Make sure the hover is up to date. // Make sure the hover is up to date.
MouseMoved(mx, my, false, false, false, false, false); MouseMoved(mx, my, false, false, false, false, false);
orig.mouse.x = mx; orig.mouse.x = mx;
@ -542,6 +549,31 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
InvalidateGraphics(); InvalidateGraphics();
} }
void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
if(GraphicsEditControlIsVisible()) return;
if(hover.constraint.v) {
ClearSelection();
Constraint *c = SS.GetConstraint(hover.constraint);
Vector p3 = c->GetLabelPos();
Point2d p2 = ProjectPoint(p3);
ShowGraphicsEditControl((int)p2.x, (int)p2.y, c->exprA->Print());
constraintBeingEdited = hover.constraint;
}
}
void GraphicsWindow::EditControlDone(char *s) {
Expr *e = Expr::FromString(s);
if(e) {
Constraint *c = SS.GetConstraint(constraintBeingEdited);
Expr::FreeKeep(&(c->exprA));
c->exprA = e->DeepCopyKeep();
HideGraphicsEditControl();
} else {
Error("Not a valid number or expression: '%s'", s);
}
}
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);
double offsetUp = offset.Dot(projUp); double offsetUp = offset.Dot(projUp);

View File

@ -246,9 +246,11 @@ public:
double dmin; double dmin;
} dogd; // state for drawing or getting distance (for hit testing) } dogd; // state for drawing or getting distance (for hit testing)
void LineDrawOrGetDistance(Vector a, Vector b); void LineDrawOrGetDistance(Vector a, Vector b);
void DrawOrGetDistance(Vector *labelPos);
double GetDistance(Point2d mp); double GetDistance(Point2d mp);
Vector GetLabelPos(void);
void Draw(void); void Draw(void);
void DrawOrGetDistance(void);
bool HasLabel(void); bool HasLabel(void);

View File

@ -35,6 +35,10 @@ BOOL GetOpenFile(char *file, char *defExtension, char *selPattern);
void CheckMenuById(int id, BOOL checked); void CheckMenuById(int id, BOOL checked);
void EnableMenuById(int id, BOOL checked); void EnableMenuById(int id, BOOL checked);
void ShowGraphicsEditControl(int x, int y, char *s);
void HideGraphicsEditControl(void);
BOOL GraphicsEditControlIsVisible(void);
void InvalidateGraphics(void); void InvalidateGraphics(void);
void InvalidateText(void); void InvalidateText(void);
SDWORD GetMilliseconds(void); SDWORD GetMilliseconds(void);

3
ui.h
View File

@ -144,6 +144,8 @@ public:
char *pendingDescription; char *pendingDescription;
hRequest AddRequest(int type); hRequest AddRequest(int type);
// The constraint that is being edited with the on-screen textbox.
hConstraint constraintBeingEdited;
// The current selection. // The current selection.
class Selection { class Selection {
@ -194,6 +196,7 @@ public:
void MouseLeftDoubleClick(double x, double y); void MouseLeftDoubleClick(double x, double y);
void MouseMiddleDown(double x, double y); void MouseMiddleDown(double x, double y);
void MouseScroll(double x, double y, int delta); void MouseScroll(double x, double y, int delta);
void EditControlDone(char *s);
}; };

View File

@ -24,6 +24,7 @@ int TextWndScrollPos;
int TextWndRows; int TextWndRows;
HWND GraphicsWnd; HWND GraphicsWnd;
HWND GraphicsEditControl;
HMENU SubMenus[100]; HMENU SubMenus[100];
struct { struct {
int x, y; int x, y;
@ -291,6 +292,18 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
static BOOL ProcessKeyDown(WPARAM wParam) static BOOL ProcessKeyDown(WPARAM wParam)
{ {
if(GraphicsEditControlIsVisible() && wParam != VK_ESCAPE) {
if(wParam == VK_RETURN) {
char s[1024];
memset(s, 0, sizeof(s));
SendMessage(GraphicsEditControl, WM_GETTEXT, 900, (LPARAM)s);
SS.GW.EditControlDone(s);
return TRUE;
} else {
return FALSE;
}
}
int c; int c;
switch(wParam) { switch(wParam) {
case VK_OEM_PLUS: c = '+'; break; case VK_OEM_PLUS: c = '+'; break;
@ -383,6 +396,32 @@ void InvalidateText(void)
InvalidateRect(TextWnd, NULL, FALSE); InvalidateRect(TextWnd, NULL, FALSE);
} }
void ShowGraphicsEditControl(int x, int y, char *s)
{
RECT r;
GetClientRect(GraphicsWnd, &r);
x = x + (r.right - r.left)/2;
y = (r.bottom - r.top)/2 - y;
// (x, y) are the bottom left, but the edit control is placed by its
// top left corner
y -= 21;
MoveWindow(GraphicsEditControl, x, y, 120, 21, TRUE);
ShowWindow(GraphicsEditControl, SW_SHOW);
SendMessage(GraphicsEditControl, WM_SETTEXT, 0, (LPARAM)s);
SendMessage(GraphicsEditControl, EM_SETSEL, 0, strlen(s));
SetFocus(GraphicsEditControl);
}
void HideGraphicsEditControl(void)
{
ShowWindow(GraphicsEditControl, SW_HIDE);
}
BOOL GraphicsEditControlIsVisible(void)
{
return IsWindowVisible(GraphicsEditControl);
}
LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam, LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
@ -407,6 +446,7 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDOWN: { case WM_MBUTTONDOWN: {
int x = LOWORD(lParam); int x = LOWORD(lParam);
int y = HIWORD(lParam); int y = HIWORD(lParam);
@ -421,6 +461,8 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
if(msg == WM_LBUTTONDOWN) { if(msg == WM_LBUTTONDOWN) {
SS.GW.MouseLeftDown(x, y); SS.GW.MouseLeftDown(x, y);
} else if(msg == WM_LBUTTONDBLCLK) {
SS.GW.MouseLeftDoubleClick(x, y);
} else if(msg == WM_MBUTTONDOWN) { } else if(msg == WM_MBUTTONDOWN) {
SS.GW.MouseMiddleDown(x, y); SS.GW.MouseMiddleDown(x, y);
} else if(msg == WM_MOUSEMOVE) { } else if(msg == WM_MOUSEMOVE) {
@ -441,11 +483,13 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
break; break;
} }
case WM_COMMAND: { case WM_COMMAND: {
int id = LOWORD(wParam); if(HIWORD(wParam) == 0) {
for(int i = 0; SS.GW.menu[i].level >= 0; i++) { int id = LOWORD(wParam);
if(id == SS.GW.menu[i].id) { for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id); if(id == SS.GW.menu[i].id) {
break; (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id);
break;
}
} }
} }
break; break;
@ -604,6 +648,11 @@ static void CreateMainWindows(void)
600, 300, 200, 200, NULL, top, Instance, NULL); 600, 300, 200, 200, NULL, top, Instance, NULL);
if(!GraphicsWnd) oops(); if(!GraphicsWnd) oops();
GraphicsEditControl = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "",
WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS,
50, 50, 100, 21, GraphicsWnd, NULL, Instance, NULL);
SendMessage(GraphicsEditControl, WM_SETFONT, (WPARAM)FixedFont, TRUE);
// The text window, with a comand line and some textual information // The text window, with a comand line and some textual information
// about the sketch. // about the sketch.
@ -643,12 +692,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{ {
Instance = hInstance; Instance = hInstance;
// Create the root windows: one for control, with text, and one for InitCommonControls();
// the graphics
CreateMainWindows();
ThawWindowPos(TextWnd);
ThawWindowPos(GraphicsWnd);
// A monospaced font // A monospaced font
FixedFont = CreateFont(TEXT_HEIGHT-2, TEXT_WIDTH, 0, 0, FW_REGULAR, FALSE, FixedFont = CreateFont(TEXT_HEIGHT-2, TEXT_WIDTH, 0, 0, FW_REGULAR, FALSE,
@ -662,6 +706,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if(!LinkFont) if(!LinkFont)
LinkFont = (HFONT)GetStockObject(SYSTEM_FONT); LinkFont = (HFONT)GetStockObject(SYSTEM_FONT);
// Create the root windows: one for control, with text, and one for
// the graphics
CreateMainWindows();
ThawWindowPos(TextWnd);
ThawWindowPos(GraphicsWnd);
// Create the heap that we use to store Exprs. // Create the heap that we use to store Exprs.
FreeAllExprs(); FreeAllExprs();