Skip to content

Commit fdbef2f

Browse files
authored
Fixes issue #2053 Updates the UI on switching mode without page refresh (#4089)
* UI element changes and Palette is regenerating * Fixed scrolling issue after mode change * Dynamically updating Record button and Save Menu based on mode * Fixed record button functionality * Fixed save button functionality after mode change * All options change together but after 2 clicks * Fixed clicking issue when changing mode. * Fixed some issues in toolbar * Reinitializing tooltips, helpful wheel and dropdowns after mode switch
1 parent 000e555 commit fdbef2f

File tree

3 files changed

+390
-174
lines changed

3 files changed

+390
-174
lines changed

js/activity.js

Lines changed: 119 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,38 +1392,26 @@ class Activity {
13921392
* Switches between beginner/advanced mode
13931393
*/
13941394
const doSwitchMode = (activity) => {
1395-
activity._doSwitchMode();
1396-
};
1397-
1398-
/**
1399-
* Switches between beginner and advanced modes.
1400-
* Displays a message prompting browser refresh to apply mode change.
1401-
* @private
1402-
*/
1403-
this._doSwitchMode = () => {
1404-
this.blocks.activeBlock = null;
1405-
const mode = this.storage.beginnerMode;
1406-
1407-
const MSGPrefix =
1408-
"<a href='#' " +
1409-
"onClick='window.location.reload()'" +
1410-
"onMouseOver='this.style.opacity = 0.5'" +
1411-
"onMouseOut='this.style.opacity = 1'>";
1412-
const MSGSuffix = "</a>";
1413-
1414-
if (mode === null || mode === undefined || mode === "true") {
1415-
this.textMsg(
1416-
_(MSGPrefix + _("Refresh your browser to change to advanced mode.") + MSGSuffix)
1417-
);
1418-
this.storage.setItem("beginnerMode", false);
1419-
} else {
1420-
this.textMsg(
1421-
_(MSGPrefix + _("Refresh your browser to change to beginner mode.") + MSGSuffix)
1422-
);
1423-
this.storage.setItem("beginnerMode", true);
1395+
// Update toolbar
1396+
activity.toolbar.renderSaveIcons(
1397+
activity.save.saveHTML.bind(activity.save),
1398+
doSVG,
1399+
activity.save.saveSVG.bind(activity.save),
1400+
activity.save.savePNG.bind(activity.save),
1401+
activity.save.saveWAV.bind(activity.save),
1402+
activity.save.saveLilypond.bind(activity.save),
1403+
activity.save.saveAbc.bind(activity.save),
1404+
activity.save.saveMxml.bind(activity.save),
1405+
activity.save.saveBlockArtwork.bind(activity.save)
1406+
);
1407+
1408+
// Regenerate palettes
1409+
if (activity.regeneratePalettes) {
1410+
activity.regeneratePalettes();
14241411
}
1425-
1426-
this.refreshCanvas();
1412+
1413+
// Force immediate canvas refresh
1414+
activity.refreshCanvas();
14271415
};
14281416

14291417
/*
@@ -6401,12 +6389,9 @@ class Activity {
64016389
this.toolbar.renderPlanetIcon(this.planet, doOpenSamples);
64026390
this.toolbar.renderMenuIcon(showHideAuxMenu);
64036391
this.toolbar.renderHelpIcon(showHelp);
6404-
this.toolbar.renderModeSelectIcon(doSwitchMode);
6392+
this.toolbar.renderModeSelectIcon(doSwitchMode, doRecordButton, doAnalytics, doOpenPlugin, deletePlugin, setScroller);
64056393
this.toolbar.renderRunSlowlyIcon(doSlowButton);
64066394
this.toolbar.renderRunStepIcon(doStepButton);
6407-
this.toolbar.renderAdvancedIcons(
6408-
doRecordButton, doAnalytics, doOpenPlugin, deletePlugin, setScroller
6409-
);
64106395
this.toolbar.renderMergeIcon(_doMergeLoad);
64116396
this.toolbar.renderRestoreIcon(restoreTrash);
64126397
if (_THIS_IS_MUSIC_BLOCKS_) {
@@ -6962,6 +6947,105 @@ class Activity {
69626947
}
69636948
};
69646949
}
6950+
6951+
/**
6952+
* Saves the current state locally
6953+
* @returns {void}
6954+
*/
6955+
saveLocally() {
6956+
try {
6957+
localStorage.setItem('beginnerMode', this.beginnerMode.toString());
6958+
} catch (e) {
6959+
console.error('Error saving to localStorage:', e);
6960+
}
6961+
}
6962+
6963+
/**
6964+
* Regenerates all palettes based on current mode
6965+
* @returns {void}
6966+
*/
6967+
regeneratePalettes() {
6968+
try {
6969+
// Store current palette positions
6970+
const palettePositions = {};
6971+
if (this.palettes && this.palettes.dict) {
6972+
for (const name in this.palettes.dict) {
6973+
const palette = this.palettes.dict[name];
6974+
if (palette && palette.container && typeof palette.container.x !== 'undefined') {
6975+
palettePositions[name] = {
6976+
x: palette.container.x,
6977+
y: palette.container.y,
6978+
visible: !!palette.visible
6979+
};
6980+
}
6981+
}
6982+
}
6983+
6984+
// Safely hide and clear existing palettes
6985+
if (!this.palettes) {
6986+
console.warn('Palettes object not initialized');
6987+
return;
6988+
}
6989+
6990+
if (typeof this.palettes.hide !== 'function') {
6991+
console.warn('Palettes hide method not available');
6992+
} else {
6993+
this.palettes.hide();
6994+
}
6995+
6996+
if (typeof this.palettes.clear !== 'function') {
6997+
console.warn('Palettes clear method not available');
6998+
// Fallback clear implementation
6999+
this.palettes.dict = {};
7000+
this.palettes.visible = false;
7001+
this.palettes.activePalette = null;
7002+
this.palettes.paletteObject = null;
7003+
} else {
7004+
this.palettes.clear();
7005+
}
7006+
7007+
// Reinitialize palettes
7008+
initPalettes(this.palettes);
7009+
7010+
// Reinitialize blocks
7011+
if (this.blocks) {
7012+
initBasicProtoBlocks(this);
7013+
}
7014+
7015+
// Restore palette positions
7016+
if (this.palettes && this.palettes.dict) {
7017+
for (const name in palettePositions) {
7018+
const palette = this.palettes.dict[name];
7019+
const pos = palettePositions[name];
7020+
7021+
if (palette && palette.container && pos) {
7022+
palette.container.x = pos.x;
7023+
palette.container.y = pos.y;
7024+
7025+
if (pos.visible) {
7026+
palette.showMenu(true);
7027+
}
7028+
}
7029+
}
7030+
}
7031+
7032+
// Update the palette display
7033+
if (this.palettes && typeof this.palettes.updatePalettes === 'function') {
7034+
this.palettes.updatePalettes();
7035+
}
7036+
7037+
// Update blocks
7038+
if (this.blocks && typeof this.blocks.updateBlockPositions === 'function') {
7039+
this.blocks.updateBlockPositions();
7040+
}
7041+
7042+
this.refreshCanvas();
7043+
7044+
} catch (e) {
7045+
console.error('Error regenerating palettes:', e);
7046+
this.errorMsg(_('Error regenerating palettes. Please refresh the page.'));
7047+
}
7048+
}
69657049
}
69667050

69677051
const activity = new Activity();

js/palette.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,53 @@ class Palettes {
385385
docById("palette").style.visibility = "visible";
386386
}
387387

388+
clear() {
389+
try {
390+
// First hide all palettes
391+
for (const name in this.dict) {
392+
if (this.dict.hasOwnProperty(name)) {
393+
const palette = this.dict[name];
394+
if (palette && typeof palette.hideMenu === 'function') {
395+
palette.hideMenu();
396+
}
397+
}
398+
}
399+
400+
// Remove the palette DOM element if it exists
401+
const paletteElement = docById("palette");
402+
if (paletteElement) {
403+
paletteElement.parentNode.removeChild(paletteElement);
404+
}
405+
406+
// Clear the dictionary and reset state
407+
this.dict = {};
408+
this.visible = false;
409+
this.activePalette = null;
410+
this.paletteObject = null;
411+
412+
// Recreate the palette using the original initialization code
413+
const element = document.createElement("div");
414+
element.id = "palette";
415+
element.setAttribute("class", "disable_highlighting");
416+
element.classList.add('flex-palette');
417+
element.setAttribute(
418+
"style",
419+
`position: fixed; z-index: 1000; left: 0px; top: ${60+this.top}px; overflow-y: auto;`
420+
);
421+
element.innerHTML =
422+
'<div style="height:fit-content"><table width ="' +
423+
1.5 * this.cellSize +
424+
'px"bgcolor="white"><thead><tr></tr></thead></table><table width ="' +
425+
4.5 * this.cellSize +
426+
'px"bgcolor="white"><thead><tr><td style= "width:28px"></tr></thead><tbody></tbody></table></div>';
427+
element.childNodes[0].style.border = `1px solid ${platformColor.selectorSelected}`;
428+
document.body.appendChild(element);
429+
430+
} catch (e) {
431+
console.error('Error clearing palettes:', e);
432+
}
433+
}
434+
388435
setBlocks(blocks) {
389436
this.blocks = blocks;
390437
return this;

0 commit comments

Comments
 (0)