Add step and repeat translate, with multiple copies; that all works
nicely. And to do that, I've added the user interface to show an edit control in the text window. [git-p4: depot-paths = "//depot/solvespace/": change = 1749]solver
parent
ecee90965e
commit
4375c01c51
|
@ -460,7 +460,7 @@ s:
|
||||||
Vector a = SS.GetEntity(ptA)->PointGetNum();
|
Vector a = SS.GetEntity(ptA)->PointGetNum();
|
||||||
Vector b = SS.GetEntity(ptB)->PointGetNum();
|
Vector b = SS.GetEntity(ptB)->PointGetNum();
|
||||||
|
|
||||||
Entity *w = SS.GetEntity(SS.GetEntity(ptA)->workplane);
|
Entity *w = SS.GetEntity(workplane);
|
||||||
Vector cu = w->Normal()->NormalU();
|
Vector cu = w->Normal()->NormalU();
|
||||||
Vector cv = w->Normal()->NormalV();
|
Vector cv = w->Normal()->NormalV();
|
||||||
Vector cn = w->Normal()->NormalN();
|
Vector cn = w->Normal()->NormalN();
|
||||||
|
|
|
@ -332,6 +332,7 @@ void Entity::PointForceTo(Vector p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case POINT_N_TRANS: {
|
case POINT_N_TRANS: {
|
||||||
|
if(timesApplied == 0) break;
|
||||||
Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied);
|
Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied);
|
||||||
SS.GetParam(param[0])->val = trans.x;
|
SS.GetParam(param[0])->val = trans.x;
|
||||||
SS.GetParam(param[1])->val = trans.y;
|
SS.GetParam(param[1])->val = trans.y;
|
||||||
|
|
1
file.cpp
1
file.cpp
|
@ -55,6 +55,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) },
|
{ 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) },
|
||||||
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
||||||
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
||||||
|
{ 'g', "Group.exprA", 'E', &(SS.sv.g.exprA) },
|
||||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||||
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
||||||
{ 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) },
|
{ 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) },
|
||||||
|
|
|
@ -292,6 +292,7 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case MNU_UNSELECT_ALL:
|
case MNU_UNSELECT_ALL:
|
||||||
HideGraphicsEditControl();
|
HideGraphicsEditControl();
|
||||||
|
HideTextEditControl();
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
SS.GW.ClearPending();
|
SS.GW.ClearPending();
|
||||||
SS.TW.ScreenNavigation('h', 0);
|
SS.TW.ScreenNavigation('h', 0);
|
||||||
|
@ -320,6 +321,8 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||||
|
|
||||||
// Forget any mention of the just-deleted entity
|
// Forget any mention of the just-deleted entity
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
|
HideGraphicsEditControl();
|
||||||
|
HideTextEditControl();
|
||||||
// And regenerate to get rid of what it generates, plus anything
|
// And regenerate to get rid of what it generates, plus anything
|
||||||
// that references it (since the regen code checks for that).
|
// that references it (since the regen code checks for that).
|
||||||
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS, 0, INT_MAX);
|
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS, 0, INT_MAX);
|
||||||
|
|
2
mesh.cpp
2
mesh.cpp
|
@ -50,7 +50,7 @@ void SMesh::GetBounding(Vector *vmax, Vector *vmin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMesh::Simplify(int start) {
|
void SMesh::Simplify(int start) {
|
||||||
#define MAX_TRIANGLES 500
|
#define MAX_TRIANGLES 2000
|
||||||
if(l.n - start > MAX_TRIANGLES) oops();
|
if(l.n - start > MAX_TRIANGLES) oops();
|
||||||
|
|
||||||
STriangle tout[MAX_TRIANGLES];
|
STriangle tout[MAX_TRIANGLES];
|
||||||
|
|
52
sketch.cpp
52
sketch.cpp
|
@ -75,16 +75,26 @@ void Group::MenuGroup(int id) {
|
||||||
g.type = EXTRUDE;
|
g.type = EXTRUDE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.wrkpl.entityB = SS.GW.ActiveWorkplane();
|
g.wrkpl.entityB = SS.GW.ActiveWorkplane();
|
||||||
g.subtype = EXTRUDE_ONE_SIDED;
|
g.subtype = ONE_SIDED;
|
||||||
g.name.strcpy("extrude");
|
g.name.strcpy("extrude");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_GROUP_ROT:
|
case GraphicsWindow::MNU_GROUP_ROT:
|
||||||
g.type = ROTATE;
|
g.type = ROTATE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
|
g.exprA = Expr::FromConstant(7)->DeepCopyKeep();
|
||||||
|
g.subtype = ONE_SIDED;
|
||||||
g.name.strcpy("rotate");
|
g.name.strcpy("rotate");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_GROUP_TRANS:
|
||||||
|
g.type = TRANSLATE;
|
||||||
|
g.opA = SS.GW.activeGroup;
|
||||||
|
g.exprA = Expr::FromConstant(7)->DeepCopyKeep();
|
||||||
|
g.subtype = ONE_SIDED;
|
||||||
|
g.name.strcpy("translate");
|
||||||
|
break;
|
||||||
|
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +123,10 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
IdList<Param,hParam> *param)
|
IdList<Param,hParam> *param)
|
||||||
{
|
{
|
||||||
Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
|
Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
|
||||||
|
Vector gp = SS.GW.projRight.Plus(SS.GW.projUp);
|
||||||
gn = gn.WithMagnitude(200/SS.GW.scale);
|
gn = gn.WithMagnitude(200/SS.GW.scale);
|
||||||
int i;
|
gp = gp.WithMagnitude(200/SS.GW.scale);
|
||||||
|
int a, i;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case DRAWING_3D:
|
case DRAWING_3D:
|
||||||
break;
|
break;
|
||||||
|
@ -170,9 +182,9 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
AddParam(param, h.param(1), gn.y);
|
AddParam(param, h.param(1), gn.y);
|
||||||
AddParam(param, h.param(2), gn.z);
|
AddParam(param, h.param(2), gn.z);
|
||||||
int ai, af;
|
int ai, af;
|
||||||
if(subtype == EXTRUDE_ONE_SIDED) {
|
if(subtype == ONE_SIDED) {
|
||||||
ai = 0; af = 1;
|
ai = 0; af = 2;
|
||||||
} else if(subtype == EXTRUDE_TWO_SIDED) {
|
} else if(subtype == TWO_SIDED) {
|
||||||
ai = -1; af = 1;
|
ai = -1; af = 1;
|
||||||
} else oops();
|
} else oops();
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
|
@ -194,11 +206,31 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRANSLATE: {
|
||||||
|
// The translation vector
|
||||||
|
AddParam(param, h.param(0), gp.x);
|
||||||
|
AddParam(param, h.param(1), gp.y);
|
||||||
|
AddParam(param, h.param(2), gp.z);
|
||||||
|
|
||||||
|
int n = (int)(exprA->Eval());
|
||||||
|
for(a = 0; a < n; a++) {
|
||||||
|
for(i = 0; i < entity->n; i++) {
|
||||||
|
Entity *e = &(entity->elem[i]);
|
||||||
|
if(e->group.v != opA.v) continue;
|
||||||
|
|
||||||
|
CopyEntity(e->h, a*2 - (subtype == ONE_SIDED ? 0 : (n-1)),
|
||||||
|
h.param(0), h.param(1), h.param(2),
|
||||||
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ROTATE:
|
case ROTATE:
|
||||||
// The translation vector
|
// The translation vector
|
||||||
AddParam(param, h.param(0), 100);
|
AddParam(param, h.param(0), gp.x);
|
||||||
AddParam(param, h.param(1), 100);
|
AddParam(param, h.param(1), gp.y);
|
||||||
AddParam(param, h.param(2), 100);
|
AddParam(param, h.param(2), gp.z);
|
||||||
// The rotation quaternion
|
// The rotation quaternion
|
||||||
AddParam(param, h.param(3), 1);
|
AddParam(param, h.param(3), 1);
|
||||||
AddParam(param, h.param(4), 0);
|
AddParam(param, h.param(4), 0);
|
||||||
|
@ -427,8 +459,8 @@ void Group::MakePolygons(void) {
|
||||||
SS.GetParam(h.param(2))->val
|
SS.GetParam(h.param(2))->val
|
||||||
);
|
);
|
||||||
Vector tbot, ttop;
|
Vector tbot, ttop;
|
||||||
if(subtype == EXTRUDE_ONE_SIDED) {
|
if(subtype == ONE_SIDED) {
|
||||||
tbot = Vector::MakeFrom(0, 0, 0); ttop = translate;
|
tbot = Vector::MakeFrom(0, 0, 0); ttop = translate.ScaledBy(2);
|
||||||
} else {
|
} else {
|
||||||
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
|
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
|
||||||
}
|
}
|
||||||
|
|
5
sketch.h
5
sketch.h
|
@ -89,6 +89,7 @@ public:
|
||||||
hGroup opB;
|
hGroup opB;
|
||||||
bool visible;
|
bool visible;
|
||||||
hEntity activeWorkplane;
|
hEntity activeWorkplane;
|
||||||
|
Expr *exprA;
|
||||||
|
|
||||||
static const int SOLVED_OKAY = 0;
|
static const int SOLVED_OKAY = 0;
|
||||||
static const int DIDNT_CONVERGE = 10;
|
static const int DIDNT_CONVERGE = 10;
|
||||||
|
@ -100,8 +101,8 @@ public:
|
||||||
|
|
||||||
static const int WORKPLANE_BY_POINT_ORTHO = 6000;
|
static const int WORKPLANE_BY_POINT_ORTHO = 6000;
|
||||||
static const int WORKPLANE_BY_LINE_SEGMENTS = 6001;
|
static const int WORKPLANE_BY_LINE_SEGMENTS = 6001;
|
||||||
static const int EXTRUDE_ONE_SIDED = 7000;
|
static const int ONE_SIDED = 7000;
|
||||||
static const int EXTRUDE_TWO_SIDED = 7001;
|
static const int TWO_SIDED = 7001;
|
||||||
int subtype;
|
int subtype;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -232,6 +232,8 @@ void SolveSpace::GenerateAll(bool andSolve, int first, int last) {
|
||||||
// the active group or active workplane could have been deleted. So
|
// the active group or active workplane could have been deleted. So
|
||||||
// clear all that out.
|
// clear all that out.
|
||||||
GW.ClearSuper();
|
GW.ClearSuper();
|
||||||
|
HideGraphicsEditControl();
|
||||||
|
HideTextEditControl();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@ void EnableMenuById(int id, BOOL checked);
|
||||||
void ShowGraphicsEditControl(int x, int y, char *s);
|
void ShowGraphicsEditControl(int x, int y, char *s);
|
||||||
void HideGraphicsEditControl(void);
|
void HideGraphicsEditControl(void);
|
||||||
BOOL GraphicsEditControlIsVisible(void);
|
BOOL GraphicsEditControlIsVisible(void);
|
||||||
|
void ShowTextEditControl(int hr, int c, char *s);
|
||||||
|
void HideTextEditControl(void);
|
||||||
|
BOOL TextEditControlIsVisible(void);
|
||||||
|
|
||||||
void ShowTextWindow(BOOL visible);
|
void ShowTextWindow(BOOL visible);
|
||||||
void InvalidateText(void);
|
void InvalidateText(void);
|
||||||
|
|
67
textwin.cpp
67
textwin.cpp
|
@ -374,12 +374,12 @@ void TextWindow::ScreenSelectRequest(int link, DWORD v) {
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
SS.GW.selection[0].entity = hr.entity(0);
|
SS.GW.selection[0].entity = hr.entity(0);
|
||||||
}
|
}
|
||||||
void TextWindow::ScreenChangeExtrudeSides(int link, DWORD v) {
|
void TextWindow::ScreenChangeOneOrTwoSides(int link, DWORD v) {
|
||||||
Group *g = SS.GetGroup(SS.TW.shown->group);
|
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||||
if(g->subtype == Group::EXTRUDE_ONE_SIDED) {
|
if(g->subtype == Group::ONE_SIDED) {
|
||||||
g->subtype = Group::EXTRUDE_TWO_SIDED;
|
g->subtype = Group::TWO_SIDED;
|
||||||
} else if(g->subtype == Group::EXTRUDE_TWO_SIDED) {
|
} else if(g->subtype == Group::TWO_SIDED) {
|
||||||
g->subtype = Group::EXTRUDE_ONE_SIDED;
|
g->subtype = Group::ONE_SIDED;
|
||||||
} else oops();
|
} else oops();
|
||||||
SS.GW.GeneratePerSolving();
|
SS.GW.GeneratePerSolving();
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
|
@ -394,9 +394,15 @@ void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
|
||||||
SS.GW.GeneratePerSolving();
|
SS.GW.GeneratePerSolving();
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
}
|
}
|
||||||
|
void TextWindow::ScreenChangeExprA(int link, DWORD v) {
|
||||||
|
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||||
|
ShowTextEditControl(13, 10, g->exprA->Print());
|
||||||
|
SS.TW.edit.meaning = EDIT_TIMES_REPEATED;
|
||||||
|
SS.TW.edit.group.v = v;
|
||||||
|
}
|
||||||
void TextWindow::ShowGroupInfo(void) {
|
void TextWindow::ShowGroupInfo(void) {
|
||||||
Group *g = SS.group.FindById(shown->group);
|
Group *g = SS.group.FindById(shown->group);
|
||||||
char *s;
|
char *s, *s2;
|
||||||
if(SS.GW.activeGroup.v == shown->group.v) {
|
if(SS.GW.activeGroup.v == shown->group.v) {
|
||||||
s = "active ";
|
s = "active ";
|
||||||
} else if(shown->group.v == Group::HGROUP_REFERENCES.v) {
|
} else if(shown->group.v == Group::HGROUP_REFERENCES.v) {
|
||||||
|
@ -407,13 +413,33 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
Printf(true, "%Ft%sGROUP %E%s", s, g->DescriptionString());
|
Printf(true, "%Ft%sGROUP %E%s", s, g->DescriptionString());
|
||||||
|
|
||||||
if(g->type == Group::EXTRUDE) {
|
if(g->type == Group::EXTRUDE) {
|
||||||
bool one = (g->subtype == Group::EXTRUDE_ONE_SIDED);
|
s = "EXTRUDE";
|
||||||
Printf(true, "%FtEXTRUDE%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
} else if(g->type == Group::TRANSLATE) {
|
||||||
&TextWindow::ScreenChangeExtrudeSides,
|
s = "TRANSLATE";
|
||||||
(one ? "" : "one side"), (one ? "one-side" : ""),
|
s2 ="REPEAT ";
|
||||||
&TextWindow::ScreenChangeExtrudeSides,
|
} else if(g->type == Group::ROTATE) {
|
||||||
|
s = "ROTATE";
|
||||||
|
s2 ="REPEAT ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g->type == Group::EXTRUDE || g->type == Group::ROTATE ||
|
||||||
|
g->type == Group::TRANSLATE)
|
||||||
|
{
|
||||||
|
bool one = (g->subtype == Group::ONE_SIDED);
|
||||||
|
Printf(true, "%Ft%s%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E", s,
|
||||||
|
&TextWindow::ScreenChangeOneOrTwoSides,
|
||||||
|
(one ? "" : "one side"), (one ? "one side" : ""),
|
||||||
|
&TextWindow::ScreenChangeOneOrTwoSides,
|
||||||
(!one ? "" : "two sides"), (!one ? "two sides" : ""));
|
(!one ? "" : "two sides"), (!one ? "two sides" : ""));
|
||||||
|
|
||||||
|
}
|
||||||
|
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
||||||
|
int times = (int)(g->exprA->Eval());
|
||||||
|
Printf(true, "%Ft%s%E %d time%s %Fl%Ll%D%f(change)%E",
|
||||||
|
s2, times, times == 1 ? "" : "s",
|
||||||
|
g->h, &TextWindow::ScreenChangeExprA);
|
||||||
|
}
|
||||||
|
if(g->type == Group::EXTRUDE) {
|
||||||
bool diff = (g->meshCombine == Group::COMBINE_AS_DIFFERENCE);
|
bool diff = (g->meshCombine == Group::COMBINE_AS_DIFFERENCE);
|
||||||
Printf(false, "%FtCOMBINE%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
Printf(false, "%FtCOMBINE%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
||||||
&TextWindow::ScreenChangeMeshCombine,
|
&TextWindow::ScreenChangeMeshCombine,
|
||||||
|
@ -505,4 +531,23 @@ void TextWindow::ShowConstraintInfo(void) {
|
||||||
Printf(false, "[[constraint]]");
|
Printf(false, "[[constraint]]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextWindow::EditControlDone(char *s) {
|
||||||
|
HideTextEditControl();
|
||||||
|
switch(edit.meaning) {
|
||||||
|
case EDIT_TIMES_REPEATED: {
|
||||||
|
Expr *e = Expr::FromString(s);
|
||||||
|
if(e) {
|
||||||
|
Group *g = SS.GetGroup(edit.group);
|
||||||
|
Expr::FreeKeep(&(g->exprA));
|
||||||
|
g->exprA = e->DeepCopyKeep();
|
||||||
|
SS.GW.GeneratePerSolving();
|
||||||
|
SS.TW.Show();
|
||||||
|
} else {
|
||||||
|
Error("Not a valid number or expression: '%s'", s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edit.meaning = EDIT_NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
14
ui.h
14
ui.h
|
@ -55,6 +55,13 @@ public:
|
||||||
int history;
|
int history;
|
||||||
ShownState *shown;
|
ShownState *shown;
|
||||||
|
|
||||||
|
static const int EDIT_NOTHING = 0;
|
||||||
|
static const int EDIT_TIMES_REPEATED = 1;
|
||||||
|
struct {
|
||||||
|
int meaning;
|
||||||
|
hGroup group;
|
||||||
|
} edit;
|
||||||
|
|
||||||
static void ReportHowGroupSolved(hGroup hg);
|
static void ReportHowGroupSolved(hGroup hg);
|
||||||
|
|
||||||
void ShowHeader(void);
|
void ShowHeader(void);
|
||||||
|
@ -68,6 +75,8 @@ public:
|
||||||
void ShowGroupSolveInfo(void);
|
void ShowGroupSolveInfo(void);
|
||||||
|
|
||||||
void OneScreenForwardTo(int screen);
|
void OneScreenForwardTo(int screen);
|
||||||
|
|
||||||
|
// All of these are callbacks from the GUI code.
|
||||||
static void ScreenSelectGroup(int link, DWORD v);
|
static void ScreenSelectGroup(int link, DWORD v);
|
||||||
static void ScreenActivateGroup(int link, DWORD v);
|
static void ScreenActivateGroup(int link, DWORD v);
|
||||||
static void ScreenToggleGroupShown(int link, DWORD v);
|
static void ScreenToggleGroupShown(int link, DWORD v);
|
||||||
|
@ -79,10 +88,13 @@ public:
|
||||||
static void ScreenSelectRequest(int link, DWORD v);
|
static void ScreenSelectRequest(int link, DWORD v);
|
||||||
static void ScreenSelectConstraint(int link, DWORD v);
|
static void ScreenSelectConstraint(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenChangeExtrudeSides(int link, DWORD v);
|
static void ScreenChangeOneOrTwoSides(int link, DWORD v);
|
||||||
static void ScreenChangeMeshCombine(int link, DWORD v);
|
static void ScreenChangeMeshCombine(int link, DWORD v);
|
||||||
|
static void ScreenChangeExprA(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenNavigation(int link, DWORD v);
|
static void ScreenNavigation(int link, DWORD v);
|
||||||
|
|
||||||
|
void EditControlDone(char *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GraphicsWindow {
|
class GraphicsWindow {
|
||||||
|
|
|
@ -15,11 +15,18 @@
|
||||||
#define MIN_COLS 45
|
#define MIN_COLS 45
|
||||||
#define TEXT_HEIGHT 20
|
#define TEXT_HEIGHT 20
|
||||||
#define TEXT_WIDTH 9
|
#define TEXT_WIDTH 9
|
||||||
|
#define TEXT_LEFT_MARGIN 4
|
||||||
|
|
||||||
|
// For the edit controls
|
||||||
|
#define EDIT_WIDTH 220
|
||||||
|
#define EDIT_HEIGHT 21
|
||||||
|
|
||||||
HINSTANCE Instance;
|
HINSTANCE Instance;
|
||||||
|
|
||||||
HWND TextWnd;
|
HWND TextWnd;
|
||||||
HWND TextWndScrollBar;
|
HWND TextWndScrollBar;
|
||||||
|
HWND TextEditControl;
|
||||||
|
int TextEditControlCol, TextEditControlHalfRow;
|
||||||
int TextWndScrollPos; // The scrollbar position, in half-row units
|
int TextWndScrollPos; // The scrollbar position, in half-row units
|
||||||
int TextWndHalfRows; // The height of our window, in half-row units
|
int TextWndHalfRows; // The height of our window, in half-row units
|
||||||
|
|
||||||
|
@ -182,7 +189,7 @@ static void PaintTextWnd(HDC hdc)
|
||||||
SelectObject(backDc, FixedFont);
|
SelectObject(backDc, FixedFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = 4 + c*TEXT_WIDTH;
|
int x = TEXT_LEFT_MARGIN + c*TEXT_WIDTH;
|
||||||
int y = (top-TextWndScrollPos)*(TEXT_HEIGHT/2);
|
int y = (top-TextWndScrollPos)*(TEXT_HEIGHT/2);
|
||||||
|
|
||||||
RECT a;
|
RECT a;
|
||||||
|
@ -227,6 +234,11 @@ void HandleTextWindowScrollBar(WPARAM wParam, LPARAM lParam)
|
||||||
si.nPos = TextWndScrollPos;
|
si.nPos = TextWndScrollPos;
|
||||||
SetScrollInfo(TextWndScrollBar, SB_CTL, &si, TRUE);
|
SetScrollInfo(TextWndScrollBar, SB_CTL, &si, TRUE);
|
||||||
|
|
||||||
|
if(TextEditControlIsVisible()) {
|
||||||
|
int x = TEXT_LEFT_MARGIN + TEXT_WIDTH*TextEditControlCol;
|
||||||
|
int y = (TextEditControlHalfRow - TextWndScrollPos)*(TEXT_HEIGHT/2);
|
||||||
|
MoveWindow(TextEditControl, x, y, EDIT_WIDTH, EDIT_HEIGHT, TRUE);
|
||||||
|
}
|
||||||
InvalidateRect(TextWnd, NULL, FALSE);
|
InvalidateRect(TextWnd, NULL, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,6 +300,10 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
case WM_MOUSEMOVE: {
|
case WM_MOUSEMOVE: {
|
||||||
|
if(TextEditControlIsVisible() || GraphicsEditControlIsVisible()) {
|
||||||
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||||
|
break;
|
||||||
|
}
|
||||||
GraphicsWindow::Selection ps = SS.GW.hover;
|
GraphicsWindow::Selection ps = SS.GW.hover;
|
||||||
SS.GW.hover.Clear();
|
SS.GW.hover.Clear();
|
||||||
|
|
||||||
|
@ -340,6 +356,9 @@ done:
|
||||||
GetClientRect(hwnd, &r);
|
GetClientRect(hwnd, &r);
|
||||||
MoveWindow(TextWndScrollBar, r.right - sw, r.top, sw,
|
MoveWindow(TextWndScrollBar, r.right - sw, r.top, sw,
|
||||||
(r.bottom - r.top), TRUE);
|
(r.bottom - r.top), TRUE);
|
||||||
|
// If the window is growing, then the scrollbar position may
|
||||||
|
// be moving, so it's as if we're dragging the scrollbar.
|
||||||
|
HandleTextWindowScrollBar(0, 0);
|
||||||
InvalidateRect(TextWnd, NULL, FALSE);
|
InvalidateRect(TextWnd, NULL, FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -368,6 +387,16 @@ static BOOL ProcessKeyDown(WPARAM wParam)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(TextEditControlIsVisible() && wParam != VK_ESCAPE) {
|
||||||
|
if(wParam == VK_RETURN) {
|
||||||
|
char s[1024];
|
||||||
|
memset(s, 0, sizeof(s));
|
||||||
|
SendMessage(TextEditControl, WM_GETTEXT, 900, (LPARAM)s);
|
||||||
|
SS.TW.EditControlDone(s);
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(wParam == VK_BACK && !GraphicsEditControlIsVisible()) {
|
if(wParam == VK_BACK && !GraphicsEditControlIsVisible()) {
|
||||||
TextWindow::ScreenNavigation('b', 0);
|
TextWindow::ScreenNavigation('b', 0);
|
||||||
|
@ -463,8 +492,35 @@ void InvalidateText(void)
|
||||||
InvalidateRect(TextWnd, NULL, FALSE);
|
InvalidateRect(TextWnd, NULL, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ShowEditControl(HWND h, int x, int y, char *s) {
|
||||||
|
MoveWindow(h, x, y, EDIT_WIDTH, EDIT_HEIGHT, TRUE);
|
||||||
|
ShowWindow(h, SW_SHOW);
|
||||||
|
SendMessage(h, WM_SETTEXT, 0, (LPARAM)s);
|
||||||
|
SendMessage(h, EM_SETSEL, 0, strlen(s));
|
||||||
|
SetFocus(h);
|
||||||
|
}
|
||||||
|
void ShowTextEditControl(int hr, int c, char *s)
|
||||||
|
{
|
||||||
|
if(TextEditControlIsVisible() || GraphicsEditControlIsVisible()) return;
|
||||||
|
|
||||||
|
int x = TEXT_LEFT_MARGIN + TEXT_WIDTH*c;
|
||||||
|
int y = (hr - TextWndScrollPos)*(TEXT_HEIGHT/2);
|
||||||
|
TextEditControlCol = c;
|
||||||
|
TextEditControlHalfRow = hr;
|
||||||
|
ShowEditControl(TextEditControl, x, y, s);
|
||||||
|
}
|
||||||
|
void HideTextEditControl(void)
|
||||||
|
{
|
||||||
|
ShowWindow(TextEditControl, SW_HIDE);
|
||||||
|
}
|
||||||
|
BOOL TextEditControlIsVisible(void)
|
||||||
|
{
|
||||||
|
return IsWindowVisible(TextEditControl);
|
||||||
|
}
|
||||||
void ShowGraphicsEditControl(int x, int y, char *s)
|
void ShowGraphicsEditControl(int x, int y, char *s)
|
||||||
{
|
{
|
||||||
|
if(TextEditControlIsVisible() || GraphicsEditControlIsVisible()) return;
|
||||||
|
|
||||||
RECT r;
|
RECT r;
|
||||||
GetClientRect(GraphicsWnd, &r);
|
GetClientRect(GraphicsWnd, &r);
|
||||||
x = x + (r.right - r.left)/2;
|
x = x + (r.right - r.left)/2;
|
||||||
|
@ -474,11 +530,7 @@ void ShowGraphicsEditControl(int x, int y, char *s)
|
||||||
// top left corner
|
// top left corner
|
||||||
y -= 20;
|
y -= 20;
|
||||||
|
|
||||||
MoveWindow(GraphicsEditControl, x, y, 220, 21, TRUE);
|
ShowEditControl(GraphicsEditControl, x, y, s);
|
||||||
ShowWindow(GraphicsEditControl, SW_SHOW);
|
|
||||||
SendMessage(GraphicsEditControl, WM_SETTEXT, 0, (LPARAM)s);
|
|
||||||
SendMessage(GraphicsEditControl, EM_SETSEL, 0, strlen(s));
|
|
||||||
SetFocus(GraphicsEditControl);
|
|
||||||
}
|
}
|
||||||
void HideGraphicsEditControl(void)
|
void HideGraphicsEditControl(void)
|
||||||
{
|
{
|
||||||
|
@ -745,6 +797,11 @@ static void CreateMainWindows(void)
|
||||||
// Force the scrollbar to get resized to the window,
|
// Force the scrollbar to get resized to the window,
|
||||||
TextWndProc(TextWnd, WM_SIZE, 0, 0);
|
TextWndProc(TextWnd, WM_SIZE, 0, 0);
|
||||||
|
|
||||||
|
TextEditControl = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "",
|
||||||
|
WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS,
|
||||||
|
50, 50, 100, 21, TextWnd, NULL, Instance, NULL);
|
||||||
|
SendMessage(TextEditControl, WM_SETFONT, (WPARAM)FixedFont, TRUE);
|
||||||
|
|
||||||
|
|
||||||
RECT r, rc;
|
RECT r, rc;
|
||||||
GetWindowRect(TextWnd, &r);
|
GetWindowRect(TextWnd, &r);
|
||||||
|
|
Loading…
Reference in New Issue