1
2
3 #include "toonz/columnfan.h"
4 #include "toonz/preferences.h"
5
6 // TnzCore includes
7 #include "tstream.h"
8
9 // STD includss
10 #include <assert.h>
11
12 //=============================================================================
13 // ColumnFan
14
ColumnFan()15 ColumnFan::ColumnFan()
16 : m_firstFreePos(0)
17 , m_unfolded(74)
18 , m_folded(9)
19 , m_cameraActive(true)
20 , m_cameraColumnDim(22) {}
21
22 //-----------------------------------------------------------------------------
23
setDimensions(int unfolded,int cameraColumn)24 void ColumnFan::setDimensions(int unfolded, int cameraColumn) {
25 m_unfolded = unfolded;
26 m_cameraColumnDim = cameraColumn;
27 // folded always 9
28 update();
29 }
30
31 //-----------------------------------------------------------------------------
32
update()33 void ColumnFan::update() {
34 int lastPos = -m_unfolded;
35 bool lastActive = true;
36 int m = m_columns.size();
37 int i;
38 for (i = 0; i < m; i++) {
39 bool active = m_columns[i].m_active;
40 if (lastActive)
41 lastPos += m_unfolded;
42 else if (active)
43 lastPos += m_folded;
44 m_columns[i].m_pos = lastPos;
45 lastActive = active;
46 }
47 m_firstFreePos = lastPos + (lastActive ? m_unfolded : m_folded);
48 m_table.clear();
49 for (i = 0; i < m; i++)
50 if (m_columns[i].m_active)
51 m_table[m_columns[i].m_pos + m_unfolded - 1] = i;
52 else if (i + 1 < m && m_columns[i + 1].m_active)
53 m_table[m_columns[i + 1].m_pos - 1] = i;
54 else if (i + 1 == m)
55 m_table[m_firstFreePos - 1] = i;
56 }
57
58 //-----------------------------------------------------------------------------
59
layerAxisToCol(int coord) const60 int ColumnFan::layerAxisToCol(int coord) const {
61 if (Preferences::instance()->isXsheetCameraColumnVisible()) {
62 int firstCol =
63 m_cameraActive
64 ? m_cameraColumnDim
65 : ((m_columns.size() > 0 && !m_columns[0].m_active) ? 0 : m_folded);
66 if (coord < firstCol) return -1;
67 coord -= firstCol;
68 }
69 if (coord < m_firstFreePos) {
70 std::map<int, int>::const_iterator it = m_table.lower_bound(coord);
71 if (it == m_table.end()) return -3;
72 assert(it != m_table.end());
73 return it->second;
74 } else
75 return m_columns.size() + (coord - m_firstFreePos) / m_unfolded;
76 }
77
78 //-----------------------------------------------------------------------------
79
colToLayerAxis(int col) const80 int ColumnFan::colToLayerAxis(int col) const {
81 int m = m_columns.size();
82 int firstCol = 0;
83 if (Preferences::instance()->isXsheetCameraColumnVisible()) {
84 if (col < -1) return -m_cameraColumnDim;
85 if (col < 0) return 0;
86 firstCol =
87 m_cameraActive
88 ? m_cameraColumnDim
89 : ((m_columns.size() > 0 && !m_columns[0].m_active) ? 0 : m_folded);
90 }
91 if (col >= 0 && col < m)
92 return firstCol + m_columns[col].m_pos;
93 else
94 return firstCol + m_firstFreePos + (col - m) * m_unfolded;
95 }
96
97 //-----------------------------------------------------------------------------
98
activate(int col)99 void ColumnFan::activate(int col) {
100 int m = m_columns.size();
101 if (col < 0) {
102 m_cameraActive = true;
103 return;
104 }
105 if (col < m) {
106 m_columns[col].m_active = true;
107 int i;
108 for (i = m - 1; i >= 0 && m_columns[i].m_active; i--) {
109 }
110 i++;
111 if (i < m) {
112 m = i;
113 m_columns.erase(m_columns.begin() + i, m_columns.end());
114 }
115 }
116 update();
117 }
118
119 //-----------------------------------------------------------------------------
120
deactivate(int col)121 void ColumnFan::deactivate(int col) {
122 if (col < 0) {
123 m_cameraActive = false;
124 return;
125 }
126 while ((int)m_columns.size() <= col) m_columns.push_back(Column());
127 m_columns[col].m_active = false;
128 update();
129 }
130
131 //-----------------------------------------------------------------------------
132
isActive(int col) const133 bool ColumnFan::isActive(int col) const {
134 return 0 <= col && col < (int)m_columns.size()
135 ? m_columns[col].m_active
136 : col < 0 ? m_cameraActive : true;
137 }
138
139 //-----------------------------------------------------------------------------
140
isEmpty() const141 bool ColumnFan::isEmpty() const { return m_columns.empty(); }
142
143 //-----------------------------------------------------------------------------
144
copyFoldedStateFrom(const ColumnFan & from)145 void ColumnFan::copyFoldedStateFrom(const ColumnFan &from) {
146 m_cameraActive = from.m_cameraActive;
147 for (int i = 0, n = (int)from.m_columns.size(); i < n; i++)
148 if (!from.isActive(i)) deactivate(i);
149 }
150
151 //-----------------------------------------------------------------------------
152
saveData(TOStream & os)153 void ColumnFan::saveData(
154 TOStream &os) { // only saves indices of folded columns
155 int index, n = (int)m_columns.size();
156 for (index = 0; index < n;) {
157 while (index < n && m_columns[index].m_active) index++;
158 if (index < n) {
159 int firstIndex = index;
160 os << index;
161 index++;
162 while (index < n && !m_columns[index].m_active) index++;
163 os << index - firstIndex;
164 }
165 }
166 }
167
168 //-----------------------------------------------------------------------------
169
loadData(TIStream & is)170 void ColumnFan::loadData(TIStream &is) {
171 m_columns.clear();
172 m_table.clear();
173 m_firstFreePos = 0;
174 while (!is.eos()) {
175 int index = 0, count = 0;
176 is >> index >> count;
177 int j;
178 for (j = 0; j < count; j++) deactivate(index + j);
179 }
180 }
181
182 //-----------------------------------------------------------------------------
183
rollLeftFoldedState(int index,int count)184 void ColumnFan::rollLeftFoldedState(int index, int count) {
185 assert(index >= 0);
186 int columnCount = m_columns.size();
187 if (columnCount <= index) return;
188 if (index + count - 1 > columnCount) count = columnCount - index + 1;
189 if (count < 2) return;
190
191 int i = index, j = index + count - 1;
192 bool tmp = isActive(i);
193
194 for (int k = i; k < j; ++k) {
195 if (isActive(k) && !isActive(k + 1))
196 deactivate(k);
197 else if (!isActive(k) && isActive(k + 1))
198 activate(k);
199 }
200 if (isActive(j) && !tmp)
201 deactivate(j);
202 else if (!isActive(j) && tmp)
203 activate(j);
204
205 update();
206 }
207
208 //-----------------------------------------------------------------------------
209
rollRightFoldedState(int index,int count)210 void ColumnFan::rollRightFoldedState(int index, int count) {
211 assert(index >= 0);
212
213 int columnCount = m_columns.size();
214 if (columnCount <= index) return;
215 if (index + count - 1 > columnCount) count = columnCount - index + 1;
216 if (count < 2) return;
217
218 int i = index, j = index + count - 1;
219 bool tmp = isActive(j);
220
221 for (int k = j; k > i; --k) {
222 if (isActive(k) && !isActive(k - 1))
223 deactivate(k);
224 else if (!isActive(k) && isActive(k - 1))
225 activate(k);
226 }
227 if (isActive(i) && !tmp)
228 deactivate(i);
229 else if (!isActive(i) && tmp)
230 activate(i);
231
232 update();
233 }
234