Skip to content

Commit

Permalink
Add image viewer module
Browse files Browse the repository at this point in the history
  • Loading branch information
JLChnToZ committed May 8, 2024
1 parent 6d33e39 commit e481f7e
Show file tree
Hide file tree
Showing 20 changed files with 1,308 additions and 276 deletions.
11 changes: 4 additions & 7 deletions Packages/idv.jlchntoz.vvmw/Editor/Common/ComponentReplacer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor;
using UnityObject = UnityEngine.Object;

using static UnityEngine.Object;

Expand Down Expand Up @@ -186,12 +185,10 @@ void RestoreDependents(Component newAddedComponent = null) {
}
if (temp == null) temp = sourceGameObject.AddComponent(current.componentType);
current.componentsInGameObject[current.componentIndex] = temp;
if (temp != null) {
var src = current.componentsInTemporary[current.componentIndex];
if (src != null && src.GetType() == temp.GetType())
EditorUtility.CopySerializedIfDifferent(current.componentsInTemporary[current.componentIndex], temp);
}
if (references.TryGetValue(current.componentsInTemporary[current.componentIndex], out var mapping))
var src = current.componentsInTemporary[current.componentIndex];
if (src == null) continue;
if (temp != null && src.GetType() == temp.GetType()) EditorUtility.CopySerializedIfDifferent(src, temp);
if (references.TryGetValue(src, out var mapping))
foreach (var (component, path) in mapping) {
using (var so = new SerializedObject(component))
try {
Expand Down
22 changes: 11 additions & 11 deletions Packages/idv.jlchntoz.vvmw/Editor/VVMW/CoreEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class CoreEditor : VVMWEditorBase {
SerializedProperty timeDriftDetectThresholdProperty;
SerializedReorderableList playerHandlersList, audioSourcesList, targetsList;
string[] playerNames;
bool[] playerTypes;
PlayerType[] playerTypes;
List<bool> screenTargetVisibilityState;
bool showTrustUrlList;

Expand Down Expand Up @@ -154,21 +154,21 @@ void DrawAutoPlayField() {
return;
}
int autoPlayPlayerType = autoPlayPlayerTypeProperty.intValue - 1;
bool isAvPro = playerTypes != null && autoPlayPlayerType >= 0 && autoPlayPlayerType < playerTypes.Length && playerTypes[autoPlayPlayerType];
TrustedUrlUtils.DrawUrlField(defaultUrlProperty, isAvPro ? TrustedUrlTypes.AVProDesktop : TrustedUrlTypes.UnityVideo);
var playerType = playerTypes != null && autoPlayPlayerType >= 0 && autoPlayPlayerType < playerTypes.Length ? playerTypes[autoPlayPlayerType] : PlayerType.Unknown;
TrustedUrlUtils.DrawUrlField(defaultUrlProperty, playerType.ToTrustUrlType(false));
if (!string.IsNullOrEmpty(defaultUrlProperty.FindPropertyRelative("url").stringValue)) {
TrustedUrlUtils.DrawUrlField(defaultQuestUrlProperty, isAvPro ? TrustedUrlTypes.AVProAndroid : TrustedUrlTypes.UnityVideo);
TrustedUrlUtils.DrawUrlField(defaultQuestUrlProperty, playerType.ToTrustUrlType(true));
if (playerNames == null || playerNames.Length != playerHandlersProperty.arraySize)
playerNames = new string[playerHandlersProperty.arraySize];
if (playerTypes == null || playerTypes.Length != playerHandlersProperty.arraySize)
playerTypes = new bool[playerHandlersProperty.arraySize];
playerTypes = new PlayerType[playerHandlersProperty.arraySize];
for (int i = 0; i < playerNames.Length; i++) {
var playerHandler = playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue as VideoPlayerHandler;
var playerHandler = playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue as AbstractMediaPlayerHandler;
if (playerHandler == null)
playerNames[i] = "null";
else {
playerNames[i] = string.IsNullOrEmpty(playerHandler.playerName) ? playerHandler.name : playerHandler.playerName;
playerTypes[i] = playerHandler.IsAvPro;
playerTypes[i] = playerHandler.GetPlayerType();
}
}
var rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
Expand All @@ -193,7 +193,7 @@ void DrawPlayerHandlersListHeader(Rect rect) {
rect.width -= size.x;
EditorGUI.LabelField(rect, "Video Player Handlers");
if (GUI.Button(buttonRect, tempContent, miniButtonStyle)) {
var handlers = (target as Core).GetComponentsInChildren<VideoPlayerHandler>(true);
var handlers = (target as Core).GetComponentsInChildren<AbstractMediaPlayerHandler>(true);
playerHandlersProperty.arraySize = handlers.Length;
for (int i = 0; i < handlers.Length; i++)
playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue = handlers[i];
Expand All @@ -210,11 +210,11 @@ void DrawAudioSourcesListHeader(Rect rect) {
if (GUI.Button(buttonRect, tempContent, miniButtonStyle)) {
Undo.IncrementCurrentGroup();
int undoGroup = Undo.GetCurrentGroup();
var builtinPlayerHandlers = new List<VideoPlayerHandler>();
VideoPlayerHandler avProPlayerHandler = null; // only one avpro player handler is supported
var builtinPlayerHandlers = new List<AbstractMediaPlayerHandler>();
AbstractMediaPlayerHandler avProPlayerHandler = null; // only one avpro player handler is supported
bool hasMultipleAvProPlayerHandler = false;
for (int i = 0, count = playerHandlersProperty.arraySize; i < count; i++) {
var playerHandler = playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue as VideoPlayerHandler;
var playerHandler = playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue as AbstractMediaPlayerHandler;
if (playerHandler == null) continue;
if (!playerHandler.IsAvPro)
builtinPlayerHandlers.Add(playerHandler);
Expand Down
26 changes: 14 additions & 12 deletions Packages/idv.jlchntoz.vvmw/Editor/VVMW/PlayListEditorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class PlayListEditorWindow : EditorWindow {
FrontendHandler frontendHandler;
Core loadedCore;
string[] playerHandlerNames;
bool[] playerHandlerTypes;
PlayerType[] playerHandlerTypes;
int firstUnityPlayerIndex = -1, firstAvProPlayerIndex = -1;
[SerializeField] List<PlayList> playLists = new List<PlayList>();
ReorderableList playListView;
Expand Down Expand Up @@ -212,13 +212,13 @@ void DrawPlayListEntry(Rect rect, int index, bool isActive, bool isFocused) {
}
}
}
var isAvPro = playerHandlerTypes != null && entry.playerIndex >= 0 && entry.playerIndex < playerHandlerTypes.Length && playerHandlerTypes[entry.playerIndex];
var playerType = playerHandlerTypes != null && entry.playerIndex >= 0 && entry.playerIndex < playerHandlerTypes.Length ? playerHandlerTypes[entry.playerIndex] : PlayerType.Unknown;
var urlRect = rect;
urlRect.yMin = titleRect.yMax + EditorGUIUtility.standardVerticalSpacing;
urlRect.height = EditorGUIUtility.singleLineHeight;
using (var changed = new EditorGUI.ChangeCheckScope()) {
urlRect = EditorGUI.PrefixLabel(urlRect, Utils.GetTempContent("URL (PC)"));
var newUrl = TrustedUrlUtils.DrawUrlField(entry.url, isAvPro ? TrustedUrlTypes.AVProDesktop : TrustedUrlTypes.UnityVideo, urlRect, "");
var newUrl = TrustedUrlUtils.DrawUrlField(entry.url, playerType.ToTrustUrlType(false), urlRect, "");
if (changed.changed) {
entry.url = newUrl;
selectedPlayList.entries[index] = entry;
Expand All @@ -231,7 +231,7 @@ void DrawPlayListEntry(Rect rect, int index, bool isActive, bool isFocused) {
using (var changed = new EditorGUI.ChangeCheckScope()) {
urlQuestRect = EditorGUI.PrefixLabel(urlQuestRect, Utils.GetTempContent("URL (Quest)"));
var newUrl = string.IsNullOrEmpty(entry.urlForQuest) ? entry.url : entry.urlForQuest;
newUrl = TrustedUrlUtils.DrawUrlField(newUrl, isAvPro ? TrustedUrlTypes.AVProAndroid : TrustedUrlTypes.UnityVideo, urlQuestRect, "");
newUrl = TrustedUrlUtils.DrawUrlField(newUrl, playerType.ToTrustUrlType(true), urlQuestRect, "");
if (changed.changed) {
entry.urlForQuest = newUrl == entry.url ? string.Empty : newUrl;
selectedPlayList.entries[index] = entry;
Expand Down Expand Up @@ -380,20 +380,22 @@ void UpdatePlayerHandlerInfos() {
if (playerHandlerNames == null || playerHandlerNames.Length != handlersCount)
playerHandlerNames = new string[handlersCount];
if (playerHandlerTypes == null || playerHandlerTypes.Length != handlersCount)
playerHandlerTypes = new bool[handlersCount];
playerHandlerTypes = new PlayerType[handlersCount];
for (int i = 0; i < handlersCount; i++) {
var handler = playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue as VideoPlayerHandler;
var handler = playerHandlersProperty.GetArrayElementAtIndex(i).objectReferenceValue as AbstractMediaPlayerHandler;
if (handler == null) {
playerHandlerNames[i] = $"Player {i + 1}";
continue;
}
playerHandlerNames[i] = string.IsNullOrEmpty(handler.playerName) ? handler.name : handler.playerName;
if (handler.IsAvPro) {
playerHandlerTypes[i] = true;
if (firstAvProPlayerIndex < 0) firstAvProPlayerIndex = i;
} else {
playerHandlerTypes[i] = false;
if (firstUnityPlayerIndex < 0) firstUnityPlayerIndex = i;
playerHandlerTypes[i] = handler.GetPlayerType();
switch (playerHandlerTypes[i]) {
case PlayerType.Unity:
if (firstUnityPlayerIndex < 0) firstUnityPlayerIndex = i;
break;
case PlayerType.AVPro:
if (firstAvProPlayerIndex < 0) firstAvProPlayerIndex = i;
break;
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions Packages/idv.jlchntoz.vvmw/Editor/VVMW/PlayerType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace JLChnToZ.VRC.VVMW.Editors {
public enum PlayerType : byte {
Unknown,
Unity,
AVPro,
Image,
}

public static class PlayerTypeExtensions {
public static TrustedUrlTypes ToTrustUrlType(this PlayerType playerType, bool isAndroid) {
switch (playerType) {
case PlayerType.AVPro:
return isAndroid ? TrustedUrlTypes.AVProAndroid : TrustedUrlTypes.AVProDesktop;
case PlayerType.Image:
return TrustedUrlTypes.ImageUrl;
default:
return TrustedUrlTypes.UnityVideo;
}
}

public static PlayerType GetPlayerType(this AbstractMediaPlayerHandler handler) {
if (handler is VideoPlayerHandler videoPlayerHandler)
return videoPlayerHandler.IsAvPro ? PlayerType.AVPro : PlayerType.Unity;
if (handler is ImageViewerHandler)
return PlayerType.Image;
return PlayerType.Unknown;
}
}
}
11 changes: 11 additions & 0 deletions Packages/idv.jlchntoz.vvmw/Editor/VVMW/PlayerType.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &6829130864087985128
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5573889228666286874}
- component: {fileID: 3828550679307862633}
- component: {fileID: 8252950667882052800}
m_Layer: 0
m_Name: Image Module
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &5573889228666286874
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6829130864087985128}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &3828550679307862633
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6829130864087985128}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f8b727e43ffe5844eb8b968a426b5750, type: 3}
m_Name:
m_EditorClassIdentifier:
serializationData:
SerializedFormat: 2
SerializedBytes:
ReferencedUnityObjects: []
SerializedBytesString:
Prefab: {fileID: 0}
PrefabModificationsReferencedUnityObjects: []
PrefabModifications: []
SerializationNodes: []
_udonSharpBackingUdonBehaviour: {fileID: 8252950667882052800}
playerName: ImageViewer
--- !u!114 &8252950667882052800
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6829130864087985128}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 45115577ef41a5b4ca741ed302693907, type: 3}
m_Name:
m_EditorClassIdentifier:
interactTextPlacement: {fileID: 0}
interactText: Use
interactTextGO: {fileID: 0}
proximity: 2
SynchronizePosition: 0
AllowCollisionOwnershipTransfer: 0
Reliable: 0
_syncMethod: 2
serializedProgramAsset: {fileID: 11400000, guid: 3665ae2df7b664c4e97cf8f011407eed,
type: 2}
programSource: {fileID: 11400000, guid: 954c198ace0b97443bb2570ff13e2245, type: 2}
serializedPublicVariablesBytesString: Ai8AAAAAATIAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAFQAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AAAAAAAYBAAAAAAAAACcBBAAAAHQAeQBwAGUAAWgAAABTAHkAcwB0AGUAbQAuAEMAbwBsAGwAZQBjAHQAaQBvAG4AcwAuAEcAZQBuAGUAcgBpAGMALgBMAGkAcwB0AGAAMQBbAFsAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4ALgBJAG4AdABlAHIAZgBhAGMAZQBzAC4ASQBVAGQAbwBuAFYAYQByAGkAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AXQBdACwAIABtAHMAYwBvAHIAbABpAGIAAQEJAAAAVgBhAHIAaQBhAGIAbABlAHMALwEAAAABaAAAAFMAeQBzAHQAZQBtAC4AQwBvAGwAbABlAGMAdABpAG8AbgBzAC4ARwBlAG4AZQByAGkAYwAuAEwAaQBzAHQAYAAxAFsAWwBWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAEkAbgB0AGUAcgBmAGEAYwBlAHMALgBJAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlACwAIABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgBdAF0ALAAgAG0AcwBjAG8AcgBsAGkAYgABAAAABgEAAAAAAAAAAi8CAAAAAUkAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAGAAMQBbAFsAUwB5AHMAdABlAG0ALgBJAG4AdAAzADIALAAgAG0AcwBjAG8AcgBsAGkAYgBdAF0ALAAgAFYAUgBDAC4AVQBkAG8AbgAuAEMAbwBtAG0AbwBuAAIAAAAGAgAAAAAAAAAnAQQAAAB0AHkAcABlAAEXAAAAUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwAsACAAbQBzAGMAbwByAGwAaQBiACcBCgAAAFMAeQBtAGIAbwBsAE4AYQBtAGUAAR8AAABfAF8AXwBVAGQAbwBuAFMAaABhAHIAcABCAGUAaABhAHYAaQBvAHUAcgBWAGUAcgBzAGkAbwBuAF8AXwBfACcBBAAAAHQAeQBwAGUAARYAAABTAHkAcwB0AGUAbQAuAEkAbgB0ADMAMgAsACAAbQBzAGMAbwByAGwAaQBiABcBBQAAAFYAYQBsAHUAZQACAAAABwUHBQcF
publicVariablesUnityEngineObjects: []
publicVariablesSerializationDataFormat: 0

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Packages/idv.jlchntoz.vvmw/Resources/lang.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"NextOn": "Next On >",
"BuiltInPlayer": "Built-in",
"AvProPlayer": "AVPro",
"ImageViewer": "Image",
"QueueModeNext": "Will be enqueued",
"QueueModeInstant": "Will play instantly",
"PickupScreen": "Pickup Screen",
Expand Down Expand Up @@ -71,6 +72,7 @@
"Unknown": "未知錯誤 {0}",
"BuiltInPlayer": "內建",
"AvProPlayer": "AVPro",
"ImageViewer": "圖片",
"QueueModeNext": "將會加入待播清單",
"QueueModeInstant": "將會立即播放",
"PickupScreen": "拾取螢幕",
Expand Down Expand Up @@ -114,6 +116,7 @@
"Unknown": "未知错误 {0}",
"BuiltInPlayer": "内置",
"AvProPlayer": "AVPro",
"ImageViewer": "图片",
"QueueModeNext": "将会加入播放队列",
"QueueModeInstant": "将会立即播放",
"PickupScreen": "拾取屏幕",
Expand Down Expand Up @@ -157,6 +160,7 @@
"NextOn": "次 >",
"BuiltInPlayer": "Video",
"AvProPlayer": "Live",
"ImageViewer": "画像",
"QueueModeNext": "キューに追加されます",
"QueueModeInstant": "すぐに再生されます",
"PickupScreen": "ピックアップスクリーン",
Expand Down Expand Up @@ -200,6 +204,7 @@
"NextOn": "다음 >",
"BuiltInPlayer": "내장",
"AvProPlayer": "AVPro",
"ImageViewer": "이미지",
"QueueModeNext": "큐에 추가됩니다",
"QueueModeInstant": "즉시 재생됩니다",
"PickupScreen": "픽업 스크린",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using UnityEngine;
using VRC.SDKBase;
using UdonSharp;

namespace JLChnToZ.VRC.VVMW {
public abstract class AbstractMediaPlayerHandler : VizVidBehaviour {
[NonSerialized] public Core core;
[Tooltip("The name of current video player. Can be the key mapped in language pack JSON.")]
public string playerName = "";
protected bool isActive, isReady, isPaused;
protected Texture texture;

public virtual bool IsActive { get => isActive; set => isActive = value; }

public virtual bool IsReady => isReady;

public virtual bool IsPlaying => false;

public virtual bool IsPaused => isPaused;

public virtual AudioSource PrimaryAudioSource => null;

public virtual float Time { get => 0; set {} }

public virtual bool Loop { get => false; set {} }

public virtual bool IsAvPro => false;

public virtual float Duration => float.PositiveInfinity;

public virtual Texture Texture => texture;

public abstract void LoadUrl(VRCUrl url, bool reload);

public virtual void Play() {}

public virtual void Pause() {}

public virtual void Stop() {}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Packages/idv.jlchntoz.vvmw/Runtime/VVMW/Core.asset
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ MonoBehaviour:
Data: 24|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: JLChnToZ.VRC.VVMW.VideoPlayerHandler[], JLChnToZ.VVMW
Data: JLChnToZ.VRC.VVMW.AbstractMediaPlayerHandler[], JLChnToZ.VVMW
- Name:
Entry: 8
Data:
Expand Down Expand Up @@ -2632,7 +2632,7 @@ MonoBehaviour:
Data: 158|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: JLChnToZ.VRC.VVMW.VideoPlayerHandler, JLChnToZ.VVMW
Data: JLChnToZ.VRC.VVMW.AbstractMediaPlayerHandler, JLChnToZ.VVMW
- Name:
Entry: 8
Data:
Expand Down
Loading

0 comments on commit e481f7e

Please sign in to comment.