瀏覽代碼

Added editor sound type editor window, the user added ones can be dragged onto line edits which sets that line editor with the internal StringHash of the Sound Type.
Added AM_READ for backwards compatibility to read old enum based sound types but not serialize them.

Alex Parlett 11 年之前
父節點
當前提交
5d12f5a521

+ 1 - 0
Bin/Data/Scripts/Editor.as

@@ -16,6 +16,7 @@
 #include "Scripts/Editor/EditorImport.as"
 #include "Scripts/Editor/EditorResourceBrowser.as"
 #include "Scripts/Editor/EditorSpawn.as"
+#include "Scripts/Editor/EditorSoundType.as"
 
 String configFileName;
 

+ 200 - 0
Bin/Data/Scripts/Editor/EditorSoundType.as

@@ -0,0 +1,200 @@
+// Urho3D Sound Type manager
+
+Window@ soundTypeEditorWindow;
+Dictionary mappings;
+
+const uint DEFAULT_SOUND_TYPES_COUNT = 5;
+
+class SoundTypeMapping
+{
+    StringHash key;
+    float value;
+
+    SoundTypeMapping()
+    {
+    }
+    
+    SoundTypeMapping(const String&in key, const float&in value)
+    {
+        this.key = StringHash(key);
+        this.value = value;
+    }
+    
+    SoundTypeMapping(const StringHash&in key, const float&in value)
+    {
+        this.key = key;
+        this.value = value;
+    }
+    
+    void Update(float value)
+    {
+        this.value = Clamp(value, 0.0f, 1.0f);
+        audio.SetMasterGain(this.key, this.value);
+    }
+}
+
+void CreateSoundTypeEditor()
+{
+    if (soundTypeEditorWindow !is null)
+        return;
+        
+    soundTypeEditorWindow = ui.LoadLayout(cache.GetResource("XMLFile", "UI/EditorSoundTypeWindow.xml"));
+    ui.root.AddChild(soundTypeEditorWindow);
+    soundTypeEditorWindow.opacity = uiMaxOpacity;
+
+    InitsoundTypeEditorWindow();
+    RefreshSoundTypeEditorWindow();
+
+    int height = Min(ui.root.height - 60, 750);    
+    soundTypeEditorWindow.SetSize(400, 0);
+    CenterDialog(soundTypeEditorWindow);
+
+    HideSoundTypeEditor();
+    
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("CloseButton", true), "Released", "HideSoundTypeEditor");
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("AddButton", true), "Released", "AddSoundTypeMapping");
+    
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("EffectValue", true), "TextFinished", "EditGain");
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("AmbientValue", true), "TextFinished", "EditGain");
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("VoiceValue", true), "TextFinished", "EditGain");
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("MusicValue", true), "TextFinished", "EditGain");
+    SubscribeToEvent(soundTypeEditorWindow.GetChild("MasterValue", true), "TextFinished", "EditGain");
+}
+
+void InitsoundTypeEditorWindow()
+{
+    mappings["Effect"] = SoundTypeMapping(GetHashFromSoundType(SOUND_EFFECT), audio.GetMasterGain(SOUND_EFFECT));
+    mappings["Ambient"] = SoundTypeMapping(GetHashFromSoundType(SOUND_AMBIENT), audio.GetMasterGain(SOUND_AMBIENT));
+    mappings["Voice"] = SoundTypeMapping(GetHashFromSoundType(SOUND_VOICE), audio.GetMasterGain(SOUND_VOICE));
+    mappings["Music"] = SoundTypeMapping(GetHashFromSoundType(SOUND_MUSIC), audio.GetMasterGain(SOUND_MUSIC));
+    mappings["Master"] = SoundTypeMapping(GetHashFromSoundType(SOUND_MASTER), audio.GetMasterGain(SOUND_MASTER));
+}
+
+void RefreshSoundTypeEditorWindow()
+{
+    RefreshDefaults(soundTypeEditorWindow.GetChild("DefaultsContainer"));
+    RefreshUser(soundTypeEditorWindow.GetChild("UserContainer"));
+}
+
+void RefreshDefaults(UIElement@ root)
+{
+    UpdateMappingValue("Effect", root.GetChild("Effect", true));
+    UpdateMappingValue("Ambient", root.GetChild("Ambient", true));
+    UpdateMappingValue("Voice", root.GetChild("Voice", true));
+    UpdateMappingValue("Music", root.GetChild("Music", true));
+    UpdateMappingValue("Master", root.GetChild("Master", true));
+}
+
+void RefreshUser(UIElement@ root)
+{
+    for (uint i = DEFAULT_SOUND_TYPES_COUNT; i < mappings.length; i++)
+    {
+        String key = mappings.keys[i];  
+        UpdateMappingValue(key, root.GetChild(key, true));
+    }
+}
+
+void UpdateMappingValue(const String&in key, UIElement@ root)
+{
+    if (root !is null)
+    {
+        LineEdit@ value = root.GetChild(key + "Value");
+        SoundTypeMapping@ mapping;
+        
+        if (mappings.Get(key, @mapping) && value !is null)
+        {
+            value.text = mapping.value;
+            root.vars["DragDropContent"] = String(mapping.key.value);
+        }
+    }
+}
+
+void AddUserUIElements(const String&in key, const String&in gain)
+{
+        ListView@ container = soundTypeEditorWindow.GetChild("UserContainer", true);
+        
+        UIElement@ itemParent = UIElement();
+        container.AddItem(itemParent);
+        
+        itemParent.style = "ListRow";
+        itemParent.name = key;
+        itemParent.layoutSpacing = 10;
+        
+        Text@ keyText = Text();
+        LineEdit@ gainEdit = LineEdit();
+        Button@ removeButton = Button();
+        
+        itemParent.AddChild(keyText);
+        itemParent.AddChild(gainEdit);
+        itemParent.AddChild(removeButton);
+        itemParent.dragDropMode = DD_SOURCE;
+        
+        keyText.text = key;
+        keyText.textAlignment = HA_LEFT;
+        keyText.SetStyleAuto();
+        
+        gainEdit.maxLength = 4;
+        gainEdit.maxWidth = 2147483647;
+        gainEdit.minWidth = 100;
+        gainEdit.name = key + "Value";
+        gainEdit.text = gain;
+        gainEdit.SetStyleAuto();
+
+        removeButton.style = "CloseButton";
+        
+        SubscribeToEvent(removeButton, "Released", "DeleteSoundTypeMapping");
+        SubscribeToEvent(gainEdit, "TextFinished", "EditGain");
+}
+
+void AddSoundTypeMapping(StringHash eventType, VariantMap& eventData)
+{
+    UIElement@ button = eventData["Element"].GetPtr();
+    LineEdit@ key = button.parent.GetChild("Key");
+    LineEdit@ gain = button.parent.GetChild("Gain");
+    
+    if (!key.text.empty && !gain.text.empty && !mappings.Exists(key.text))
+    {
+        AddUserUIElements(key.text,gain.text);
+        mappings[key.text] = SoundTypeMapping(key.text, gain.text.ToFloat());
+    }
+    
+    key.text = "";
+    gain.text = "";
+    
+    RefreshSoundTypeEditorWindow();
+}
+
+void DeleteSoundTypeMapping(StringHash eventType, VariantMap& eventData)
+{
+    UIElement@ button = eventData["Element"].GetPtr();
+    UIElement@ parent = button.parent;
+    
+    mappings.Erase(parent.name);
+    button.parent.Remove();
+}
+
+void EditGain(StringHash eventType, VariantMap& eventData)
+{
+    LineEdit@ input = eventData["Element"].GetPtr();
+    String key = input.parent.name;
+    
+    SoundTypeMapping@ mapping;
+    
+    if (mappings.Get(key, @mapping))
+        mapping.Update(input.text.ToFloat());
+        
+    RefreshSoundTypeEditorWindow();
+}
+
+bool ShowSoundTypeEditor()
+{
+    RefreshSoundTypeEditorWindow();
+    soundTypeEditorWindow.visible = true;
+    soundTypeEditorWindow.BringToFront();
+    return true;
+}
+
+void HideSoundTypeEditor()
+{
+    soundTypeEditorWindow.visible = false;
+}

+ 2 - 0
Bin/Data/Scripts/Editor/EditorUI.as

@@ -77,6 +77,7 @@ void CreateUI()
     CreateMaterialEditor();
     CreateParticleEffectEditor();
     CreateSpawnEditor();
+    CreateSoundTypeEditor();
     CreateStatsBar();
     CreateConsole();
     CreateDebugHud();
@@ -417,6 +418,7 @@ void CreateMenuBar()
         popup.AddChild(CreateMenuItem("Material editor", @ShowMaterialEditor));
         popup.AddChild(CreateMenuItem("Particle editor", @ShowParticleEffectEditor));
         popup.AddChild(CreateMenuItem("Spawn editor", @ShowSpawnEditor));
+        popup.AddChild(CreateMenuItem("Sound Type editor", @ShowSoundTypeEditor));
         popup.AddChild(CreateMenuItem("Editor settings", @ShowEditorSettingsDialog));
         popup.AddChild(CreateMenuItem("Editor preferences", @ShowEditorPreferencesDialog));
         CreateChildDivider(popup);

+ 134 - 0
Bin/Data/UI/EditorSoundTypeWindow.xml

@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<element type="Window">
+	<attribute name="Name" value="SoundTypeWindow" />
+	<attribute name="Max Size" value="300 2147483647" />
+	<attribute name="Layout Mode" value="Vertical" />
+	<attribute name="Layout Spacing" value="4" />
+	<attribute name="Layout Border" value="6 6 6 6" />
+	<attribute name="Resize Border" value="6 6 6 6" />
+	<attribute name="Is Movable" value="true" />
+	<attribute name="Is Resizable" value="true" />
+	<element>
+		<attribute name="Max Size" value="2147483647 16" />
+		<attribute name="Layout Mode" value="Horizontal" />
+		<element type="Text">
+			<attribute name="Text" value="Sound Type editor" />
+		</element>
+		<element type="Button" style="CloseButton">
+			<attribute name="Name" value="CloseButton" />
+		</element>
+	</element>
+	<element type="BorderImage" style="EditorDivider" />
+	<element type="Text">
+		<attribute name="Text" value="Defaults" />
+	</element>
+	<element type="ListView" style="PanelView">
+		<attribute name="Name" value="DefaultsContainer" />
+		<attribute name="Min Size" value="0 60" />
+		<element type="BorderImage" internal="true" style="none">
+			<element internal="true" style="none">
+				<element style="ListRow">
+					<attribute name="Name" value="Effect" />
+					<attribute name="Layout Spacing" value="10" />
+					<element type="Text">
+						<attribute name="Text" value="Effect" />
+					</element>
+					<element type="LineEdit">
+						<attribute name="Name" value="EffectValue" />
+						<attribute name="Min Size" value="100 0" />
+						<attribute name="Max Size" value="2147483647 20" />
+						<attribute name="Max Length" value="4" />
+					</element>
+				</element>
+				<element style="ListRow">
+					<attribute name="Name" value="Ambient" />
+					<attribute name="Layout Spacing" value="10" />
+					<element type="Text">
+						<attribute name="Text" value="Ambient" />
+					</element>
+					<element type="LineEdit">
+						<attribute name="Name" value="AmbientValue" />
+						<attribute name="Min Size" value="100 0" />
+						<attribute name="Max Size" value="2147483647 20" />
+						<attribute name="Max Length" value="4" />
+					</element>
+				</element>
+				<element style="ListRow">
+					<attribute name="Name" value="Voice" />
+					<attribute name="Layout Spacing" value="10" />
+					<element type="Text">
+						<attribute name="Text" value="Voice" />
+					</element>
+					<element type="LineEdit">
+						<attribute name="Name" value="VoiceValue" />
+						<attribute name="Min Size" value="100 0" />
+						<attribute name="Max Size" value="2147483647 20" />
+						<attribute name="Max Length" value="4" />
+					</element>
+				</element>
+				<element style="ListRow">
+					<attribute name="Name" value="Music" />
+					<attribute name="Layout Spacing" value="10" />
+					<element type="Text">
+						<attribute name="Text" value="Music" />
+					</element>
+					<element type="LineEdit">
+						<attribute name="Name" value="MusicValue" />
+						<attribute name="Min Size" value="100 0" />
+						<attribute name="Max Size" value="2147483647 20" />
+						<attribute name="Max Length" value="4" />
+					</element>
+				</element>
+				<element style="ListRow">
+					<attribute name="Name" value="Master" />
+					<attribute name="Layout Spacing" value="10" />
+					<element type="Text">
+						<attribute name="Text" value="Master" />
+					</element>
+					<element type="LineEdit">
+						<attribute name="Name" value="MasterValue" />
+						<attribute name="Min Size" value="100 0" />
+						<attribute name="Max Size" value="2147483647 20" />
+						<attribute name="Max Length" value="4" />
+					</element>
+				</element>
+			</element>
+		</element>
+	</element>
+	<element type="BorderImage" style="EditorDivider" />
+	<element type="Text">
+		<attribute name="Text" value="User" />
+	</element>
+	<element type="ListView" style="PanelView">
+		<attribute name="Name" value="UserContainer" />
+		<attribute name="Min Size" value="0 60" />
+		<element type="BorderImage" internal="true" style="none">
+			<element internal="true" style="none">
+            </element>
+		</element>
+	</element>
+    <element>
+        <attribute name="Max Size" value="2147483647 30" />   
+        <attribute name="Layout Mode" value="Horizontal" />
+        <element type="LineEdit">
+            <attribute name="Name" value="Key" />
+            <attribute name="Min Size" value="100 20" />
+            <attribute name="Max Size" value="2147483647 20" />
+        </element>
+        <element type="LineEdit">
+            <attribute name="Name" value="Gain" />
+            <attribute name="Min Size" value="100 20" />
+            <attribute name="Max Size" value="2147483647 20" />
+        </element>
+		<element type="Button" >
+			<attribute name="Name" value="AddButton" />
+            <attribute name="Min Size" value="0 20" />
+            <attribute name="Max Size" value="2147483647 20" />
+            <attribute name="Layout Mode" value="Horizontal" />
+            <element type="Text">
+                <attribute name="Text" value="Add" />
+                <attribute name="Text Alignment" value="Center" />
+            </element>
+		</element>
+    </element>
+</element>

+ 2 - 2
Source/Engine/Audio/Audio.cpp

@@ -229,8 +229,8 @@ float Audio::GetSoundSourceMasterGain(const StringHash& type) const
     VariantMap::ConstIterator masterIt = masterGain_.Find(soundTypeHashes[SOUND_MASTER]);
     VariantMap::ConstIterator typeIt = masterGain_.Find(type);
 
-    if (typeIt == masterGain_.End())
-        return 0.0f;
+    if (typeIt == masterGain_.End() || typeIt == masterIt)
+        return masterIt->second_.GetFloat();
 
     return masterIt->second_.GetFloat() * typeIt->second_.GetFloat();
 }

+ 2 - 0
Source/Engine/Core/Attribute.h

@@ -46,6 +46,8 @@ static const unsigned AM_NODEID = 0x10;
 static const unsigned AM_COMPONENTID = 0x20;
 /// Attribute is a node ID vector where first element is the amount of nodes.
 static const unsigned AM_NODEIDVECTOR = 0x40;
+/// Attribute is only read not written, mainly used for backwards compatibility with serialization.
+static const unsigned AM_READ = 0x80;
 
 class Serializable;
 

+ 1 - 1
Source/Engine/Scene/Serializable.cpp

@@ -319,7 +319,7 @@ bool Serializable::LoadXML(const XMLElement& source, bool setInstanceDefault)
         while (attempts)
         {
             const AttributeInfo& attr = attributes->At(i);
-            if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true))
+            if (((attr.mode_ & AM_FILE) || (attr.mode_ & AM_READ)) && !attr.name_.Compare(name, true))
             {
                 Variant varValue;
 

+ 1 - 1
Source/Engine/Script/AudioAPI.cpp

@@ -117,7 +117,7 @@ void RegisterAudio(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Audio", "bool get_playing() const", asMETHOD(Audio, IsPlaying), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "bool get_initialized() const", asMETHOD(Audio, IsInitialized), asCALL_THISCALL);
     engine->RegisterGlobalFunction("Audio@+ get_audio()", asFUNCTION(GetAudio), asCALL_CDECL);
-    engine->RegisterGlobalFunction("StringHash GetHashFromSoundType(SoundType type) const", asFUNCTION(GetHashFromType), asCALL_CDECL);
+    engine->RegisterGlobalFunction("StringHash GetHashFromSoundType(SoundType type)", asFUNCTION(GetHashFromType), asCALL_CDECL);
 }
 
 void RegisterAudioAPI(asIScriptEngine* engine)

+ 1 - 0
Source/Engine/Script/SceneAPI.cpp

@@ -45,6 +45,7 @@ static void RegisterSerializable(asIScriptEngine* engine)
     engine->RegisterGlobalProperty("const uint AM_NODEID", (void*)&AM_NODEID);
     engine->RegisterGlobalProperty("const uint AM_COMPONENTID", (void*)&AM_COMPONENTID);
     engine->RegisterGlobalProperty("const uint AM_NODEIDVECTOR", (void*)&AM_NODEIDVECTOR);
+    engine->RegisterGlobalProperty("const uint AM_READ", (void*) &AM_READ);
 
     RegisterSerializable<Serializable>(engine, "Serializable");
 }