Browse Source

added the ability to allow the webview code to retrieve user preferences

Shaddock Heath 9 years ago
parent
commit
b630f5bb3a

+ 1 - 0
Script/AtomicWebViewEditor/clientExtensions/ClientExtensionEventNames.ts

@@ -30,4 +30,5 @@ export default class ClientExtensionEventNames {
     static ResourceRenamedEvent = "ResourceRenamedEvent";
     static ResourceDeletedEvent = "ResourceDeletedEvent";
     static ProjectUnloadedEvent = "ProjectUnloadedEvent";
+    static PreferencesChangedEvent = "PreferencesChangedEvent";
 }

+ 20 - 0
Script/AtomicWebViewEditor/clientExtensions/ClientExtensionServices.ts

@@ -86,6 +86,7 @@ export class ExtensionServiceRegistry extends ServiceRegistry<Editor.ClientExten
         eventDispatcher.subscribeToEvent(ClientExtensionEventNames.ProjectUnloadedEvent, (ev) => this.projectUnloaded());
         eventDispatcher.subscribeToEvent(ClientExtensionEventNames.ResourceDeletedEvent, (ev) => this.deleteResource(ev));
         eventDispatcher.subscribeToEvent(ClientExtensionEventNames.CodeSavedEvent, (ev) => this.saveCode(ev));
+        eventDispatcher.subscribeToEvent(ClientExtensionEventNames.PreferencesChangedEvent, (ev) => this.preferencesChanged());
     }
 
     /**
@@ -189,4 +190,23 @@ export class ExtensionServiceRegistry extends ServiceRegistry<Editor.ClientExten
             }
         });
     }
+
+    /**
+     * Called when prefeerences changes
+     * @param  {Editor.EditorEvents.PreferencesChangedEvent} ev
+     */
+    preferencesChanged() {
+        this.registeredServices.forEach((service) => {
+            // Notify services that the project has been unloaded
+            try {
+                if (service.preferencesChanged) {
+                    service.preferencesChanged();
+                }
+            } catch (e) {
+                alert(`Extension Error:\n Error detected in extension ${service.name}\n \n ${e.stack}`);
+            }
+        });
+    }
+
+
 }

+ 37 - 5
Script/AtomicWebViewEditor/clientExtensions/ServiceLocator.ts

@@ -40,13 +40,15 @@ export class ClientServiceLocatorType implements Editor.ClientExtensions.ClientS
 
     private services: ClientExtensionServices.ExtensionServiceRegistry;
     private eventDispatcher: Editor.Extensions.EventDispatcher = new ClientExtensionServices.EventDispatcher();
-
+    private userPreferences = {};
+    
     /**
-     * Returns the Host Interop module
-     * @return {Editor.ClientExtensions.HostInterop}
+     * Sets the preferences for the service locator
+     * @param  {any} prefs
+     * @return {[type]}
      */
-    getHostInterop(): Editor.ClientExtensions.HostInterop {
-        return HostInteropType.getInstance();
+    setPreferences(prefs : any) {
+        this.userPreferences = prefs;
     }
 
     loadService(service: Editor.ClientExtensions.ClientEditorService) {
@@ -79,6 +81,36 @@ export class ClientServiceLocatorType implements Editor.ClientExtensions.ClientS
             this.eventDispatcher.subscribeToEvent(eventType, callback);
         }
     }
+
+    /** Methods available to extensions **/
+
+    /**
+     * Returns the Host Interop module
+     * @return {Editor.ClientExtensions.HostInterop}
+     */
+    getHostInterop(): Editor.ClientExtensions.HostInterop {
+        return HostInteropType.getInstance();
+    }
+
+
+    /**
+     * Return a preference value or the provided default from the user settings file
+     * @param  {string} extensionName name of the extension the preference lives under
+     * @param  {string} preferenceName name of the preference to retrieve
+     * @param  {number | boolean | string} defaultValue value to return if pref doesn't exist
+     * @return {number|boolean|string}
+     */
+    getUserPreference(extensionName: string, preferenceName: string, defaultValue?: number | boolean | string): number | boolean | string {
+        if (this.userPreferences) {
+            let extensionPrefs = this.userPreferences["extensions"];
+            if (extensionPrefs && extensionPrefs[extensionName]) {
+                return extensionPrefs[extensionName][preferenceName] || defaultValue;
+            }
+        }
+
+        // if all else fails
+        return defaultValue;
+    }
 }
 
 // Singleton service locator that can be referenced

+ 8 - 0
Script/AtomicWebViewEditor/clientExtensions/languageExtensions/typescript/TypescriptLanguageExtension.ts

@@ -300,4 +300,12 @@ export default class TypescriptLanguageExtension implements Editor.ClientExtensi
             this.worker.port.postMessage(message);
         }
     }
+
+    /**
+     * Called when the user preferences have been changed (or initially loaded)
+     * @return {[type]}
+     */
+    preferencesChanged() {
+        // nothing to do yet
+    }
 }

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

@@ -123,3 +123,12 @@ export function codeSaved(path: string, fileExt: string, contents: string) {
     };
     serviceLocator.sendEvent(ClientExtensionEventNames.CodeSavedEvent, data);
 }
+
+/**
+ * Called when new preferences are available (or initially with current prefs)
+ * @param  {any} prefs
+ */
+export function loadPreferences(prefs: any) {
+    serviceLocator.setPreferences(prefs);
+    serviceLocator.sendEvent(ClientExtensionEventNames.PreferencesChangedEvent, null);
+}

+ 21 - 0
Script/AtomicWebViewEditor/interop.ts

@@ -76,6 +76,7 @@ export default class HostInteropType {
     static EDITOR_SAVE_FILE = "editorSaveFile";
     static EDITOR_LOAD_COMPLETE = "editorLoadComplete";
     static EDITOR_CHANGE = "editorChange";
+    static EDITOR_GET_USER_PREFS = "editorGetUserPrefs";
 
     constructor() {
         // Set up the window object so the host can call into it
@@ -85,6 +86,7 @@ export default class HostInteropType {
         window.HOST_projectUnloaded = this.projectUnloaded.bind(this);
         window.HOST_resourceRenamed = this.resourceRenamed.bind(this);
         window.HOST_resourceDeleted = this.resourceDeleted.bind(this);
+        window.HOST_loadPreferences = this.loadPreferences.bind(this);
     }
 
     /**
@@ -106,6 +108,9 @@ export default class HostInteropType {
         // get the code
         this.getResource(codeUrl).then((src: string) => {
             editorCommands.loadCodeIntoEditor(src, filename, fileExt);
+            atomicQueryPromise({
+                message: HostInteropType.EDITOR_GET_USER_PREFS
+            });
         }).catch((e: Editor.ClientExtensions.AtomicErrorMessage) => {
             console.log("Error loading code: " + e.error_message);
         });
@@ -213,6 +218,22 @@ export default class HostInteropType {
     resourceDeleted(path: string) {
         editorCommands.resourceDeleted(path);
     }
+
+    /**
+     * Host is notifying client that there are preferences to load and passing us the path
+     * of the prefs.
+     * @param  {string} prefUrl
+     */
+    loadPreferences(prefUrl: string) {
+        console.log("Load preferences called for :" + prefUrl);
+        // load prefs
+        this.getResource(prefUrl).then((prefsJson: string) => {
+            let prefs = JSON.parse(prefsJson);
+            editorCommands.loadPreferences(prefs);
+        }).catch((e: Editor.ClientExtensions.AtomicErrorMessage) => {
+            console.log("Error loading preferences: " + e.error_message);
+        });
+    }
 }
 
 HostInteropType.getInstance().editorLoaded();

+ 1 - 0
Script/AtomicWebViewEditor/typings/WindowExt.d.ts

@@ -31,4 +31,5 @@ interface Window {
     HOST_projectUnloaded: () => void;
     HOST_resourceRenamed: (path: string, newPath: string) => void;
     HOST_resourceDeleted: (path: string) => void;
+    HOST_loadPreferences: (path: string) => void;
 }

+ 16 - 0
Script/TypeScript/EditorWork.d.ts

@@ -140,6 +140,12 @@ declare module Editor.EditorEvents {
         serializable: Atomic.Serializable;
 
     }
+
+    export interface PreferencesChangedEvent {
+
+        preferences: any;
+
+    }
 }
 
 declare module Editor.Extensions {
@@ -313,6 +319,15 @@ declare module Editor.ClientExtensions {
      */
     export interface ClientServiceLocator extends Editor.Extensions.ServiceLoader {
         getHostInterop(): HostInterop;
+
+        /**
+         * Return a preference value or the provided default from the user settings file
+         * @param  {string} extensionName name of the extension the preference lives under
+         * @param  {string} preferenceName name of the preference to retrieve
+         * @param  {number | boolean | string} defaultValue value to return if pref doesn't exist
+         * @return {number|boolean|string}
+         */
+        getUserPreference(extensionName: string, preferenceName: string, defaultValue?: number | boolean | string): number | boolean | string;
     }
 
     export interface ClientEditorService extends Editor.Extensions.EditorServiceExtension {
@@ -329,6 +344,7 @@ declare module Editor.ClientExtensions {
         delete?(ev: EditorEvents.DeleteResourceEvent);
         rename?(ev: EditorEvents.RenameResourceEvent);
         projectUnloaded?();
+        preferencesChanged?();
     }
 
     export interface AtomicErrorMessage {

+ 24 - 11
Source/AtomicEditor/Editors/JSResourceEditor.cpp

@@ -33,6 +33,8 @@
 #include <AtomicJS/Javascript/JSVM.h>
 
 #include <ToolCore/ToolEnvironment.h>
+#include <ToolCore/ToolSystem.h>
+#include <ToolCore/Project/Project.h>
 
 #include <AtomicWebView/WebViewEvents.h>
 #include <AtomicWebView/UIWebView.h>
@@ -92,12 +94,12 @@ JSResourceEditor ::JSResourceEditor(Context* context, const String &fullpath, UI
     c->AddChild(webView_->GetInternalWidget());
 
 }
-    
+
 JSResourceEditor::~JSResourceEditor()
 {
 
 }
-   
+
 String getNormalizedPath(const String& path)
 {
     // Full path is the fully qualified path from the root of the filesystem.  In order
@@ -107,34 +109,34 @@ String getNormalizedPath(const String& path)
     const String& RESOURCES_MARKER = "resources/";
     return path.SubstringUTF8(path.ToLower().Find(RESOURCES_MARKER));
 }
-    
+
 void JSResourceEditor::HandleRenameResourceNotification(StringHash eventType, VariantMap& eventData)
 {
     using namespace RenameResourceNotification;
     const String& newPath = eventData[P_NEWRESOURCEPATH].GetString();
     const String& path = eventData[P_RESOURCEPATH].GetString();
-    
+
     webClient_->ExecuteJavaScript(ToString("HOST_resourceRenamed(\"%s\",\"%s\");", getNormalizedPath(path).CString(), getNormalizedPath(newPath).CString()));
-    
+
     if (fullpath_.Compare(path) == 0) {
         fullpath_ = newPath;
         SetModified(modified_);
     }
 }
-    
+
 void JSResourceEditor::HandleDeleteResourceNotification(StringHash eventType, VariantMap& eventData)
 {
     using namespace DeleteResourceNotification;
     const String& path = eventData[P_RESOURCEPATH].GetString();
-    
+
     webClient_->ExecuteJavaScript(ToString("HOST_resourceDeleted(\"%s\");", getNormalizedPath(path).CString()));
 }
-    
+
 void JSResourceEditor::HandleProjectUnloadedNotification(StringHash eventType, VariantMap& eventData)
 {
     webClient_->ExecuteJavaScript("HOST_projectUnloaded();");
 }
-    
+
 void JSResourceEditor::HandleWebViewLoadEnd(StringHash eventType, VariantMap& eventData)
 {
     // need to wait until we get an editor load complete message since we could
@@ -150,9 +152,10 @@ void JSResourceEditor::HandleWebMessage(StringHash eventType, VariantMap& eventD
     const String& EDITOR_SAVE_CODE = "editorSaveCode";
     const String& EDITOR_SAVE_FILE = "editorSaveFile";
     const String& EDITOR_LOAD_COMPLETE = "editorLoadComplete";
-    
+    const String& EDITOR_GET_USER_PREFS = "editorGetUserPrefs";
+
     String normalizedPath = getNormalizedPath(fullpath_);
-    
+
     WebMessageHandler* handler = static_cast<WebMessageHandler*>(eventData[P_HANDLER].GetPtr());
 
     if (request == EDITOR_CHANGE)
@@ -188,6 +191,16 @@ void JSResourceEditor::HandleWebMessage(StringHash eventType, VariantMap& eventD
                 file.Write((void*) code.CString(), code.Length());
                 file.Close();
             }
+            else if (message == EDITOR_GET_USER_PREFS)
+            {
+                ToolSystem* tsys = GetSubsystem<ToolSystem>();
+                Project* proj = tsys->GetProject();
+                FileSystem* fileSystem = GetSubsystem<FileSystem>();
+                if (fileSystem->FileExists(proj->GetUserPrefsFullPath()))
+                {
+                    webClient_->ExecuteJavaScript(ToString("HOST_loadPreferences(\"atomic://%s\");", proj->GetUserPrefsFullPath().CString()));
+                }
+            }
         }
     }