From 94ee8a8cf442d49f3817fdcbbd33dc45009e9211 Mon Sep 17 00:00:00 2001 From: John Thomson Date: Fri, 12 Dec 2025 11:06:31 -0600 Subject: [PATCH] Fix updating BG color control for buttons (BL-15532) --- .../bookEdit/js/CanvasElementManager.ts | 15 +++-- .../bookEdit/toolbox/canvas/canvasTool.tsx | 66 +++++++++++-------- .../bookEdit/toolbox/games/GameTool.tsx | 2 +- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/BloomBrowserUI/bookEdit/js/CanvasElementManager.ts b/src/BloomBrowserUI/bookEdit/js/CanvasElementManager.ts index 15a15fc219e8..143c7eeda616 100644 --- a/src/BloomBrowserUI/bookEdit/js/CanvasElementManager.ts +++ b/src/BloomBrowserUI/bookEdit/js/CanvasElementManager.ts @@ -122,7 +122,7 @@ export class CanvasElementManager { // identifies the source that requested the notification; allows us to remove the // right one when no longer needed, and prevent multiple notifiers to the same client. id: string; - handler: (x: BubbleSpec | undefined) => void; + handler: (x: Bubble | undefined) => void; }[] = []; // These variables are used by the canvas element's onmouse* event handlers @@ -3047,9 +3047,9 @@ export class CanvasElementManager { } public doNotifyChange() { - const spec = this.getSelectedFamilySpec(); + const bubble = this.getPatriarchBubbleOfActiveElement(); this.thingsToNotifyOfCanvasElementChange.forEach((f) => - f.handler(spec), + f.handler(bubble), ); } @@ -4438,7 +4438,7 @@ export class CanvasElementManager { public requestCanvasElementChangeNotification( id: string, - notifier: (bubble: BubbleSpec | undefined) => void, + notifier: (bubble: Bubble | undefined) => void, ): void { this.detachCanvasElementChangeNotification(id); this.thingsToNotifyOfCanvasElementChange.push({ @@ -4470,9 +4470,12 @@ export class CanvasElementManager { return this.updateBubbleWithPropsHelper(activeBubble, newBubbleProps); } - public updateSelectedFamilyBubbleSpec(newBubbleProps: BubbleSpecPattern) { + public updateSelectedFamilyBubbleSpec( + newBubbleProps: BubbleSpecPattern, + ): Bubble { const parentBubble = this.getPatriarchBubbleOfActiveElement(); - return this.updateBubbleWithPropsHelper(parentBubble, newBubbleProps); + this.updateBubbleWithPropsHelper(parentBubble, newBubbleProps); + return parentBubble!; } private updateBubbleWithPropsHelper( diff --git a/src/BloomBrowserUI/bookEdit/toolbox/canvas/canvasTool.tsx b/src/BloomBrowserUI/bookEdit/toolbox/canvas/canvasTool.tsx index 52113a6b9f1d..79e19ad62665 100644 --- a/src/BloomBrowserUI/bookEdit/toolbox/canvas/canvasTool.tsx +++ b/src/BloomBrowserUI/bookEdit/toolbox/canvas/canvasTool.tsx @@ -10,7 +10,7 @@ import { CanvasElementManager, ITextColorInfo, } from "../../js/CanvasElementManager"; -import { BubbleSpec, TailSpec } from "comicaljs"; +import { Bubble, BubbleSpec, TailSpec } from "comicaljs"; import { ToolBottomHelpLink } from "../../../react_components/helpLink"; import FormControl from "@mui/material/FormControl"; import Select from "@mui/material/Select"; @@ -154,9 +154,9 @@ const CanvasToolControls: React.FunctionComponent = () => { // If canvasElementType is not undefined, corresponds to the active canvas element's family. // Otherwise, corresponds to the most recently active canvas element's family. - const [currentFamilySpec, setCurrentFamilySpec] = useState< - BubbleSpec | undefined - >(undefined); + const [currentBubble, setCurrentBubble] = useState( + undefined, + ); // Callback to initialize bubbleEditing and get the initial bubbleSpec const bubbleSpecInitialization = () => { @@ -172,18 +172,18 @@ const CanvasToolControls: React.FunctionComponent = () => { canvasElementManager.turnOnCanvasElementEditing(); deselectVideoContainers(); - const bubbleSpec = canvasElementManager.getSelectedFamilySpec(); + const bubble = canvasElementManager.getPatriarchBubbleOfActiveElement(); // The callback function is (currently) called when switching between canvas elements, but is not called // if the tail spec changes, or for style and similar changes to the canvas element that are initiated by React. canvasElementManager.requestCanvasElementChangeNotification( "canvasElement", - (bubble: BubbleSpec | undefined) => { - setCurrentFamilySpec(bubble); + (bubble: Bubble | undefined) => { + setCurrentBubble(bubble); }, ); - setCurrentFamilySpec(bubbleSpec); + setCurrentBubble(bubble); }; // Enhance: if we don't want to have a static, or don't want @@ -199,19 +199,24 @@ const CanvasToolControls: React.FunctionComponent = () => { // Reset UI when current bubble spec changes (e.g. user clicked on a bubble). useEffect(() => { - if (currentFamilySpec) { - setStyle(currentFamilySpec.style); + if (currentBubble) { + const currentBubbleSpec = currentBubble.getBubbleSpec(); + setStyle(currentBubbleSpec.style); setShowTailChecked( - currentFamilySpec.tails && currentFamilySpec.tails.length > 0, + currentBubbleSpec.tails && currentBubbleSpec.tails.length > 0, ); setIsRoundedCornersChecked( - !!currentFamilySpec.cornerRadiusX && - !!currentFamilySpec.cornerRadiusY && - currentFamilySpec.cornerRadiusX > 0 && - currentFamilySpec.cornerRadiusY > 0, + !!currentBubbleSpec.cornerRadiusX && + !!currentBubbleSpec.cornerRadiusY && + currentBubbleSpec.cornerRadiusX > 0 && + currentBubbleSpec.cornerRadiusY > 0, ); - setOutlineColor(currentFamilySpec.outerBorderColor); - const backColor = getBackgroundColorValue(currentFamilySpec); + setOutlineColor(currentBubbleSpec.outerBorderColor); + const isButton = + currentBubble.content.classList.contains(kBloomButtonClass); + const backColor = isButton + ? currentBubble.content.style.backgroundColor + : getBackgroundColorValue(currentBubbleSpec); const newSwatch = getColorInfoFromSpecialNameOrColorString(backColor); setBackgroundColorSwatch(newSwatch); @@ -233,7 +238,7 @@ const CanvasToolControls: React.FunctionComponent = () => { } else { setCanvasElementType(undefined); } - }, [currentFamilySpec]); + }, [currentBubble]); const getBubbleType = ( mgr: CanvasElementManager | undefined, @@ -262,7 +267,8 @@ const CanvasToolControls: React.FunctionComponent = () => { }; // BL-8537: If we are choosing "caption" style, we make sure that the background color is opaque. - const backgroundColorArray = currentFamilySpec?.backgroundColors; + const backgroundColorArray = + currentBubble?.getBubbleSpec()?.backgroundColors; if ( newStyle === "caption" && backgroundColorArray && @@ -279,12 +285,12 @@ const CanvasToolControls: React.FunctionComponent = () => { newBubbleProps["backgroundColors"] = backgroundColorArray; } - const newSpec = + const bubble = canvasElementManager.updateSelectedFamilyBubbleSpec( newBubbleProps, ); // We do this because the new style's spec may affect Show Tail, or background opacity too. - setCurrentFamilySpec(newSpec); + setCurrentBubble(bubble); } }; @@ -384,8 +390,8 @@ const CanvasToolControls: React.FunctionComponent = () => { const updateReactFromComical = ( canvasElementManager: CanvasElementManager, ) => { - const newSpec = canvasElementManager.getSelectedFamilySpec(); - setCurrentFamilySpec(newSpec); + const bubble = canvasElementManager.getPatriarchBubbleOfActiveElement(); + setCurrentBubble(bubble); }; // Callback when outline color of the bubble is changed @@ -510,7 +516,7 @@ const CanvasToolControls: React.FunctionComponent = () => { // BL-8537 Because of the black shadow background, partly transparent backgrounds don't work for // captions. We'll use this to tell the color chooser not to show the alpha option. - const isCaption = currentFamilySpec?.style === "caption"; + const isCaption = currentBubble?.getBubbleSpec()?.style === "caption"; const backgroundColorControl = ( @@ -669,7 +675,7 @@ const CanvasToolControls: React.FunctionComponent = () => { checked={isRoundedCornersChecked} disabled={ !styleSupportsRoundedCorners( - currentFamilySpec, + currentBubble?.getBubbleSpec(), ) } onCheckChanged={(newValue) => { @@ -682,7 +688,9 @@ const CanvasToolControls: React.FunctionComponent = () => { @@ -709,7 +717,11 @@ const CanvasToolControls: React.FunctionComponent = () => { "canvasElement-options-dropdown-menu", }} onChange={(event) => { - if (isBubble(currentFamilySpec)) { + if ( + isBubble( + currentBubble?.getBubbleSpec(), + ) + ) { handleOutlineColorChanged(event); setIsOutlineColorSelectOpen(false); } diff --git a/src/BloomBrowserUI/bookEdit/toolbox/games/GameTool.tsx b/src/BloomBrowserUI/bookEdit/toolbox/games/GameTool.tsx index ee964b5a0d8a..917b1821a26d 100644 --- a/src/BloomBrowserUI/bookEdit/toolbox/games/GameTool.tsx +++ b/src/BloomBrowserUI/bookEdit/toolbox/games/GameTool.tsx @@ -865,7 +865,7 @@ const DragActivityControls: React.FunctionComponent<{ // requester with the key dragActivityTool, so it won't be a large leak. canvasElementManager?.requestCanvasElementChangeNotification( "dragActivityTool", - (b) => setBubble(b), + (b) => setBubble(b?.getBubbleSpec()), ); }, [props.pageGeneration, canvasElementManager]); useEffect(() => {