| /* |
| * Copyright (C) 2017 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| WI.ShaderProgramContentView = class ShaderProgramContentView extends WI.ContentView |
| { |
| constructor(shaderProgram) |
| { |
| console.assert(shaderProgram instanceof WI.ShaderProgram); |
| |
| super(shaderProgram); |
| |
| let contentDidChangeDebouncer = new Debouncer((event) => { |
| this._contentDidChange(event); |
| }); |
| |
| this.element.classList.add("shader-program"); |
| |
| let createEditor = (shaderType) => { |
| let textEditor = new WI.TextEditor; |
| textEditor.readOnly = false; |
| textEditor.addEventListener(WI.TextEditor.Event.Focused, this._editorFocused, this); |
| textEditor.addEventListener(WI.TextEditor.Event.NumberOfSearchResultsDidChange, this._numberOfSearchResultsDidChange, this); |
| textEditor.addEventListener(WI.TextEditor.Event.ContentDidChange, (event) => { |
| contentDidChangeDebouncer.delayForTime(250, event); |
| }, this); |
| textEditor.element.classList.add("shader"); |
| |
| let shaderTypeContainer = textEditor.element.insertAdjacentElement("afterbegin", document.createElement("div")); |
| shaderTypeContainer.classList.add("type-title"); |
| |
| switch (shaderType) { |
| case WI.ShaderProgram.ShaderType.Vertex: |
| shaderTypeContainer.textContent = WI.UIString("Vertex Shader"); |
| textEditor.mimeType = "x-shader/x-vertex"; |
| textEditor.element.classList.add("vertex"); |
| break; |
| |
| case WI.ShaderProgram.ShaderType.Fragment: |
| shaderTypeContainer.textContent = WI.UIString("Fragment Shader"); |
| textEditor.mimeType = "x-shader/x-fragment"; |
| textEditor.element.classList.add("fragment"); |
| break; |
| } |
| |
| this.addSubview(textEditor); |
| return textEditor; |
| }; |
| |
| this._vertexEditor = createEditor(WI.ShaderProgram.ShaderType.Vertex); |
| this._fragmentEditor = createEditor(WI.ShaderProgram.ShaderType.Fragment); |
| this._lastActiveEditor = this._vertexEditor; |
| } |
| |
| // Protected |
| |
| shown() |
| { |
| super.shown(); |
| |
| this._vertexEditor.shown(); |
| this._fragmentEditor.shown(); |
| |
| this.representedObject.requestVertexShaderSource((content) => { |
| this._vertexEditor.string = content || ""; |
| }); |
| |
| this.representedObject.requestFragmentShaderSource((content) => { |
| this._fragmentEditor.string = content || ""; |
| }); |
| } |
| |
| hidden() |
| { |
| this._vertexEditor.hidden(); |
| this._fragmentEditor.hidden(); |
| |
| super.hidden(); |
| } |
| |
| closed() |
| { |
| this._vertexEditor.close(); |
| this._fragmentEditor.close(); |
| |
| super.closed(); |
| } |
| |
| get supportsSave() |
| { |
| return true; |
| } |
| |
| get saveData() |
| { |
| let filename = WI.UIString("Shader"); |
| if (this._lastActiveEditor === this._vertexEditor) |
| filename = WI.UIString("Vertex"); |
| else if (this._lastActiveEditor === this._fragmentEditor) |
| filename = WI.UIString("Fragment"); |
| |
| return { |
| url: WI.FileUtilities.inspectorURLForFilename(filename + ".glsl"), |
| content: this._lastActiveEditor.string, |
| forceSaveAs: true, |
| }; |
| } |
| |
| get supportsSearch() |
| { |
| return true; |
| } |
| |
| get numberOfSearchResults() |
| { |
| return this._lastActiveEditor.numberOfSearchResults; |
| } |
| |
| get hasPerformedSearch() |
| { |
| return this._lastActiveEditor.currentSearchQuery !== null; |
| } |
| |
| set automaticallyRevealFirstSearchResult(reveal) |
| { |
| this._lastActiveEditor.automaticallyRevealFirstSearchResult = reveal; |
| } |
| |
| performSearch(query) |
| { |
| this._lastActiveEditor.performSearch(query); |
| } |
| |
| searchCleared() |
| { |
| this._lastActiveEditor.searchCleared(); |
| } |
| |
| searchQueryWithSelection() |
| { |
| return this._lastActiveEditor.searchQueryWithSelection(); |
| } |
| |
| revealPreviousSearchResult(changeFocus) |
| { |
| this._lastActiveEditor.revealPreviousSearchResult(changeFocus); |
| } |
| |
| revealNextSearchResult(changeFocus) |
| { |
| this._lastActiveEditor.revealNextSearchResult(changeFocus); |
| } |
| |
| revealPosition(position, textRangeToSelect, forceUnformatted) |
| { |
| this._lastActiveEditor.revealPosition(position, textRangeToSelect, forceUnformatted); |
| } |
| |
| // Private |
| |
| _editorFocused(event) |
| { |
| if (this._lastActiveEditor === event.target) |
| return; |
| |
| let currentSearchQuery = null; |
| |
| if (this._lastActiveEditor) { |
| currentSearchQuery = this._lastActiveEditor.currentSearchQuery; |
| |
| this._lastActiveEditor.searchCleared(); |
| } |
| |
| this._lastActiveEditor = event.target; |
| |
| if (currentSearchQuery) |
| this._lastActiveEditor.performSearch(currentSearchQuery); |
| } |
| |
| _numberOfSearchResultsDidChange(event) |
| { |
| this.dispatchEventToListeners(WI.ContentView.Event.NumberOfSearchResultsDidChange); |
| } |
| |
| _contentDidChange(event) |
| { |
| if (event.target === this._vertexEditor) |
| this.representedObject.updateVertexShader(this._vertexEditor.string); |
| else if (event.target === this._fragmentEditor) |
| this.representedObject.updateFragmentShader(this._fragmentEditor.string); |
| } |
| }; |