//////////////////////////////////////////////////////////// //// © Microsoft. All rights reserved. //// //////////////////////////////////////////////////////////// /// /// /// /// /// /// /// (function (AppNS) { "use strict"; var CanvasManager = AppNS.CanvasManager; var WinUtils = WinJS.Utilities; var WinUI = WinJS.UI; var pointerDown; var ToolbarManager = WinJS.Namespace.defineWithParent(AppNS, "ToolbarManager", { showUndo: function () { }, hideUndo: function () { }, fragmentLoad: function (root, state) { WinUI.processAll(); var currentBrush = state.toolName || CanvasManager.ToolNames.Marker; var currentWidth = state.width || 10; var currentColorId = state.colorId || 0; // Middle color var currentColorString; var commmandBarHost = root.querySelector(".commandBar"); var ViewManagement = Windows.UI.ViewManagement; var appLayout = ViewManagement.ApplicationLayout.getForCurrentView(); var layoutState = ViewManagement.ApplicationLayoutState; var currentLayoutState = ViewManagement.ApplicationLayout.value; var redrawBrushPreviews = true; var redrawSizePreviews = true; var redrawOptionPreviews = true; var currentCommandName; var toolStateId = {}; var commandNames = { brush: "brush", size: "size", option: "option", more: "more", undo: "undo", clear: "clear", brushSnapped: "brush-snapped", sizeSnapped: "size-snapped", colorpicker: "colorpicker" }; // Set color picker full and fill widths to the remaining toolbar width, the numbers represent the space occupied in the toolbar by other elements, such as commands and margins. var colorPickerFullWidth = state.toolbarWidth - 613; var colorPickerFillWidth = state.toolbarWidth - 913; var unSnappedLeftMargin = 30; var spaceForLeftCommands = unSnappedLeftMargin + 300; var tool; // Style classes enum var classes = { colorPickerContainer: "colorpickerContainer", toolbarFlyout: "toolbar-flyout", brushPreview: "brush-preview", selectedPreview: "selectedPreview", brushWidthThick: "brush-width-thick", brushWidthThin: "brush-width-thin", panModeToggle: "pan-mode-toggle", commandToolbarUndo: "command_toolbar_undo", commandToolbarOption: "command_toolbar_option", commandToolbarSize: "command_toolbar_size", commandToolbarBrush: "command_toolbar_brush", commandToolbarMore: "command_toolbar_more", brushPreviewPrefix: "brush-preview-", sizePreviewPrefix: "size-preview-", optionPreviewPrefix: "option-preview-", winCommandBarHoriz: "win-commandBar-horiz", winMediaFlyoutBackground: "win-mediaFlyout-background", toolbarFlyoutBackground: "toolbar-flyout-background", canvasFlyoutBackground: "canvas-flyout-background", brushFlyout: "brush-flyout", sizeFlyout: "size-flyout", optionFlyout: "option-flyout", commandLabel: "commandLabel", moreFlyout: "more-flyout", undoButton: "undo-button", clearButton: "clear-button", appBar: "appBar" }; var appBar = document.getElementById(classes.appBar); var styles = { hidden: "hidden", visible: "visible" }; // Helper functions to hide and show elements var hideElement = function (e) { e.style.visibility = styles.hidden; }; var showElement = function (e) { e.style.visibility = styles.visible; }; var previewIndexTypes = { size: 0, option: 1 }; // Helper functions to hide and show dismiss targets var closeFlyouts = function () { dismissAllFlyouts(); restoreCommand(currentCommandName); currentCommandName = null; hideElement(toolbarFlyoutDismissArea); }; var hideToolbarDismissArea = function () { hideElement(toolbarFlyoutDismissArea); }; var showDismissAreas = function () { showElement(toolbarFlyoutDismissArea); }; var restoreCommand = function (commandName) { // If this is an option or brush command, restore it accordingly; otherwise restore it to original if (commandName === commandNames.option || commandName === commandNames.brush) { commandBar.setCommandState(commandName, toolStateId[currentBrush]); } else { commandBar.setCommandState(commandName, 0); } }; // Create and initialize dismiss area over toolbar var toolbarFlyoutDismissArea = document.createElement("div"); toolbarFlyoutDismissArea.className = classes.toolbarFlyoutBackground; toolbarFlyoutDismissArea.style.left = spaceForLeftCommands + "px"; toolbarFlyoutDismissArea.style.minHeight = appBar.offsetHeight + "px"; toolbarFlyoutDismissArea.style.minWidth = state.toolbarWidth - spaceForLeftCommands + "px"; hideElement(toolbarFlyoutDismissArea); toolbarFlyoutDismissArea.addEventListener("click", closeFlyouts); root.appendChild(toolbarFlyoutDismissArea); // Helper function to get persisted preview indexes var getPersistedPreviewIndex = function (indexType, toolName) { var index = null; switch (indexType) { case previewIndexTypes.size: if (state.currentSizePreviewIndexes) { index = state.currentSizePreviewIndexes[toolName]; } break; case previewIndexTypes.option: if (state.currentOptionPreviewIndexes) { index = state.currentOptionPreviewIndexes[toolName]; } break; } return index; } // Command groups var leftGroup = new WinUI.CommandGroup("leftGroup", WinUI.CommandStack.left); var rightGroup = new WinUI.CommandGroup("rightGroup", WinUI.CommandStack.right); var colorGroup = new WinUI.CommandGroup("colorGroup", WinUI.CommandStack.left); // Commands var moreCommand = new WinUI.Command(commandNames.more, [{ payload: { name: commandNames.more }, templateValues: { commandName: "More", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/moreIcon40px.{{state}}.png" } }, { payload: { name: commandNames.more }, templateValues: { commandName: "More", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/moreIcon40px.{{state}}.png" } }], 1); var toolName; var brushCommandStates = []; for (toolName in CanvasManager.ToolCards) { brushCommandStates.push({ payload: { name: commandNames.brush }, templateValues: { commandName: CanvasManager.ToolCards[toolName].label, imageUrl: "/Res/brushIcon40px.{{state}}.png" } }, { payload: { name: commandNames.brush }, templateValues: { commandName: CanvasManager.ToolCards[toolName].label, imageUrl: "/Res/brushIcon40px.press.png" } }); } brushCommandStates.push({ payload: { name: commandNames.brush }, templateValues: { commandName: "Pan mode", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/panmodeOptionIcon40px.{{state}}.png" } }, { payload: { name: commandNames.brush }, templateValues: { commandName: "Pan mode", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/panmodeOptionIcon40px.press.png" } }); var panModeStateId = brushCommandStates.length - 1; var brushCommand = new WinUI.Command(commandNames.brush, brushCommandStates, 1); var sizeCommand = new WinUI.Command(commandNames.size, [{ payload: { name: commandNames.size }, templateValues: { commandName: "Size", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/sizeIcon40px.{{state}}.png" } }, { payload: { name: commandNames.size }, templateValues: { commandName: "Size", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/sizeIcon40px.press.png" } }], 1); var brushCommandSnapped = new WinUI.Command(commandNames.brushSnapped, [{ payload: { name: commandNames.brush }, templateValues: { commandName: "Brush", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/brushIcon40px.{{state}}.png" } }, { payload: { name: commandNames.brush }, templateValues: { commandName: "Brush", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/brushIcon40px.press.png" } }], 1); var sizeCommandSnapped = new WinUI.Command(commandNames.sizeSnapped, [{ payload: { name: commandNames.size }, templateValues: { commandName: "Size", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/sizeIcon40px.{{state}}.png" } }, { payload: { name: commandNames.size }, templateValues: { commandName: "Size", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/sizeIcon40px.press.png" } }], 1); var optionCommandStates = []; for (toolName in CanvasManager.ToolCards) { optionCommandStates.push({ payload: { name: commandNames.option }, templateValues: { commandName: CanvasManager.ToolCards[toolName].optionLabel, imageUrl: "/Res/" + CanvasManager.ToolCards[toolName].optionKey + "OptionIcon40px.{{state}}.png" } }, { payload: { name: commandNames.option, toolName: toolName }, templateValues: { commandName: CanvasManager.ToolCards[toolName].optionLabel, imageUrl: "/Res/" + CanvasManager.ToolCards[toolName].optionKey + "OptionIcon40px.press.png" } }); } var optionCommand = new WinUI.Command(commandNames.option, optionCommandStates, 1); var undoCommand = new WinUI.Command(commandNames.undo, [{ payload: { name: commandNames.undo }, templateValues: { commandName: "Undo", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/undoIcon40px.{{state}}.png" } }, { payload: { name: commandNames.undo }, templateValues: { commandName: "Undo", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/undoIcon40px.press.png" } }], 1); var clearCommand = new WinUI.Command(commandNames.clear, [{ payload: { name: commandNames.clear }, templateValues: { commandName: "Clear", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/newIcon40px.{{state}}.png" } }, { payload: { name: commandNames.clear }, templateValues: { commandName: "Clear", // TODO: Win8Apps WORK 92: Add localization support imageUrl: "/Res/newIcon40px.press.png" } }], 1); // Color picker var colorPickerCommand = new WinUI.Command(commandNames.colorpicker, [{ payload: { name: commandNames.colorpicker }, templateValues: { commandName: "Color picker" } }], 1); colorPickerCommand.hostedElement = document.createElement("span"); colorPickerCommand.hostedElement.className = classes.colorPickerContainer; var colorPicker = new Microsoft.Paint.ColorPicker(colorPickerCommand.hostedElement, ToolbarManager.ToolbarColors, { height: 40, width: colorPickerFullWidth, hoverHeightGrowth: 2, hoverWidthGrowth: 1.75, bottomPosition: 20, selectedWidthGrowth: 1.25, selectedHeightGrowth: 1.25, affectedNeighbors: 3 }); // Disable automatic state change brushCommand.advanceState = false; sizeCommand.advanceState = false; brushCommandSnapped.advanceState = false; sizeCommandSnapped.advanceState = false; optionCommand.advanceState = false; undoCommand.advanceState = false; clearCommand.advanceState = false; colorPickerCommand.advanceState = false; moreCommand.advanceState = false; // Disable hiding the appbar on invoke brushCommand.hideOnInvoke = false; sizeCommand.hideOnInvoke = false; brushCommandSnapped.hideOnInvoke = false; sizeCommandSnapped.hideOnInvoke = false; optionCommand.hideOnInvoke = false; undoCommand.hideOnInvoke = false; clearCommand.hideOnInvoke = false; colorPickerCommand.hideOnInvoke = false; moreCommand.hideOnInvoke = false; // Add commands to groups leftGroup.addCommand(brushCommand); leftGroup.addCommand(sizeCommand); leftGroup.addCommand(optionCommand); rightGroup.addCommand(moreCommand); rightGroup.addCommand(undoCommand); rightGroup.addCommand(clearCommand); rightGroup.addCommand(brushCommandSnapped); rightGroup.addCommand(sizeCommandSnapped); colorGroup.addCommand(colorPickerCommand); var getCommandNamesForLayout = function (layout) { var commandNamesForLayout = null; if (layout === layoutState.fullScreen) { commandNamesForLayout = [commandNames.brush, commandNames.size, commandNames.option, commandNames.undo, commandNames.clear, commandNames.colorpicker]; } else if (layout === layoutState.filled) { commandNamesForLayout = [commandNames.brush, commandNames.size, commandNames.option, commandNames.colorpicker, commandNames.more]; } else if (layout === layoutState.snapped) { commandNamesForLayout = [commandNames.brush, commandNames.size]; } return commandNamesForLayout; }; // Instantiate command bar var commandBar = new WinUI.CommandBar(commmandBarHost, { orientation: "horizontal", commandGroups: [leftGroup, rightGroup, colorGroup], ariaLabel: "Toolbar", uniqueId: "toolbar" }); // Helper function to draw previews var drawPreview = function (preview, newColor, width, tool, optionKey, optionValue, offsetY) { preview.canvas.clear(); if (newColor) { var color = new AppNS.Painter.Graphics.Color(); color.fromString(newColor); preview.color = color; } if (tool) { preview.tool = tool; } if (width) { preview.tool.width = width; } if (optionKey && optionValue) { if (tool === CanvasManager.ToolNames.Brush) { preview.tool[optionKey] = (optionValue || preview.tool[optionKey]) / 5; } else { preview.tool[optionKey] = (optionValue || preview.tool[optionKey]); } } if (!offsetY) { offsetY = 25; } var startX = 50; var endX = 200; // Draw eraser preview on top of marker stroke if (tool === CanvasManager.ToolNames.Eraser) { // Draw the background var width = 20; var height = 2; var ctx = preview.canvas.context; ctx.globalCompositeOperation = "source-over"; ctx.fillStyle = preview.color.toString(); ctx.fillRect(width, height, preview.canvas.domCanvas.width - 2 * width, preview.canvas.domCanvas.height - 2 * height); // Draw the eraser stroke preview.drawStart({ x: startX + 10, y: offsetY - 3 }); preview.draw({ x: 130, y: offsetY + 3 }); preview.draw({ x: 170, y: offsetY - 3 }); preview.drawStop({ x: endX, y: offsetY + 3 }); } else { preview.drawStart({ x: startX, y: offsetY }); preview.draw({ x: startX + 5, y: offsetY }); preview.draw({ x: startX + 50, y: offsetY }); preview.draw({ x: startX + 75, y: offsetY }); preview.draw({ x: startX + 100, y: offsetY }); preview.draw({ x: startX + 110, y: offsetY }); preview.draw({ x: startX + 115, y: offsetY }); preview.draw({ x: startX + 120, y: offsetY }); preview.draw({ x: startX + 125, y: offsetY }); preview.draw({ x: endX, y: offsetY }); preview.draw({ x: endX + 5, y: offsetY }); preview.drawStop({ x: endX + 10, y: offsetY }); } }; // Flyouts var brushFlyout = document.getElementById(classes.brushFlyout); var sizeFlyout = document.getElementById(classes.sizeFlyout); var optionFlyout = document.getElementById(classes.optionFlyout); var moreFlyout = document.getElementById(classes.moreFlyout); brushFlyout.addEventListener("afterhide", hideToolbarDismissArea); sizeFlyout.addEventListener("afterhide", hideToolbarDismissArea); optionFlyout.addEventListener("afterhide", hideToolbarDismissArea); // Brush flyout var brushFlyoutPreviews = []; var brushFlyoutDomElements = {}; // Create canvases for brush previews var i = 0; var len = 0; // Add pan mode toggle var panModeDiv = document.createElement("div"); panModeDiv.className = classes.panModeToggle; panModeDiv.innerHTML = "Pan mode"; panModeDiv.addEventListener("MSPointerOut", function (event) { if (pointerDown) { WinUtils.removeClass(event.currentTarget, classes.selectedPreview); WinUtils.addClass(currentBrushPreview, classes.selectedPreview); pointerDown = false; } }); panModeDiv.addEventListener("MSPointerDown", function (event) { pointerDown = true; WinUtils.removeClass(currentBrushPreview, classes.selectedPreview); WinUtils.addClass(event.currentTarget, classes.selectedPreview); }); panModeDiv.addEventListener("MSPointerUp", function (event) { if (pointerDown) { AppNS.CanvasManager.canvasBlocked = true; AppNS.CanvasManager.canvasPannable = true; hideFlyout(brushFlyout); currentBrushPreview = event.currentTarget; commandBar.setCommandState(commandNames.brush, panModeStateId); pointerDown = false; closeFlyouts(); } }); brushFlyout.appendChild(panModeDiv); for (toolName in CanvasManager.ToolCards) { var brushPreviewCanvas = document.createElement("canvas"); brushFlyoutDomElements[toolName] = brushPreviewCanvas; brushFlyoutPreviews[i] = new AppNS.Painter.Painter(brushPreviewCanvas); toolStateId[toolName] = 2 * i; if (toolName === AppNS.CanvasManager.ToolNames.Crayon) { // Create texture image for crayon var textureImage = new Image(40, 40); var crayonPainter = brushFlyoutPreviews[i]; textureImage.addEventListener("load", function () { var card = CanvasManager.ToolCards[CanvasManager.ToolNames.Crayon]; var tool = new card.toolClass(); tool.setTexture(textureImage); tool.size = card.supportedSizes[card.defaultSizeIndex]; tool[card.optionKey] = card.optionValues[card.defaultOptionIndex]; crayonPainter.loadTool(tool, CanvasManager.ToolNames.Crayon); drawPreview(crayonPainter, AppNS.ToolbarManager.ToolbarColors[currentColorId], 30, CanvasManager.ToolNames.Crayon); }); textureImage.src = "../Controls/Paint/Res/crayon_texture.png"; } else { var card = CanvasManager.ToolCards[toolName]; var tool = new card.toolClass(); tool.size = card.supportedSizes[card.defaultSizeIndex]; if (toolName !== CanvasManager.ToolNames.Eraser) { tool[card.optionKey] = card.optionValues[card.defaultOptionIndex]; } brushFlyoutPreviews[i].loadTool(tool, toolName); } brushFlyoutPreviews[i].loadTool(tool, toolName); // Set default option value in tool if (toolName !== CanvasManager.ToolNames.Eraser) { tool[CanvasManager.ToolCards[toolName].optionKey] = CanvasManager.ToolCards[toolName].optionValues[CanvasManager.ToolCards[toolName].defaultOptionIndex]; } brushPreviewCanvas.id = classes.brushPreviewPrefix + toolName; brushPreviewCanvas.className = classes.brushPreview; brushPreviewCanvas.addEventListener("MSPointerOut", function (event) { if (pointerDown) { WinUtils.removeClass(event.currentTarget, classes.selectedPreview); WinUtils.addClass(currentBrushPreview, classes.selectedPreview); pointerDown = false; } }); brushPreviewCanvas.addEventListener("MSPointerDown", function (event) { pointerDown = true; WinUtils.removeClass(currentBrushPreview, classes.selectedPreview); WinUtils.addClass(event.currentTarget, classes.selectedPreview); }); brushPreviewCanvas.addEventListener("MSPointerUp", function (event) { if (pointerDown) { if (CanvasManager.canvasPannable) { AppNS.CanvasManager.canvasBlocked = false; AppNS.CanvasManager.canvasPannable = false; } var selectedTool = event.currentTarget.id.substr(14); if (currentBrush === CanvasManager.ToolNames.Eraser && selectedTool !== CanvasManager.ToolNames.Eraser) { showElement(document.getElementById(classes.commandToolbarOption)); } if (selectedTool === CanvasManager.ToolNames.Eraser) { hideElement(document.getElementById(classes.commandToolbarOption)); } else { commandBar.setCommandState(commandNames.option, toolStateId[selectedTool]); } // Set tool to be drawn with to the selected tool CanvasManager.tool = selectedTool; // Set the option command label if the selected tool is not the eraser and we are not in snap view if (selectedTool !== CanvasManager.ToolNames.Eraser && currentLayoutState !== layoutState.snapped) { document.querySelector("#" + classes.commandToolbarOption + " ." + classes.commandLabel).innerText = CanvasManager.ToolCards[selectedTool].optionLabel; // TODO: Win8Bugs 423768 CommandBar - Provide API to change command text redrawOptionPreviews = true; } // Remove previous highlights WinUtils.removeClass(currentSizePreview[currentBrush], classes.selectedPreview); if (currentBrush !== CanvasManager.ToolNames.Eraser) { WinUtils.removeClass(currentOptionPreview[currentBrush], classes.selectedPreview); } // If there's no previous selection for size, set the default if (!currentSizePreview[selectedTool]) { currentSizePreview[selectedTool] = sizeFlyoutDomElements[CanvasManager.ToolCards[selectedTool].defaultSizeIndex]; } // If there's no previous selection for option, set the default if (!currentOptionPreview[selectedTool] && selectedTool !== CanvasManager.ToolNames.Eraser) { currentOptionPreview[selectedTool] = optionFlyoutDomElements[CanvasManager.ToolCards[selectedTool].defaultOptionIndex]; } // Apply size and option selections WinUtils.addClass(currentSizePreview[selectedTool], classes.selectedPreview); if (selectedTool !== CanvasManager.ToolNames.Eraser) { WinUtils.addClass(currentOptionPreview[selectedTool], classes.selectedPreview); } // Apply brush selection currentBrushPreview = event.currentTarget; lastBrushPreview = event.currentTarget; redrawSizePreviews = true; commandBar.setCommandState(commandNames.brush, toolStateId[selectedTool]); currentBrush = selectedTool; closeFlyouts(); pointerDown = false; } }); brushFlyout.appendChild(brushPreviewCanvas); brushPreviewCanvas.height = brushPreviewCanvas.offsetHeight; brushPreviewCanvas.width = brushPreviewCanvas.offsetWidth; i++; } var currentBrushPreview; if (state.toolName) { currentBrushPreview = brushFlyoutDomElements[state.toolName]; } else { currentBrushPreview = brushFlyoutDomElements[currentBrush]; } WinUtils.addClass(currentBrushPreview, classes.selectedPreview); var lastBrushPreview = currentBrushPreview; // Size flyout var sizeFlyoutPreviews = []; var sizeFlyoutDomElements = []; // Create canvases for size previews for (i = 0, len = CanvasManager.ToolCards[currentBrush].supportedSizes.length; i < len; i++) { var sizePreviewCanvas = document.createElement("canvas"); sizeFlyoutDomElements[i] = sizePreviewCanvas; if (i < 3) { sizePreviewCanvas.className = classes.brushWidthThick; } else { sizePreviewCanvas.className = classes.brushWidthThin; } sizePreviewCanvas.id = classes.sizePreviewPrefix + i; sizeFlyoutPreviews[i] = new AppNS.Painter.Painter(sizePreviewCanvas); CanvasManager.loadAllTools(sizeFlyoutPreviews[i]); sizeFlyout.appendChild(sizePreviewCanvas); sizePreviewCanvas.addEventListener("MSPointerOut", function (event) { if (pointerDown) { WinUtils.removeClass(event.currentTarget, classes.selectedPreview); WinUtils.addClass(currentSizePreview[currentBrush], classes.selectedPreview); pointerDown = false; } }); sizePreviewCanvas.addEventListener("MSPointerDown", function (event) { pointerDown = true; WinUtils.removeClass(currentSizePreview[currentBrush], classes.selectedPreview); WinUtils.addClass(event.currentTarget, classes.selectedPreview); }); sizePreviewCanvas.addEventListener("MSPointerUp", function (event) { if (pointerDown) { var selectedSize = event.currentTarget.id.substr(13); CanvasManager.toolWidth = CanvasManager.ToolCards[currentBrush].supportedSizes[selectedSize]; currentWidth = CanvasManager.ToolCards[currentBrush].supportedSizes[selectedSize]; currentSizePreview[currentBrush] = event.currentTarget; closeFlyouts(); pointerDown = false; } }); sizePreviewCanvas.height = sizePreviewCanvas.offsetHeight; sizePreviewCanvas.width = sizePreviewCanvas.offsetWidth; } var currentSizePreview = {}; // Set default size preview if (state.currentSizePreviewIndexes) { for (toolName in state.currentSizePreviewIndexes) { currentSizePreview[toolName] = sizeFlyoutDomElements[getPersistedPreviewIndex(previewIndexTypes.size, toolName)]; } } else { currentSizePreview[currentBrush] = sizeFlyoutDomElements[CanvasManager.ToolCards[currentBrush].defaultSizeIndex]; } WinUtils.addClass(currentSizePreview[currentBrush], classes.selectedPreview); // Option flyout var optionFlyoutPreviews = []; var optionFlyoutDomElements = []; // Create canvases for option previews for (i = 0, len = CanvasManager.ToolCards[currentBrush].optionValues.length; i < len; i++) { var optionPreviewCanvas = document.createElement("canvas"); optionPreviewCanvas.id = classes.optionPreviewPrefix + i; optionFlyoutPreviews[i] = new AppNS.Painter.Painter(optionPreviewCanvas); optionFlyoutDomElements[i] = optionPreviewCanvas; CanvasManager.loadAllTools(optionFlyoutPreviews[i]); optionFlyout.appendChild(optionPreviewCanvas); optionPreviewCanvas.className = classes.brushWidthThin; optionPreviewCanvas.addEventListener("MSPointerOut", function (event) { if (pointerDown) { WinUtils.removeClass(event.currentTarget, classes.selectedPreview); WinUtils.addClass(currentOptionPreview[currentBrush], classes.selectedPreview); pointerDown = false; } }); optionPreviewCanvas.addEventListener("MSPointerDown", function (event) { pointerDown = true; WinUtils.removeClass(currentOptionPreview[currentBrush], classes.selectedPreview); WinUtils.addClass(event.currentTarget, classes.selectedPreview); }); optionPreviewCanvas.addEventListener("MSPointerUp", function (event) { if (pointerDown) { var selectedOption = event.currentTarget.id.substr(15); // Set new option if (CanvasManager.ToolCards[currentBrush].optionKey) { CanvasManager.setToolProperty(CanvasManager.ToolCards[currentBrush].optionKey, CanvasManager.ToolCards[currentBrush].optionValues[selectedOption]); } currentOptionPreview[currentBrush] = event.currentTarget; closeFlyouts(); pointerDown = false; } }); optionPreviewCanvas.height = optionPreviewCanvas.offsetHeight; optionPreviewCanvas.width = optionPreviewCanvas.offsetWidth; } var currentOptionPreview = {}; // Set default option preview if (state.currentOptionPreviewIndexes) { for (toolName in state.currentOptionPreviewIndexes) { currentOptionPreview[toolName] = optionFlyoutDomElements[getPersistedPreviewIndex(previewIndexTypes.option, toolName)]; } } else { currentOptionPreview[currentBrush] = optionFlyoutDomElements[CanvasManager.ToolCards[currentBrush].defaultOptionIndex]; } WinUtils.addClass(currentOptionPreview[currentBrush], classes.selectedPreview); // Helper function to render brush options on canvases var renderBrushOptions = function (previews, brush) { for (i = 0, len = previews.length; i < len; i++) { drawPreview(previews[i], null, null, brush, CanvasManager.ToolCards[brush].optionKey, CanvasManager.ToolCards[brush].optionValues[i]); } }; function hideUndo() { if (!CanvasManager.canUndo() && currentLayoutState === layoutState.fullScreen) { hideElement(document.getElementById(classes.commandToolbarUndo)); } } // Shows the undo button if in the fullscreen state and the canvas can undo function showUndo() { if (currentLayoutState === layoutState.fullScreen && CanvasManager.canUndo() && appBar.style.visibility === styles.visible) { showElement(document.getElementById(classes.commandToolbarUndo)); } } WinUI.getControl(appBar).addEventListener("beforeshow", function () { if (CanvasManager.canUndo() && currentLayoutState === layoutState.fullScreen) { showElement(document.getElementById(classes.commandToolbarUndo)); } }); AppNS.ToolbarManager.hideUndo = hideUndo; AppNS.ToolbarManager.showUndo = showUndo; // Command event listeners commandBar.addEventListener("commandinvoked", function (event) { // Set command state to clicked if (event.payload.name === commandNames.brush || event.payload.name === commandNames.option) { commandBar.setCommandState(event.payload.name, toolStateId[currentBrush] + 1); } else if (event.payload.name !== commandNames.undo && event.payload.name !== commandNames.clear) { commandBar.setCommandState(event.payload.name, 1); } if (currentCommandName) { restoreCommand(currentCommandName); } currentCommandName = event.payload.name; switch (currentCommandName) { case commandNames.brush: if (brushFlyout.style.visibility !== styles.visible) { dismissAllFlyouts(); showDismissAreas(); if (redrawBrushPreviews) { var i = 0; for (toolName in CanvasManager.ToolCards) { drawPreview(brushFlyoutPreviews[i], currentColorString, 30, toolName); i++; } redrawBrushPreviews = false; } showFlyout(brushFlyout, document.getElementById(classes.commandToolbarBrush), "top"); } else { closeFlyouts(); } break; case commandNames.size: if (sizeFlyout.style.visibility !== styles.visible) { dismissAllFlyouts(); showDismissAreas(); if (redrawSizePreviews) { for (var i = 0, len = CanvasManager.ToolCards[currentBrush].supportedSizes.length; i < len; i++) { if (i < 3) { drawPreview(sizeFlyoutPreviews[i], currentColorString, CanvasManager.ToolCards[currentBrush].supportedSizes[i], currentBrush, null, null, 50); } else { drawPreview(sizeFlyoutPreviews[i], currentColorString, CanvasManager.ToolCards[currentBrush].supportedSizes[i], currentBrush); } } redrawSizePreviews = false; } showFlyout(sizeFlyout, document.getElementById(classes.commandToolbarSize), "top"); } else { closeFlyouts(); } break; case commandNames.option: if (optionFlyout.style.visibility !== styles.visible) { dismissAllFlyouts(); showDismissAreas(); if (redrawOptionPreviews) { if (CanvasManager.ToolCards[currentBrush].optionKey) { for (var i = 0, len = CanvasManager.ToolCards[currentBrush].optionValues.length; i < len; i++) { drawPreview(optionFlyoutPreviews[i], currentColorString, 30, currentBrush, CanvasManager.ToolCards[currentBrush].optionKey, CanvasManager.ToolCards[currentBrush].optionValues[i]); } } redrawOptionPreviews = false; } showFlyout(optionFlyout, document.getElementById(classes.commandToolbarOption), "top"); } else { closeFlyouts(); } break; case commandNames.undo: CanvasManager.undoCanvas() break; case commandNames.clear: CanvasManager.clearCanvas(); break; case commandNames.more: if (moreFlyout.style.visibility !== styles.visible) { dismissAllFlyouts(); showDismissAreas(); showFlyout(moreFlyout, document.getElementById(classes.commandToolbarMore), "top"); } else { closeFlyouts(); } break; } }); document.getElementById(classes.undoButton).addEventListener("click", function () { CanvasManager.undoCanvas(); closeFlyouts(); }); document.getElementById(classes.clearButton).addEventListener("click", function () { CanvasManager.clearCanvas(); closeFlyouts(); }); colorPicker.addEventListener("colorselected", function (event) { CanvasManager.color = event.payload.color; currentColorId = event.payload.colorId; currentColorString = event.payload.color; redrawBrushPreviews = true; redrawSizePreviews = true; redrawOptionPreviews = true; }); // Preselect color colorPicker.selectColor(currentColorId); // Helper functions for showing and hiding flyouts var showFlyout = function (flyout, anchor, position) { WinUI.getControl(flyout).show(anchor, position); }; var hideFlyout = function (flyout) { WinUI.getControl(flyout).hide(); }; // Helper function to dismiss all flyouts var dismissAllFlyouts = function () { hideFlyout(brushFlyout); hideFlyout(sizeFlyout); hideFlyout(optionFlyout); }; // Helper function to restore brush and option commands to the selected state var restoreBrushCommands = function () { commandBar.setCommandState(commandNames.brush, toolStateId[currentBrush]); commandBar.setCommandState(commandNames.option, toolStateId[currentBrush]); }; var changeLayout = function (newLayout) { /// /// Changes the toolbar layout to a specified layout such as snap or fill /// /// /// layoutState to be changed to /// if (newLayout === layoutState.fullScreen) { panModeDiv.style.display = "none"; CanvasManager.canvasBlocked = false; CanvasManager.canvasPannable = false; WinUtils.removeClass(currentBrushPreview, classes.selectedPreview); WinUtils.addClass(lastBrushPreview, classes.selectedPreview); currentBrushPreview = lastBrushPreview; colorPicker.width = colorPickerFullWidth; commandBar.setCommands(getCommandNamesForLayout(layoutState.fullScreen)) .then(restoreBrushCommands); } else { panModeDiv.style.display = "block"; if (newLayout === layoutState.snapped) { if (currentLayoutState !== layoutState.snapped) { // Center command icons document.querySelector(".win-commandBar-horiz").style.marginLeft = (window.innerWidth - 200) / 2 + "px"; } commandBar.setCommands(getCommandNamesForLayout(layoutState.snapped)) .then(restoreBrushCommands); } else if (newLayout === layoutState.filled) { colorPicker.width = colorPickerFillWidth; commandBar.setCommands(getCommandNamesForLayout(layoutState.filled)) .then(restoreBrushCommands); } } if (currentLayoutState === layoutState.snapped && newLayout !== currentLayoutState) { document.querySelector("." + classes.winCommandBarHoriz).style.marginLeft = unSnappedLeftMargin + "px"; } currentLayoutState = newLayout; }; // Set commands if (currentLayoutState === layoutState.fullScreen) { commandBar.setCommands(getCommandNamesForLayout(layoutState.fullScreen)); } else { changeLayout(currentLayoutState); } // Hide undo if no undo data was persisted if (!state.undoBlobNames && currentLayoutState === layoutState.fullScreen) { hideElement(document.getElementById(classes.commandToolbarUndo)); } // Initialize commands with persisted state if (state.toolName) { var commandStateId = toolStateId[state.toolName]; commandBar.setCommandState(commandNames.brush, commandStateId); if (state.toolName !== CanvasManager.ToolNames.Eraser) { commandBar.setCommandState(commandNames.option, commandStateId); } } // Show appbar commandBar.show(); WinJS.Namespace.defineWithParent(AppNS, "ToolbarManager", { toolName: { get: function () { /// /// Gets the current tool name /// /// /// String /// return currentBrush; } }, colorId: { get: function () { /// /// Gets the current color id /// /// /// Number /// return currentColorId; } }, optionValueIndex: { get: function () { /// /// Gets the current option value index for the current tool /// /// /// Number /// return parseInt(currentOptionPreview[currentBrush].id.substr(15)); } }, currentSizePreviewIndexes: { get: function () { /// /// Gets the an object with the current size index for all the tools /// /// /// Object. Keys are tool names, values are the size index for that tool /// var sizePreviewIndexes = {}; for (toolName in currentSizePreview) { sizePreviewIndexes[toolName] = parseInt(currentSizePreview[toolName].id.substr(13)); } return sizePreviewIndexes; } }, currentOptionPreviewIndexes: { get: function () { /// /// Gets the an object with the current size index for all the tools /// /// /// An object in which keys are tool names and values are the size index for that tool /// var optionPreviewIndexes = {}; for (toolName in currentOptionPreview) { optionPreviewIndexes[toolName] = parseInt(currentOptionPreview[toolName].id.substr(15)); } return optionPreviewIndexes; } }, changeLayout: changeLayout }); } }); })(Microsoft.Paint);