Solvespace

Форк
0
/
undoredo.cpp 
153 строки · 4.5 Кб
1
//-----------------------------------------------------------------------------
2
// The user-visible undo/redo operation; whenever they change something, we
3
// record our state and push it on a stack, and we pop the stack when they
4
// select undo.
5
//
6
// Copyright 2008-2013 Jonathan Westhues.
7
//-----------------------------------------------------------------------------
8
#include "solvespace.h"
9

10
void SolveSpaceUI::UndoRemember() {
11
    unsaved = true;
12
    PushFromCurrentOnto(&undo);
13
    UndoClearStack(&redo);
14
    UndoEnableMenus();
15
}
16

17
void SolveSpaceUI::UndoUndo() {
18
    if(undo.cnt <= 0) return;
19

20
    PushFromCurrentOnto(&redo);
21
    PopOntoCurrentFrom(&undo);
22
    UndoEnableMenus();
23
}
24

25
void SolveSpaceUI::UndoRedo() {
26
    if(redo.cnt <= 0) return;
27

28
    PushFromCurrentOnto(&undo);
29
    PopOntoCurrentFrom(&redo);
30
    UndoEnableMenus();
31
}
32

33
void SolveSpaceUI::UndoEnableMenus() {
34
    SS.GW.undoMenuItem->SetEnabled(undo.cnt > 0);
35
    SS.GW.redoMenuItem->SetEnabled(redo.cnt > 0);
36
}
37

38
void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
39
    if(uk->cnt == MAX_UNDO) {
40
        UndoClearState(&(uk->d[uk->write]));
41
        // And then write in to this one again
42
    } else {
43
        (uk->cnt)++;
44
    }
45

46
    UndoState *ut = &(uk->d[uk->write]);
47
    *ut = {};
48
    ut->group.ReserveMore(SK.group.n);
49
    for(Group &src : SK.group) {
50
        // Shallow copy
51
        Group dest(src);
52
        // And then clean up all the stuff that needs to be a deep copy,
53
        // and zero out all the dynamic stuff that will get regenerated.
54
        dest.clean = false;
55
        dest.solved = {};
56
        dest.polyLoops = {};
57
        dest.bezierLoops = {};
58
        dest.bezierOpens = {};
59
        dest.polyError = {};
60
        dest.thisMesh = {};
61
        dest.runningMesh = {};
62
        dest.thisShell = {};
63
        dest.runningShell = {};
64
        dest.displayMesh = {};
65
        dest.displayOutlines = {};
66

67
        dest.remap = src.remap;
68

69
        dest.impMesh = {};
70
        dest.impShell = {};
71
        dest.impEntity = {};
72
        ut->group.Add(&dest);
73
    }
74
    for(auto &src : SK.groupOrder) { ut->groupOrder.Add(&src); }
75
    ut->request.ReserveMore(SK.request.n);
76
    for(auto &src : SK.request) { ut->request.Add(&src); }
77
    ut->constraint.ReserveMore(SK.constraint.n);
78
    for(auto &src : SK.constraint) {
79
        // Shallow copy
80
        Constraint dest(src);
81
        ut->constraint.Add(&dest);
82
    }
83
    ut->param.ReserveMore(SK.param.n);
84
    for(auto &src : SK.param) { ut->param.Add(&src); }
85
    ut->style.ReserveMore(SK.style.n);
86
    for(auto &src : SK.style) { ut->style.Add(&src); }
87
    ut->activeGroup = SS.GW.activeGroup;
88

89
    uk->write = WRAP(uk->write + 1, MAX_UNDO);
90
}
91

92
void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
93
    ssassert(uk->cnt > 0, "Cannot pop from empty undo stack");
94
    (uk->cnt)--;
95
    uk->write = WRAP(uk->write - 1, MAX_UNDO);
96

97
    UndoState *ut = &(uk->d[uk->write]);
98

99
    // Free everything in the main copy of the program before replacing it
100
    for(hGroup hg : SK.groupOrder) {
101
        Group *g = SK.GetGroup(hg);
102
        g->Clear();
103
    }
104
    SK.group.Clear();
105
    SK.groupOrder.Clear();
106
    SK.request.Clear();
107
    SK.constraint.Clear();
108
    SK.param.Clear();
109
    SK.style.Clear();
110

111
    // And then do a shallow copy of the state from the undo list
112
    ut->group.MoveSelfInto(&(SK.group));
113
    for(auto &gh : ut->groupOrder) { SK.groupOrder.Add(&gh); }
114
    ut->request.MoveSelfInto(&(SK.request));
115
    ut->constraint.MoveSelfInto(&(SK.constraint));
116
    ut->param.MoveSelfInto(&(SK.param));
117
    ut->style.MoveSelfInto(&(SK.style));
118
    SS.GW.activeGroup = ut->activeGroup;
119

120
    // No need to free it, since a shallow copy was made above
121
    *ut = {};
122

123
    // And reset the state everywhere else in the program, since the
124
    // sketch just changed a lot.
125
    SS.GW.ClearSuper();
126
    SS.TW.ClearSuper();
127
    SS.ReloadAllLinked(SS.saveFile);
128
    SS.GenerateAll(SolveSpaceUI::Generate::ALL);
129
    SS.ScheduleShowTW();
130

131
    // Activate the group that was active before.
132
    Group *activeGroup = SK.GetGroup(SS.GW.activeGroup);
133
    activeGroup->Activate();
134
}
135

136
void SolveSpaceUI::UndoClearStack(UndoStack *uk) {
137
    while(uk->cnt > 0) {
138
        uk->write = WRAP(uk->write - 1, MAX_UNDO);
139
        (uk->cnt)--;
140
        UndoClearState(&(uk->d[uk->write]));
141
    }
142
    *uk = {}; // for good measure
143
}
144

145
void SolveSpaceUI::UndoClearState(UndoState *ut) {
146
    for(auto &g : ut->group) { g.remap.clear(); }
147
    ut->group.Clear();
148
    ut->request.Clear();
149
    ut->constraint.Clear();
150
    ut->param.Clear();
151
    ut->style.Clear();
152
    *ut = {};
153
}
154

155

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.