Pārlūkot izejas kodu

Work on wiring up the ability to tell editor to jump to a particular line and also added clickable icons in the TypeScript compiler output to jump to editor and line of error.

Shaddock Heath 8 gadi atpakaļ
vecāks
revīzija
0cbcdd1a47

+ 12 - 0
Data/AtomicEditor/CodeEditor/MonacoEditor.html

@@ -118,6 +118,18 @@
                 interop.getInstance().formatCode();
             });
         }
+
+        function HOST_gotoLineNumber(lineNumber) {
+            setupEditor.then((interop) => {
+                interop.getInstance().gotoLineNumber(lineNumber);
+            });
+        }
+
+        function HOST_gotoTokenPos(tokenPosition) {
+            setupEditor.then((interop) => {
+                interop.getInstance().gotoPos(tokenPosition);
+            });
+        }
     </script>
 
 </body>

+ 10 - 0
Resources/EditorData/AtomicEditor/editor/ui/typescriptresults.tb.txt

@@ -0,0 +1,10 @@
+TBLayout: axis: y, distribution: available
+	lp: min-width: 640, min-height: 400;
+	TBLayout: distribution: available
+		TBLayout: distribution: available, size: available
+			TBEditField: multiline: 1, readonly: 1, id: msg, styling: 1
+	TBSeparator: gravity: left right, skin: AESeparator
+		lp: max-height: 5
+	TBLayout: axis: y, distribution: available
+		lp: max-height: 30
+		TBButton: text: Close, id: close, gravity: right

+ 20 - 2
Script/AtomicEditor/hostExtensions/HostExtensionServices.ts

@@ -390,6 +390,15 @@ export class UIServicesProvider extends ServicesProvider<Editor.HostExtensions.U
         return this.mainFrame.resourceframe.currentResourceEditor;
     }
 
+    /**
+     * Will load a resource editor or navigate to an already loaded resource editor by path
+     * @return {Editor.ResourceEditor}
+     */
+    loadResourceEditor(resourcePath: string): Editor.ResourceEditor {
+        this.mainFrame.resourceframe.sendEvent(EditorEvents.EditResource, {path: resourcePath} );
+        return this.mainFrame.resourceframe.currentResourceEditor;
+    }
+
     /**
      * Adds a new menu to the hierarchy context menu
      * @param  {string} id
@@ -442,12 +451,21 @@ export class UIServicesProvider extends ServicesProvider<Editor.HostExtensions.U
             this.inspectorFrame.loadCustomInspectorWidget(customInspector);
         }
     }
+
     /**
      * Disaplays a modal window
      * @param  {Editor.Modal.ModalWindow} window
      */
     showModalWindow(windowText: string, uifilename: string, handleWidgetEventCB: (ev: Atomic.UIWidgetEvent) => void): Editor.Modal.ExtensionWindow {
-        return this.modalOps.showExtensionWindow(windowText, uifilename, handleWidgetEventCB);
+        return this.modalOps.showExtensionWindow(windowText, uifilename, handleWidgetEventCB, true);
+    }
+
+    /**
+     * Disaplays a modal window
+     * @param  {Editor.Modal.ModalWindow} window
+     */
+    showNonModalWindow(windowText: string, uifilename: string, handleWidgetEventCB: (ev: Atomic.UIWidgetEvent) => void): Editor.Modal.ExtensionWindow {
+        return this.modalOps.showExtensionWindow(windowText, uifilename, handleWidgetEventCB, false);
     }
 
     /**
@@ -455,7 +473,7 @@ export class UIServicesProvider extends ServicesProvider<Editor.HostExtensions.U
      * @param  {string} windowText
      * @param  {string} message
      */
-    showModalError(windowText: string, message: string) {
+    showModalError(windowText: string, message: string): Atomic.UIMessageWindow {
         return this.modalOps.showError(windowText, message);
     }
 

+ 41 - 2
Script/AtomicEditor/hostExtensions/languageExtensions/TypescriptLanguageExtension.ts

@@ -441,6 +441,9 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
     }) {
         // get the name of the resources directory without preceding path
         let resourceDir = ToolCore.toolSystem.project.resourcePath.replace(Atomic.addTrailingSlash(ToolCore.toolSystem.project.projectPath), "");
+        let links = {};
+        let linkId = 0;
+
         let messageArray = results.annotations.filter(result => {
             // If we are compiling the lib.d.ts or some other built-in library and it was successful, then
             // we really don't need to display that result since it's just noise.  Only display it if it fails
@@ -456,7 +459,9 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
             if (result.type == "success") {
                 message += `<color #00ff00>${result.text}</color>`;
             } else {
-                message += `<color #e3e02b>${result.text} at line ${result.row} col ${result.column}</color>`;
+                message += `<color #e3e02b>${result.text} at line ${result.row + 1} col ${result.column}</color> <widget TBSkinImage: skin: MagnifierBitmap, text:"..." id: link${linkId}>`;
+                links["link" + linkId] = result;
+                linkId++;
             }
             return message;
         }).join("\n");
@@ -474,6 +479,40 @@ export default class TypescriptLanguageExtension implements Editor.HostExtension
             `Compilation Completed in ${results.duration}ms`
         ].join("\n");
 
-        this.serviceRegistry.uiServices.showModalError("TypeScript Compilation Results", message);
+        //let window = this.serviceRegistry.uiServices.showModalError("TypeScript Compilation Results", message);
+        let window = this.serviceRegistry.uiServices.showNonModalWindow("TypeScript Compilation Results", "AtomicEditor/editor/ui/typescriptresults.tb.txt", (ev:Atomic.UIWidgetEvent) => {
+            if (ev.type == Atomic.UI_EVENT_TYPE.UI_EVENT_TYPE_CLICK) {
+                if (ev.target.id == "close") {
+                  window.close();
+                } else {
+                    let diag = links[ev.target.id];
+                    if (diag) {
+                        const editor = this.serviceRegistry.uiServices.loadResourceEditor(diag.file) as Editor.JSResourceEditor;
+
+                        // TODO: need something here to wait for editor to fully load
+                        editor.gotoLineNumber(diag.row + 1);
+                    }
+                }
+            }
+        });
+
+        let textField = window.getWidget<Atomic.UIEditField>("msg");
+        textField.setText(message);
+        textField.reformat(true);
+
+        /*
+        window.subscribeToEvent(Atomic.UIWidgetEvent(ev => {
+            if (ev.type == Atomic.UI_EVENT_TYPE.UI_EVENT_TYPE_CLICK) {
+                let diag = links[ev.target.id];
+                if (diag) {
+                    const editor = this.serviceRegistry.uiServices.loadResourceEditor(diag.file) as Editor.JSResourceEditor;
+
+                    // TODO: need something here to wait for editor to fully load
+                    editor.gotoLineNumber(diag.row + 1);
+                }
+            }
+        }));
+        */
+
     }
 }

+ 9 - 6
Script/AtomicEditor/ui/modal/ModalOps.ts

@@ -257,23 +257,24 @@ class ModalOps extends Atomic.ScriptObject {
     }
 
     // TODO: standardize  to same pattern as other modal windows
-    showError(windowText: string, message: string) {
+    showError(windowText: string, message: string):Atomic.UIMessageWindow {
         var view = EditorUI.getView();
         var window = new Atomic.UIMessageWindow(view, "modal_error");
         window.show(windowText, message, Atomic.UI_MESSAGEWINDOW_SETTINGS.UI_MESSAGEWINDOW_SETTINGS_OK, true, 640, 360);
+        return window;
     }
 
-    showExtensionWindow(windowText: string, uifilename: string, handleWidgetEventCB: (ev: Atomic.UIWidgetEvent) => void): Editor.Modal.ExtensionWindow {
-        if (this.show()) {
+    showExtensionWindow(windowText: string, uifilename: string, handleWidgetEventCB: (ev: Atomic.UIWidgetEvent) => void, modal: boolean = true): Editor.Modal.ExtensionWindow {
+        if (this.show(modal)) {
 
             this.opWindow = new ExtensionWindow(windowText, uifilename, handleWidgetEventCB);
             return this.opWindow;
         }
     }
 
-    private show(): boolean {
+    private show(modal:boolean = true): boolean {
 
-        if (this.dimmer.parent) {
+        if (modal && this.dimmer.parent) {
 
             console.log("WARNING: attempting to show modal while dimmer is active");
             return false;
@@ -288,7 +289,9 @@ class ModalOps extends Atomic.ScriptObject {
         }
 
         var view = EditorUI.getView();
-        view.addChild(this.dimmer);
+        if (modal) {
+            view.addChild(this.dimmer);
+        }
 
         return true;
 

+ 19 - 0
Script/AtomicWebViewEditor/editor/editorCommands.ts

@@ -200,3 +200,22 @@ export function invokeShortcut(shortcut: Editor.EditorShortcutType) {
             break;
     }
 }
+
+/**
+ * Selects the provided line number
+ */
+export function gotoLineNumber(lineNumber:number) {
+    const ed = internalEditor.getInternalEditor();
+    ed.revealLineInCenterIfOutsideViewport(lineNumber);
+    ed.setPosition(new monaco.Position(lineNumber, 0));
+}
+
+/**
+ * Selects the provided position
+ */
+export function gotoTokenPos(tokenPos:number) {
+    const ed = internalEditor.getInternalEditor();
+    const pos = ed.getModel().getPositionAt(tokenPos);
+    ed.revealPositionInCenterIfOutsideViewport(pos);
+    ed.setPosition(pos);
+}

+ 24 - 1
Script/AtomicWebViewEditor/interop.ts

@@ -86,6 +86,11 @@ export default class HostInteropType {
     static EDITOR_CHANGE = "editorChange";
     static EDITOR_GET_USER_PREFS = "editorGetUserPrefs";
 
+    private setCodeLoaded;
+    private editorReady = new Promise((resolve, reject) => {
+        this.setCodeLoaded = resolve;
+    });
+
     /**
      * Called from the host to notify the client what file to load
      * @param  {string} codeUrl
@@ -104,7 +109,9 @@ export default class HostInteropType {
         // get the code
         this.getResource(codeUrl).then((src: string) => {
             editorCommands.loadCodeIntoEditor(src, filename, fileExt);
-            window.atomicQueryPromise(HostInteropType.EDITOR_GET_USER_PREFS);
+            return window.atomicQueryPromise(HostInteropType.EDITOR_GET_USER_PREFS);
+        }).then(() => {
+            this.setCodeLoaded();
         }).catch((e: Editor.ClientExtensions.AtomicErrorMessage) => {
             console.log("Error loading code: " + e.error_message);
         });
@@ -241,4 +248,20 @@ export default class HostInteropType {
     formatCode() {
         editorCommands.formatCode();
     }
+
+    /**
+     * Jump to the provided line number
+     */
+    gotoLineNumber(lineNumber:number) {
+        this.editorReady.then(() => {
+            editorCommands.gotoLineNumber(lineNumber);
+        });
+    }
+
+    /**
+     * Jump to the provided position
+     */
+    gotoTokenPos(tokenPos:number) {
+        editorCommands.gotoTokenPos(tokenPos);
+    }
 }

+ 9 - 1
Script/TypeScript/EditorWork.d.ts

@@ -251,7 +251,8 @@ declare module Editor.HostExtensions {
         refreshHierarchyFrame();
         loadCustomInspector(customInspector: Atomic.UIWidget);
         showModalWindow(windowText: string, uifilename: string, handleWidgetEventCB: (ev: Atomic.UIWidgetEvent) => void): Editor.Modal.ExtensionWindow;
-        showModalError(windowText: string, message: string);
+        showNonModalWindow(windowText: string, uifilename: string, handleWidgetEventCB: (ev: Atomic.UIWidgetEvent) => void): Editor.Modal.ExtensionWindow;
+        showModalError(windowText: string, message: string):Atomic.UIMessageWindow;
         showResourceSelection(windowText: string, importerType: string, resourceType: string, callback: (retObject: any, args: any) => void, args?: any);
 
         /**
@@ -260,6 +261,13 @@ declare module Editor.HostExtensions {
          */
         getCurrentResourceEditor(): Editor.ResourceEditor;
 
+        
+        /**
+         * Will load a resource editor or navigate to an already loaded resource editor by path
+         * @return {Editor.ResourceEditor}
+         */
+        loadResourceEditor(path: string): Editor.ResourceEditor;
+
         /**
          * Register a custom editor.  These editors will override editors in the standard editor list if
          * they both resolve the ```canHandleResource``` call.

+ 2 - 2
Source/AtomicEditor/Editors/JSResourceEditor.cpp

@@ -235,12 +235,12 @@ void JSResourceEditor::SetFocus()
 
 void JSResourceEditor::GotoTokenPos(int tokenPos)
 {
-
+    webClient_->ExecuteJavaScript(ToString("HOST_gotoTokenPos(%d);", tokenPos));
 }
 
 void JSResourceEditor::GotoLineNumber(int lineNumber)
 {
-
+    webClient_->ExecuteJavaScript(ToString("HOST_gotoLineNumber(%d);", lineNumber));
 }
 
 bool JSResourceEditor::Save()