267 lines
8.1 KiB
C#
267 lines
8.1 KiB
C#
using System;
|
|
|
|
using ImagesGui.ImageDiff;
|
|
|
|
using Unity.PlasticSCM.Editor.Diff.Texture.Views;
|
|
using Unity.PlasticSCM.Editor.Diff.Texture.Views.Differences;
|
|
using Unity.PlasticSCM.Editor.Diff.Texture.Views.OnionSkin;
|
|
using Unity.PlasticSCM.Editor.Diff.Texture.Views.SideBySide;
|
|
using Unity.PlasticSCM.Editor.Diff.Texture.Views.Swipe;
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace Unity.PlasticSCM.Editor.Diff.Texture
|
|
{
|
|
internal class ImageDiffViewer : VisualElement
|
|
{
|
|
internal ImageDiffViewer(IImageDiffToolbar toolbar)
|
|
{
|
|
mToolbar = toolbar;
|
|
|
|
style.flexGrow = 1;
|
|
}
|
|
|
|
internal void Dispose()
|
|
{
|
|
DestroyTextures();
|
|
DestroyDiffTexture();
|
|
|
|
if (mOnionSkinView != null)
|
|
mOnionSkinView.Dispose();
|
|
|
|
if (mSideBySideView != null)
|
|
mSideBySideView.Dispose();
|
|
|
|
if (mDifferencesView != null)
|
|
mDifferencesView.Dispose();
|
|
|
|
if (mSwipeView != null)
|
|
mSwipeView.Dispose();
|
|
}
|
|
|
|
internal void SetInfo(
|
|
string leftFile, string rightFile,
|
|
string leftSymbolicName, string rightSymbolicName)
|
|
{
|
|
DestroyTextures();
|
|
DestroyDiffTexture();
|
|
|
|
mLeftTexture = TextureLoader.LoadFromFile(leftFile);
|
|
mRightTexture = TextureLoader.LoadFromFile(rightFile);
|
|
|
|
mToolbar.EnableDifferencesMode();
|
|
|
|
UpdateCurrentView();
|
|
}
|
|
|
|
internal void SetViewMode(ImageDiffMode mode)
|
|
{
|
|
if (mCurrentMode == mode)
|
|
return;
|
|
|
|
mCurrentMode = mode;
|
|
UpdateCurrentView();
|
|
}
|
|
|
|
internal void SetChannelMode(ColorWriteMask mode)
|
|
{
|
|
mChannelMode = mode;
|
|
|
|
if (mDifferencesView != null)
|
|
mDifferencesView.SetChannelMode(mode);
|
|
|
|
if (mSideBySideView != null)
|
|
mSideBySideView.SetChannelMode(mode);
|
|
|
|
if (mOnionSkinView != null)
|
|
mOnionSkinView.SetChannelMode(mode);
|
|
|
|
if (mSwipeView != null)
|
|
mSwipeView.SetChannelMode(mode);
|
|
}
|
|
|
|
internal ImageDiffMode CurrentViewMode { get { return mCurrentMode; } }
|
|
|
|
internal ColorWriteMask CurrentChannelMode { get { return mChannelMode; } }
|
|
|
|
void UpdateCurrentView()
|
|
{
|
|
if (mLeftTexture == null && mRightTexture == null)
|
|
return;
|
|
|
|
VisualElement view = GetOrCreateView(mCurrentMode);
|
|
|
|
ReplaceView(view);
|
|
}
|
|
|
|
VisualElement GetOrCreateView(ImageDiffMode mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case ImageDiffMode.OnionSkin:
|
|
return GetOrCreateOnionSkinView();
|
|
case ImageDiffMode.Differences:
|
|
return GetOrCreateDifferencesView();
|
|
case ImageDiffMode.Swipe:
|
|
return GetOrCreateSwipeView();
|
|
case ImageDiffMode.SideBySide:
|
|
default:
|
|
return GetOrCreateSideBySideView();
|
|
}
|
|
}
|
|
|
|
VisualElement GetOrCreateOnionSkinView()
|
|
{
|
|
if (mOnionSkinView == null)
|
|
mOnionSkinView = new OnionSkinView();
|
|
|
|
mOnionSkinView.SetImages(mLeftTexture, mRightTexture);
|
|
mOnionSkinView.SetChannelMode(mChannelMode);
|
|
return mOnionSkinView;
|
|
}
|
|
|
|
VisualElement GetOrCreateSideBySideView()
|
|
{
|
|
if (mSideBySideView == null)
|
|
mSideBySideView = new SideBySideView();
|
|
|
|
mSideBySideView.SetImages(mLeftTexture, mRightTexture);
|
|
mSideBySideView.SetChannelMode(mChannelMode);
|
|
return mSideBySideView;
|
|
}
|
|
|
|
VisualElement GetOrCreateDifferencesView()
|
|
{
|
|
if (mDifferencesView == null)
|
|
mDifferencesView = new DifferencesView();
|
|
|
|
if (mDiffTexture == null)
|
|
mDiffTexture = ComputePixelDiff(mLeftTexture, mRightTexture);
|
|
|
|
mDifferencesView.SetImage(mDiffTexture);
|
|
mDifferencesView.EnableZoomButtons();
|
|
mDifferencesView.SetChannelMode(mChannelMode);
|
|
return mDifferencesView;
|
|
}
|
|
|
|
VisualElement GetOrCreateSwipeView()
|
|
{
|
|
if (mSwipeView == null)
|
|
mSwipeView = new SwipeView();
|
|
|
|
mSwipeView.SetImages(mLeftTexture, mRightTexture);
|
|
mSwipeView.SetChannelMode(mChannelMode);
|
|
return mSwipeView;
|
|
}
|
|
|
|
static unsafe Texture2D ComputePixelDiff(
|
|
Texture2D leftTexture, Texture2D rightTexture)
|
|
{
|
|
ImagePixelDiff.GetDiffImageSize(
|
|
leftTexture != null ? leftTexture.width : 0,
|
|
leftTexture != null ? leftTexture.height : 0,
|
|
rightTexture != null ? rightTexture.width : 0,
|
|
rightTexture != null ? rightTexture.height : 0,
|
|
out int diffWidth, out int diffHeight);
|
|
|
|
if (diffWidth <= 0 || diffHeight <= 0)
|
|
return null;
|
|
|
|
Color32[] leftPixels = leftTexture != null
|
|
? leftTexture.GetPixels32()
|
|
: new Color32[0];
|
|
Color32[] rightPixels = rightTexture != null
|
|
? rightTexture.GetPixels32()
|
|
: new Color32[0];
|
|
Color32[] diffPixels = new Color32[diffWidth * diffHeight];
|
|
|
|
int bytesPerPixel = 4;
|
|
int leftStride = leftTexture != null
|
|
? leftTexture.width * bytesPerPixel : 0;
|
|
int rightStride = rightTexture != null
|
|
? rightTexture.width * bytesPerPixel : 0;
|
|
int diffStride = diffWidth * bytesPerPixel;
|
|
|
|
fixed (Color32* pLeft = leftPixels)
|
|
fixed (Color32* pRight = rightPixels)
|
|
fixed (Color32* pDiff = diffPixels)
|
|
{
|
|
ImagePixelDiff.PixelDiff(
|
|
(byte*)pLeft,
|
|
leftTexture != null ? leftTexture.width : 0,
|
|
leftTexture != null ? leftTexture.height : 0,
|
|
leftStride,
|
|
(byte*)pRight,
|
|
rightTexture != null ? rightTexture.width : 0,
|
|
rightTexture != null ? rightTexture.height : 0,
|
|
rightStride,
|
|
(byte*)pDiff,
|
|
diffWidth, diffHeight, diffStride,
|
|
bytesPerPixel);
|
|
}
|
|
|
|
Texture2D diffTexture = new Texture2D(
|
|
diffWidth, diffHeight, TextureFormat.RGBA32, false);
|
|
diffTexture.filterMode = FilterMode.Bilinear;
|
|
diffTexture.hideFlags = HideFlags.HideAndDontSave;
|
|
diffTexture.SetPixels32(diffPixels);
|
|
diffTexture.Apply();
|
|
|
|
return diffTexture;
|
|
}
|
|
|
|
void ReplaceView(VisualElement view)
|
|
{
|
|
if (mCurrentView == view)
|
|
return;
|
|
|
|
if (mCurrentView != null)
|
|
Remove(mCurrentView);
|
|
|
|
Add(view);
|
|
mCurrentView = view;
|
|
}
|
|
|
|
void DestroyTextures()
|
|
{
|
|
if (mLeftTexture != null)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(mLeftTexture);
|
|
mLeftTexture = null;
|
|
}
|
|
|
|
if (mRightTexture != null)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(mRightTexture);
|
|
mRightTexture = null;
|
|
}
|
|
}
|
|
|
|
void DestroyDiffTexture()
|
|
{
|
|
if (mDiffTexture == null)
|
|
return;
|
|
|
|
UnityEngine.Object.DestroyImmediate(mDiffTexture);
|
|
mDiffTexture = null;
|
|
}
|
|
|
|
VisualElement mCurrentView;
|
|
ImageDiffMode mCurrentMode = ImageDiffMode.SideBySide;
|
|
ColorWriteMask mChannelMode = ColorWriteMask.All;
|
|
|
|
Texture2D mLeftTexture;
|
|
Texture2D mRightTexture;
|
|
Texture2D mDiffTexture;
|
|
|
|
OnionSkinView mOnionSkinView;
|
|
SideBySideView mSideBySideView;
|
|
DifferencesView mDifferencesView;
|
|
SwipeView mSwipeView;
|
|
|
|
readonly IImageDiffToolbar mToolbar;
|
|
}
|
|
}
|