Allow generating groups in arbitrary order.
parent
df87ac6e6f
commit
c9648805ea
|
@ -689,8 +689,8 @@ nogrid:;
|
||||||
// specially by assigning a style with a fill color, or when the filled
|
// specially by assigning a style with a fill color, or when the filled
|
||||||
// paths are just being filled by default. This should go last, to make
|
// paths are just being filled by default. This should go last, to make
|
||||||
// the transparency work.
|
// the transparency work.
|
||||||
Group *g;
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
for(g = SK.group.First(); g; g = SK.group.NextAfter(g)) {
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
if(!(g->IsVisible())) continue;
|
if(!(g->IsVisible())) continue;
|
||||||
g->DrawFilledPaths();
|
g->DrawFilledPaths();
|
||||||
}
|
}
|
||||||
|
|
14
src/file.cpp
14
src/file.cpp
|
@ -20,14 +20,15 @@ void SolveSpaceUI::ClearExisting(void) {
|
||||||
UndoClearStack(&redo);
|
UndoClearStack(&redo);
|
||||||
UndoClearStack(&undo);
|
UndoClearStack(&undo);
|
||||||
|
|
||||||
Group *g;
|
for(int i = 0; i < SK.groupOrder.n; i++) {
|
||||||
for(g = SK.group.First(); g; g = SK.group.NextAfter(g)) {
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
g->Clear();
|
g->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SK.constraint.Clear();
|
SK.constraint.Clear();
|
||||||
SK.request.Clear();
|
SK.request.Clear();
|
||||||
SK.group.Clear();
|
SK.group.Clear();
|
||||||
|
SK.groupOrder.Clear();
|
||||||
SK.style.Clear();
|
SK.style.Clear();
|
||||||
|
|
||||||
SK.entity.Clear();
|
SK.entity.Clear();
|
||||||
|
@ -39,12 +40,13 @@ hGroup SolveSpaceUI::CreateDefaultDrawingGroup(void) {
|
||||||
|
|
||||||
// And an empty group, for the first stuff the user draws.
|
// And an empty group, for the first stuff the user draws.
|
||||||
g.visible = true;
|
g.visible = true;
|
||||||
|
g.name = "sketch-in-plane";
|
||||||
g.type = Group::DRAWING_WORKPLANE;
|
g.type = Group::DRAWING_WORKPLANE;
|
||||||
g.subtype = Group::WORKPLANE_BY_POINT_ORTHO;
|
g.subtype = Group::WORKPLANE_BY_POINT_ORTHO;
|
||||||
|
g.order = 1;
|
||||||
g.predef.q = Quaternion::From(1, 0, 0, 0);
|
g.predef.q = Quaternion::From(1, 0, 0, 0);
|
||||||
hRequest hr = Request::HREQUEST_REFERENCE_XY;
|
hRequest hr = Request::HREQUEST_REFERENCE_XY;
|
||||||
g.predef.origin = hr.entity(1);
|
g.predef.origin = hr.entity(1);
|
||||||
g.name = "sketch-in-plane";
|
|
||||||
SK.group.AddAndAssignId(&g);
|
SK.group.AddAndAssignId(&g);
|
||||||
SK.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
|
SK.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
|
||||||
return g.h;
|
return g.h;
|
||||||
|
@ -58,6 +60,7 @@ void SolveSpaceUI::NewFile(void) {
|
||||||
g.visible = true;
|
g.visible = true;
|
||||||
g.name = "#references";
|
g.name = "#references";
|
||||||
g.type = Group::DRAWING_3D;
|
g.type = Group::DRAWING_3D;
|
||||||
|
g.order = 0;
|
||||||
g.h = Group::HGROUP_REFERENCES;
|
g.h = Group::HGROUP_REFERENCES;
|
||||||
SK.group.Add(&g);
|
SK.group.Add(&g);
|
||||||
|
|
||||||
|
@ -308,7 +311,8 @@ bool SolveSpaceUI::SaveToFile(const std::string &filename) {
|
||||||
// A group will have either a mesh or a shell, but not both; but the code
|
// A group will have either a mesh or a shell, but not both; but the code
|
||||||
// to print either of those just does nothing if the mesh/shell is empty.
|
// to print either of those just does nothing if the mesh/shell is empty.
|
||||||
|
|
||||||
SMesh *m = &(SK.group.elem[SK.group.n-1].runningMesh);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[SK.groupOrder.n - 1]);
|
||||||
|
SMesh *m = &g->runningMesh;
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(m->l.elem[i]);
|
||||||
fprintf(fh, "Triangle %08x %08x "
|
fprintf(fh, "Triangle %08x %08x "
|
||||||
|
@ -317,7 +321,7 @@ bool SolveSpaceUI::SaveToFile(const std::string &filename) {
|
||||||
CO(tr->a), CO(tr->b), CO(tr->c));
|
CO(tr->a), CO(tr->b), CO(tr->c));
|
||||||
}
|
}
|
||||||
|
|
||||||
SShell *s = &(SK.group.elem[SK.group.n-1].runningShell);
|
SShell *s = &g->runningShell;
|
||||||
SSurface *srf;
|
SSurface *srf;
|
||||||
for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) {
|
for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) {
|
||||||
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
|
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
|
||||||
|
|
|
@ -16,8 +16,8 @@ void SolveSpaceUI::MarkGroupDirtyByEntity(hEntity he) {
|
||||||
void SolveSpaceUI::MarkGroupDirty(hGroup hg) {
|
void SolveSpaceUI::MarkGroupDirty(hGroup hg) {
|
||||||
int i;
|
int i;
|
||||||
bool go = false;
|
bool go = false;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
if(g->h.v == hg.v) {
|
if(g->h.v == hg.v) {
|
||||||
go = true;
|
go = true;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,8 @@ bool SolveSpaceUI::GroupsInOrder(hGroup before, hGroup after) {
|
||||||
|
|
||||||
int beforep = -1, afterp = -1;
|
int beforep = -1, afterp = -1;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
if(g->h.v == before.v) beforep = i;
|
if(g->h.v == before.v) beforep = i;
|
||||||
if(g->h.v == after.v) afterp = i;
|
if(g->h.v == after.v) afterp = i;
|
||||||
}
|
}
|
||||||
|
@ -141,52 +141,71 @@ bool SolveSpaceUI::PruneConstraints(hGroup hg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::GenerateAll(void) {
|
void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForBBox) {
|
||||||
int i;
|
int first, last, i, j;
|
||||||
int firstDirty = INT_MAX, lastVisible = 0;
|
|
||||||
|
SK.groupOrder.Clear();
|
||||||
|
for(int i = 0; i < SK.group.n; i++)
|
||||||
|
SK.groupOrder.Add(&SK.group.elem[i].h);
|
||||||
|
std::sort(&SK.groupOrder.elem[0], &SK.groupOrder.elem[SK.groupOrder.n],
|
||||||
|
[](const hGroup &ha, const hGroup &hb) {
|
||||||
|
return SK.GetGroup(ha)->order < SK.GetGroup(hb)->order;
|
||||||
|
});
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case GENERATE_DIRTY: {
|
||||||
|
first = INT_MAX;
|
||||||
|
last = 0;
|
||||||
|
|
||||||
// Start from the first dirty group, and solve until the active group,
|
// Start from the first dirty group, and solve until the active group,
|
||||||
// since all groups after the active group are hidden.
|
// since all groups after the active group are hidden.
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
g->order = i;
|
|
||||||
if((!g->clean) || (g->solved.how != System::SOLVED_OKAY)) {
|
if((!g->clean) || (g->solved.how != System::SOLVED_OKAY)) {
|
||||||
firstDirty = min(firstDirty, i);
|
first = min(first, i);
|
||||||
}
|
}
|
||||||
if(g->h.v == SS.GW.activeGroup.v) {
|
if(g->h.v == SS.GW.activeGroup.v) {
|
||||||
lastVisible = i;
|
last = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(firstDirty == INT_MAX || lastVisible == 0) {
|
if(first == INT_MAX || last == 0) {
|
||||||
// All clean; so just regenerate the entities, and don't solve anything.
|
// All clean; so just regenerate the entities, and don't solve anything.
|
||||||
GenerateAll(GENERATE_REGEN);
|
first = -1;
|
||||||
|
last = -1;
|
||||||
} else {
|
} else {
|
||||||
SS.nakedEdges.Clear();
|
SS.nakedEdges.Clear();
|
||||||
GenerateAll(firstDirty, lastVisible);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GENERATE_ALL:
|
||||||
|
first = 0;
|
||||||
|
last = INT_MAX;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENERATE_REGEN:
|
||||||
|
first = -1;
|
||||||
|
last = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENERATE_UNTIL_ACTIVE: {
|
||||||
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
|
if(SK.groupOrder.elem[i].v == SS.GW.activeGroup.v)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
first = 0;
|
||||||
|
last = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree) {
|
|
||||||
switch(type) {
|
|
||||||
case GENERATE_ALL: GenerateAll(0, INT_MAX, andFindFree); break;
|
|
||||||
case GENERATE_REGEN: GenerateAll(-1, -1, andFindFree); break;
|
|
||||||
case GENERATE_UNTIL_ACTIVE: GenerateAll(0, -2, andFindFree); break;
|
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree, bool genForBBox) {
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// generate until active group
|
|
||||||
if(last == -2) {
|
|
||||||
last = SK.group.IndexOf(SS.GW.activeGroup);
|
|
||||||
if(last == -1) last = INT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're generating entities for display, first we need to find
|
// If we're generating entities for display, first we need to find
|
||||||
// the bounding box to turn relative chord tolerance to absolute.
|
// the bounding box to turn relative chord tolerance to absolute.
|
||||||
if(!SS.exportMode && !genForBBox) {
|
if(!SS.exportMode && !genForBBox) {
|
||||||
GenerateAll(first, last, /*andFindFree=*/false, /*genForBBox=*/true);
|
GenerateAll(type, /*andFindFree=*/false, /*genForBBox=*/true);
|
||||||
BBox box = SK.CalculateEntityBBox(/*includeInvisibles=*/true);
|
BBox box = SK.CalculateEntityBBox(/*includeInvisibles=*/true);
|
||||||
Vector size = box.maxp.Minus(box.minp);
|
Vector size = box.maxp.Minus(box.minp);
|
||||||
double maxSize = std::max({ size.x, size.y, size.z });
|
double maxSize = std::max({ size.x, size.y, size.z });
|
||||||
|
@ -207,19 +226,19 @@ void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree, bool genFo
|
||||||
int64_t inTime = GetMilliseconds();
|
int64_t inTime = GetMilliseconds();
|
||||||
|
|
||||||
bool displayedStatusMessage = false;
|
bool displayedStatusMessage = false;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
|
|
||||||
int64_t now = GetMilliseconds();
|
int64_t now = GetMilliseconds();
|
||||||
// Display the status message if we've taken more than 400 ms, or
|
// Display the status message if we've taken more than 400 ms, or
|
||||||
// if we've taken 200 ms but we're not even halfway done, or if
|
// if we've taken 200 ms but we're not even halfway done, or if
|
||||||
// we've already started displaying the status message.
|
// we've already started displaying the status message.
|
||||||
if( (now - inTime > 400) ||
|
if( (now - inTime > 400) ||
|
||||||
((now - inTime > 200) && i < (SK.group.n / 2)) ||
|
((now - inTime > 200) && i < (SK.groupOrder.n / 2)) ||
|
||||||
displayedStatusMessage)
|
displayedStatusMessage)
|
||||||
{
|
{
|
||||||
displayedStatusMessage = true;
|
displayedStatusMessage = true;
|
||||||
std::string msg = ssprintf("generating group %d/%d", i, SK.group.n);
|
std::string msg = ssprintf("generating group %d/%d", i, SK.groupOrder.n);
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
GetGraphicsWindowSize(&w, &h);
|
GetGraphicsWindowSize(&w, &h);
|
||||||
|
@ -377,7 +396,7 @@ pruned:
|
||||||
SK.param.Clear();
|
SK.param.Clear();
|
||||||
prev.MoveSelfInto(&(SK.param));
|
prev.MoveSelfInto(&(SK.param));
|
||||||
// Try again
|
// Try again
|
||||||
GenerateAll(first, last, andFindFree, genForBBox);
|
GenerateAll(type, andFindFree, genForBBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::ForceReferences(void) {
|
void SolveSpaceUI::ForceReferences(void) {
|
||||||
|
@ -507,11 +526,11 @@ void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpaceUI::ActiveGroupsOkay() {
|
bool SolveSpaceUI::ActiveGroupsOkay() {
|
||||||
for(int i = 0; i < SK.group.n; i++) {
|
for(int i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *group = &SK.group.elem[i];
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
if(!group->IsSolvedOkay())
|
if(!g->IsSolvedOkay())
|
||||||
return false;
|
return false;
|
||||||
if(group->h.v == SS.GW.activeGroup.v)
|
if(g->h.v == SS.GW.activeGroup.v)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -222,7 +222,7 @@ void GraphicsWindow::Init(void) {
|
||||||
orig.projUp = projUp;
|
orig.projUp = projUp;
|
||||||
|
|
||||||
// And with the last group active
|
// And with the last group active
|
||||||
activeGroup = SK.group.elem[SK.group.n-1].h;
|
activeGroup = SK.groupOrder.elem[SK.groupOrder.n - 1];
|
||||||
SK.GetGroup(activeGroup)->Activate();
|
SK.GetGroup(activeGroup)->Activate();
|
||||||
|
|
||||||
showWorkplanes = false;
|
showWorkplanes = false;
|
||||||
|
@ -592,12 +592,12 @@ void GraphicsWindow::EnsureValidActives(void) {
|
||||||
Group *g = SK.group.FindByIdNoOops(activeGroup);
|
Group *g = SK.group.FindByIdNoOops(activeGroup);
|
||||||
if((!g) || (g->h.v == Group::HGROUP_REFERENCES.v)) {
|
if((!g) || (g->h.v == Group::HGROUP_REFERENCES.v)) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
if(SK.group.elem[i].h.v != Group::HGROUP_REFERENCES.v) {
|
if(SK.groupOrder.elem[i].v != Group::HGROUP_REFERENCES.v) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i >= SK.group.n) {
|
if(i >= SK.groupOrder.n) {
|
||||||
// This can happen if the user deletes all the groups in the
|
// This can happen if the user deletes all the groups in the
|
||||||
// sketch. It's difficult to prevent that, because the last
|
// sketch. It's difficult to prevent that, because the last
|
||||||
// group might have been deleted automatically, because it failed
|
// group might have been deleted automatically, because it failed
|
||||||
|
@ -606,7 +606,7 @@ void GraphicsWindow::EnsureValidActives(void) {
|
||||||
// to delete the references, though.
|
// to delete the references, though.
|
||||||
activeGroup = SS.CreateDefaultDrawingGroup();
|
activeGroup = SS.CreateDefaultDrawingGroup();
|
||||||
} else {
|
} else {
|
||||||
activeGroup = SK.group.elem[i].h;
|
activeGroup = SK.groupOrder.elem[i];
|
||||||
}
|
}
|
||||||
SK.GetGroup(activeGroup)->Activate();
|
SK.GetGroup(activeGroup)->Activate();
|
||||||
change = true;
|
change = true;
|
||||||
|
|
|
@ -56,6 +56,9 @@ void Group::MenuGroup(int id) {
|
||||||
g.color = RGBi(100, 100, 100);
|
g.color = RGBi(100, 100, 100);
|
||||||
g.scale = 1;
|
g.scale = 1;
|
||||||
|
|
||||||
|
Group *gl = SK.GetGroup(SK.groupOrder.elem[SK.groupOrder.n - 1]);
|
||||||
|
g.order = gl->order + 1;
|
||||||
|
|
||||||
if(id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT)) {
|
if(id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT)) {
|
||||||
g.impFile = RecentFile[id-RECENT_IMPORT];
|
g.impFile = RecentFile[id-RECENT_IMPORT];
|
||||||
id = GraphicsWindow::MNU_GROUP_IMPORT;
|
id = GraphicsWindow::MNU_GROUP_IMPORT;
|
||||||
|
|
|
@ -414,12 +414,12 @@ void Group::GenerateDisplayItems(void) {
|
||||||
|
|
||||||
Group *Group::PreviousGroup(void) {
|
Group *Group::PreviousGroup(void) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
if(g->h.v == h.v) break;
|
if(g->h.v == h.v) break;
|
||||||
}
|
}
|
||||||
if(i == 0 || i >= SK.group.n) return NULL;
|
if(i == 0 || i >= SK.groupOrder.n) return NULL;
|
||||||
return &(SK.group.elem[i-1]);
|
return SK.GetGroup(SK.groupOrder.elem[i - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Group *Group::RunningMeshGroup(void) {
|
Group *Group::RunningMeshGroup(void) {
|
||||||
|
|
|
@ -811,6 +811,7 @@ void SolveSpaceUI::Clear(void) {
|
||||||
|
|
||||||
void Sketch::Clear(void) {
|
void Sketch::Clear(void) {
|
||||||
group.Clear();
|
group.Clear();
|
||||||
|
groupOrder.Clear();
|
||||||
constraint.Clear();
|
constraint.Clear();
|
||||||
request.Clear();
|
request.Clear();
|
||||||
style.Clear();
|
style.Clear();
|
||||||
|
|
|
@ -628,6 +628,7 @@ class Sketch {
|
||||||
public:
|
public:
|
||||||
// These are user-editable, and define the sketch.
|
// These are user-editable, and define the sketch.
|
||||||
IdList<Group,hGroup> group;
|
IdList<Group,hGroup> group;
|
||||||
|
List<hGroup> groupOrder;
|
||||||
IdList<CONSTRAINT,hConstraint> constraint;
|
IdList<CONSTRAINT,hConstraint> constraint;
|
||||||
IdList<Request,hRequest> request;
|
IdList<Request,hRequest> request;
|
||||||
IdList<Style,hStyle> style;
|
IdList<Style,hStyle> style;
|
||||||
|
@ -659,6 +660,7 @@ public:
|
||||||
// The state for undo/redo
|
// The state for undo/redo
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IdList<Group,hGroup> group;
|
IdList<Group,hGroup> group;
|
||||||
|
List<hGroup> groupOrder;
|
||||||
IdList<Request,hRequest> request;
|
IdList<Request,hRequest> request;
|
||||||
IdList<Constraint,hConstraint> constraint;
|
IdList<Constraint,hConstraint> constraint;
|
||||||
IdList<Param,hParam> param;
|
IdList<Param,hParam> param;
|
||||||
|
@ -879,14 +881,14 @@ public:
|
||||||
bool PruneConstraints(hGroup hg);
|
bool PruneConstraints(hGroup hg);
|
||||||
|
|
||||||
enum GenerateType {
|
enum GenerateType {
|
||||||
|
GENERATE_DIRTY,
|
||||||
GENERATE_ALL,
|
GENERATE_ALL,
|
||||||
GENERATE_REGEN,
|
GENERATE_REGEN,
|
||||||
GENERATE_UNTIL_ACTIVE,
|
GENERATE_UNTIL_ACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void GenerateAll(GenerateType type, bool andFindFree = false);
|
void GenerateAll(GenerateType type = GENERATE_DIRTY, bool andFindFree = false,
|
||||||
void GenerateAll(void);
|
bool genForBBox = false);
|
||||||
void GenerateAll(int first, int last, bool andFindFree = false, bool genForBBox = false);
|
|
||||||
void SolveGroup(hGroup hg, bool andFindFree);
|
void SolveGroup(hGroup hg, bool andFindFree);
|
||||||
void MarkDraggedParams(void);
|
void MarkDraggedParams(void);
|
||||||
void ForceReferences(void);
|
void ForceReferences(void);
|
||||||
|
|
|
@ -56,15 +56,10 @@ void TextWindow::ScreenToggleGroupShown(int link, uint32_t v) {
|
||||||
SS.GenerateAll();
|
SS.GenerateAll();
|
||||||
}
|
}
|
||||||
void TextWindow::ScreenShowGroupsSpecial(int link, uint32_t v) {
|
void TextWindow::ScreenShowGroupsSpecial(int link, uint32_t v) {
|
||||||
int i;
|
bool state = link == 's';
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(int i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
|
g->visible = state;
|
||||||
if(link == 's') {
|
|
||||||
g->visible = true;
|
|
||||||
} else {
|
|
||||||
g->visible = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TextWindow::ScreenActivateGroup(int link, uint32_t v) {
|
void TextWindow::ScreenActivateGroup(int link, uint32_t v) {
|
||||||
|
@ -105,8 +100,8 @@ void TextWindow::ShowListOfGroups(void) {
|
||||||
Printf(false, "%Ft shown ok group-name%E");
|
Printf(false, "%Ft shown ok group-name%E");
|
||||||
int i;
|
int i;
|
||||||
bool afterActive = false;
|
bool afterActive = false;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
Group *g = &(SK.group.elem[i]);
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
std::string s = g->DescriptionString();
|
std::string s = g->DescriptionString();
|
||||||
bool active = (g->h.v == SS.GW.activeGroup.v);
|
bool active = (g->h.v == SS.GW.activeGroup.v);
|
||||||
bool shown = g->visible;
|
bool shown = g->visible;
|
||||||
|
@ -260,14 +255,14 @@ void TextWindow::ScreenDeleteGroup(int link, uint32_t v) {
|
||||||
"before proceeding.");
|
"before proceeding.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SK.group.RemoveById(SS.TW.shown.group);
|
SK.group.RemoveById(hg);
|
||||||
// This is a major change, so let's re-solve everything.
|
// This is a major change, so let's re-solve everything.
|
||||||
SS.TW.ClearSuper();
|
SS.TW.ClearSuper();
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL);
|
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL);
|
||||||
}
|
}
|
||||||
void TextWindow::ShowGroupInfo(void) {
|
void TextWindow::ShowGroupInfo(void) {
|
||||||
Group *g = SK.group.FindById(shown.group);
|
Group *g = SK.GetGroup(shown.group);
|
||||||
const char *s = "???";
|
const char *s = "???";
|
||||||
|
|
||||||
if(shown.group.v == Group::HGROUP_REFERENCES.v) {
|
if(shown.group.v == Group::HGROUP_REFERENCES.v) {
|
||||||
|
@ -465,7 +460,7 @@ void TextWindow::ScreenAllowRedundant(int link, uint32_t v) {
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
}
|
}
|
||||||
void TextWindow::ShowGroupSolveInfo(void) {
|
void TextWindow::ShowGroupSolveInfo(void) {
|
||||||
Group *g = SK.group.FindById(shown.group);
|
Group *g = SK.GetGroup(shown.group);
|
||||||
if(g->IsSolvedOkay()) {
|
if(g->IsSolvedOkay()) {
|
||||||
// Go back to the default group info screen
|
// Go back to the default group info screen
|
||||||
shown.screen = SCREEN_GROUP_INFO;
|
shown.screen = SCREEN_GROUP_INFO;
|
||||||
|
|
|
@ -73,6 +73,9 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
dest.impEntity = {};
|
dest.impEntity = {};
|
||||||
ut->group.Add(&dest);
|
ut->group.Add(&dest);
|
||||||
}
|
}
|
||||||
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
|
ut->groupOrder.Add(&(SK.groupOrder.elem[i]));
|
||||||
|
}
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
for(i = 0; i < SK.request.n; i++) {
|
||||||
ut->request.Add(&(SK.request.elem[i]));
|
ut->request.Add(&(SK.request.elem[i]));
|
||||||
}
|
}
|
||||||
|
@ -94,6 +97,8 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
|
int i;
|
||||||
|
|
||||||
if(uk->cnt <= 0) oops();
|
if(uk->cnt <= 0) oops();
|
||||||
(uk->cnt)--;
|
(uk->cnt)--;
|
||||||
uk->write = WRAP(uk->write - 1, MAX_UNDO);
|
uk->write = WRAP(uk->write - 1, MAX_UNDO);
|
||||||
|
@ -101,11 +106,12 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
UndoState *ut = &(uk->d[uk->write]);
|
UndoState *ut = &(uk->d[uk->write]);
|
||||||
|
|
||||||
// Free everything in the main copy of the program before replacing it
|
// Free everything in the main copy of the program before replacing it
|
||||||
Group *g;
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
for(g = SK.group.First(); g; g = SK.group.NextAfter(g)) {
|
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||||
g->Clear();
|
g->Clear();
|
||||||
}
|
}
|
||||||
SK.group.Clear();
|
SK.group.Clear();
|
||||||
|
SK.groupOrder.Clear();
|
||||||
SK.request.Clear();
|
SK.request.Clear();
|
||||||
SK.constraint.Clear();
|
SK.constraint.Clear();
|
||||||
SK.param.Clear();
|
SK.param.Clear();
|
||||||
|
@ -113,6 +119,8 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
|
|
||||||
// And then do a shallow copy of the state from the undo list
|
// And then do a shallow copy of the state from the undo list
|
||||||
ut->group.MoveSelfInto(&(SK.group));
|
ut->group.MoveSelfInto(&(SK.group));
|
||||||
|
for(i = 0; i < ut->groupOrder.n; i++)
|
||||||
|
SK.groupOrder.Add(&ut->groupOrder.elem[i]);
|
||||||
ut->request.MoveSelfInto(&(SK.request));
|
ut->request.MoveSelfInto(&(SK.request));
|
||||||
ut->constraint.MoveSelfInto(&(SK.constraint));
|
ut->constraint.MoveSelfInto(&(SK.constraint));
|
||||||
ut->param.MoveSelfInto(&(SK.param));
|
ut->param.MoveSelfInto(&(SK.param));
|
||||||
|
@ -131,7 +139,7 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
|
|
||||||
// Activate the group that was active before.
|
// Activate the group that was active before.
|
||||||
Group *activeGroup = SK.group.FindById(SS.GW.activeGroup);
|
Group *activeGroup = SK.GetGroup(SS.GW.activeGroup);
|
||||||
activeGroup->Activate();
|
activeGroup->Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue