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
parent
2926fa95d9
commit
9b1b255e85
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
13
expr.cpp
13
expr.cpp
|
@ -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
5
expr.h
|
@ -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 (+)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
4
sketch.h
4
sketch.h
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
3
ui.h
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue