@teachinglab/omd 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,9 +15,12 @@ import { jsvgLayoutGroup, jsvgEllipse, jsvgLine } from '@teachinglab/jsvg';
15
15
  * @extends omdEquationSequenceNode
16
16
  */
17
17
  export class omdStepVisualizer extends omdEquationSequenceNode {
18
- constructor(steps) {
18
+ constructor(steps, styling = {}) {
19
19
  super(steps);
20
20
 
21
+ // Store styling options
22
+ this.styling = styling || {};
23
+
21
24
  // Visual elements for step tracking
22
25
  this.stepDots = [];
23
26
  this.stepLines = [];
@@ -37,9 +40,32 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
37
40
 
38
41
  this.addChild(this.visualContainer);
39
42
  this._initializeVisualElements();
43
+
44
+ // Set default filter level to show only major steps (stepMark = 0)
45
+ // This ensures intermediate steps are hidden and expansion dots can be created
46
+ console.debug('Step visualizer: Setting default filter level to 0');
47
+ console.debug('Steps before filter:', this.steps.map(s => ({type: s.constructor.name, stepMark: s.stepMark, visible: s.visible})));
48
+
49
+ if (this.setFilterLevel && typeof this.setFilterLevel === 'function') {
50
+ this.setFilterLevel(0);
51
+ console.debug('Steps after filter:', this.steps.map(s => ({type: s.constructor.name, stepMark: s.stepMark, visible: s.visible})));
52
+ } else {
53
+ console.debug('setFilterLevel method not available');
54
+ }
55
+
40
56
  this.computeDimensions();
41
57
  this.updateLayout();
42
58
  }
59
+
60
+ /**
61
+ * Sets the fixed position for the step visualizer
62
+ * @param {number} position - The x position from the left edge where the visualizer should be positioned
63
+ */
64
+ setFixedVisualizerPosition(position) {
65
+ if (this.layoutManager) {
66
+ this.layoutManager.setFixedVisualizerPosition(position);
67
+ }
68
+ }
43
69
 
44
70
  /**
45
71
  * Force rebuild visual container (dots/lines) from scratch
@@ -88,8 +114,9 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
88
114
  const radius = getDotRadius(equation.stepMark ?? 0);
89
115
  const dot = new jsvgEllipse();
90
116
  dot.setWidthAndHeight(radius * 2, radius * 2);
91
- dot.setFillColor(omdColor.stepColor);
92
- dot.setStrokeColor(omdColor.stepColor);
117
+ const dotColor = this.styling.dotColor || omdColor.stepColor;
118
+ dot.setFillColor(dotColor);
119
+ dot.setStrokeColor(dotColor);
93
120
  dot.setStrokeWidth(this.lineWidth);
94
121
  dot.radius = radius;
95
122
 
@@ -114,7 +141,8 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
114
141
  */
115
142
  _createStepLine(fromIndex, toIndex) {
116
143
  const line = new jsvgLine();
117
- line.setStrokeColor(omdColor.stepColor);
144
+ const lineColor = this.styling.lineColor || omdColor.stepColor;
145
+ line.setStrokeColor(lineColor);
118
146
  line.setStrokeWidth(this.lineWidth);
119
147
 
120
148
  line.fromDotIndex = fromIndex;
@@ -151,30 +179,39 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
151
179
  * Override addStep to update visual elements when new steps are added
152
180
  */
153
181
  addStep(step, options = {}) {
154
- let createdDot=null;
182
+ // Call parent first to add the step properly
183
+ super.addStep(step, options);
184
+
185
+ // Now create visual elements for equation nodes only
155
186
  if (step instanceof omdEquationNode) {
156
- this.steps.push(step);
157
- const equations = this.steps.filter(s => s instanceof omdEquationNode);
158
- const newIndex = equations.length - 1;
159
- this.steps.pop();
160
- createdDot = this._createStepDot(step, newIndex);
161
- step.findAllNodes().forEach(node => {
162
- this.nodeToStepMap.set(node.id, newIndex);
163
- });
187
+ // Find the actual index of this equation in the steps array
188
+ const equationIndex = this.steps.filter(s => s instanceof omdEquationNode).indexOf(step);
164
189
 
165
- if (newIndex > 0) {
166
- this._createStepLine(newIndex - 1, newIndex);
190
+ if (equationIndex >= 0) {
191
+ const createdDot = this._createStepDot(step, equationIndex);
192
+
193
+ // Update the node to step mapping
194
+ step.findAllNodes().forEach(node => {
195
+ this.nodeToStepMap.set(node.id, equationIndex);
196
+ });
197
+
198
+ // Create connecting line if this isn't the first equation
199
+ if (equationIndex > 0) {
200
+ this._createStepLine(equationIndex - 1, equationIndex);
201
+ }
202
+
203
+ // After stepMark is set, adjust dot radius
204
+ if (createdDot) {
205
+ const radius = getDotRadius(step.stepMark ?? 0);
206
+ createdDot.setWidthAndHeight(radius * 2, radius * 2);
207
+ createdDot.radius = radius;
208
+ }
167
209
  }
168
210
  }
169
211
 
170
- super.addStep(step, options);
171
-
172
- // after stepMark is set, adjust dot radius
173
- if(createdDot){
174
- const radius=getDotRadius(step.stepMark??0);
175
- createdDot.setWidthAndHeight(radius*2,radius*2);
176
- createdDot.radius=radius;
177
- }
212
+ // Update layout after adding the step
213
+ this.computeDimensions();
214
+ this.updateLayout();
178
215
  }
179
216
 
180
217
  /**
@@ -191,11 +228,12 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
191
228
  super.computeDimensions();
192
229
  this.sequenceWidth = this.width;
193
230
 
194
- // Ensure stepDots is initialized before accessing its length
195
- if (this.stepDots && this.stepDots.length > 0) {
231
+ // Set width to include the fixed visualizer position plus visualizer width
232
+ if (this.stepDots && this.stepDots.length > 0 && this.layoutManager) {
196
233
  const containerWidth = this.dotRadius * 3;
197
- const visualWidth = this.visualSpacing + containerWidth;
198
- this.setWidthAndHeight(this.width + visualWidth, this.height);
234
+ const fixedVisualizerPosition = this.layoutManager.fixedVisualizerPosition || 250;
235
+ const totalWidth = fixedVisualizerPosition + this.visualSpacing + containerWidth;
236
+ this.setWidthAndHeight(totalWidth, this.height);
199
237
  }
200
238
  }
201
239
 
@@ -203,14 +241,26 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
203
241
  * Override updateLayout to update visual elements as well
204
242
  */
205
243
  updateLayout() {
244
+ console.debug('\n=== omdStepVisualizer.updateLayout START ===');
245
+ console.debug('Calling super.updateLayout()...');
206
246
  super.updateLayout();
207
247
 
208
248
  // Only update visual layout if layoutManager is initialized
209
249
  if (this.layoutManager) {
250
+ console.debug('LayoutManager found, updating visual elements...');
251
+ console.debug('Calling layoutManager.updateVisualLayout()...');
210
252
  this.layoutManager.updateVisualLayout();
253
+
254
+ console.debug('Calling layoutManager.updateVisualVisibility()...');
211
255
  this.layoutManager.updateVisualVisibility();
256
+
257
+ console.debug('Calling layoutManager.updateAllLinePositions()...');
212
258
  this.layoutManager.updateAllLinePositions();
259
+ } else {
260
+ console.debug('WARNING: LayoutManager not initialized!');
213
261
  }
262
+
263
+ console.debug('=== omdStepVisualizer.updateLayout END ===\n');
214
264
  }
215
265
 
216
266
  /**
@@ -313,12 +363,18 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
313
363
  this.activeDot = this.stepDots[dotIndex];
314
364
 
315
365
  const dot = this.stepDots[dotIndex];
316
- dot.setFillColor(omdColor.explainColor);
317
- dot.setStrokeColor(omdColor.explainColor);
366
+ const explainColor = this.styling.explainColor || omdColor.explainColor;
367
+ dot.setFillColor(explainColor);
368
+ dot.setStrokeColor(explainColor);
318
369
 
319
- this.setLineAboveColor(dotIndex, omdColor.explainColor);
370
+ this.setLineAboveColor(dotIndex, this.styling.explainColor || omdColor.explainColor);
320
371
  this.textBoxManager.createTextBoxForDot(dotIndex);
372
+
373
+ // Temporarily disable equation repositioning for simple dot state changes
374
+ const originalRepositioning = this.layoutManager.allowEquationRepositioning;
375
+ this.layoutManager.allowEquationRepositioning = false;
321
376
  this.layoutManager.updateVisualZOrder();
377
+ this.layoutManager.allowEquationRepositioning = originalRepositioning;
322
378
  }
323
379
 
324
380
  /**
@@ -329,14 +385,20 @@ export class omdStepVisualizer extends omdEquationSequenceNode {
329
385
  try {
330
386
  if (this.activeDotIndex !== -1) {
331
387
  const dot = this.stepDots[this.activeDotIndex];
332
- dot.setFillColor(omdColor.stepColor);
333
- dot.setStrokeColor(omdColor.stepColor);
388
+ const dotColor = this.styling.dotColor || omdColor.stepColor;
389
+ dot.setFillColor(dotColor);
390
+ dot.setStrokeColor(dotColor);
334
391
 
335
- this.setLineAboveColor(this.activeDotIndex, omdColor.stepColor);
392
+ this.setLineAboveColor(this.activeDotIndex, this.styling.lineColor || omdColor.stepColor);
336
393
  this.textBoxManager.removeTextBoxForDot(this.activeDotIndex);
337
394
 
338
395
  this.highlighting.clearHighlights();
396
+
397
+ // Temporarily disable equation repositioning for simple dot state changes
398
+ const originalRepositioning = this.layoutManager.allowEquationRepositioning;
399
+ this.layoutManager.allowEquationRepositioning = false;
339
400
  this.layoutManager.updateVisualZOrder();
401
+ this.layoutManager.allowEquationRepositioning = originalRepositioning;
340
402
 
341
403
  this.activeDot = null;
342
404
  this.activeDotIndex = -1;