first commit
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
using Codice.Client.Common.Threading;
|
||||
using Codice.CM.Common;
|
||||
using Codice.Utils;
|
||||
using PlasticGui;
|
||||
using PlasticGui.WorkspaceWindow;
|
||||
using PlasticGui.WebApi.Responses;
|
||||
using Unity.PlasticSCM.Editor.Tool;
|
||||
using Unity.PlasticSCM.Editor.UI.UIElements;
|
||||
using Unity.PlasticSCM.Editor.WebApi;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Welcome
|
||||
{
|
||||
class DownloadAndInstallOperation
|
||||
{
|
||||
internal interface INotify
|
||||
{
|
||||
void InstallationStarted();
|
||||
void InstallationFinished();
|
||||
}
|
||||
|
||||
internal static void Run(
|
||||
Edition plasticEdition,
|
||||
string installerDestinationPath,
|
||||
ProgressControlsForDialogs progressControls,
|
||||
INotify notify)
|
||||
{
|
||||
((IProgressControls)progressControls).ShowProgress(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.DownloadingProgress));
|
||||
|
||||
NewVersionResponse plasticVersion = null;
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
plasticVersion = WebRestApiClient.PlasticScm.
|
||||
GetLastVersion(plasticEdition);
|
||||
|
||||
if (plasticVersion == null)
|
||||
return;
|
||||
|
||||
string installerUrl = GetInstallerUrl(
|
||||
plasticVersion.Version,
|
||||
plasticEdition == Edition.Cloud);
|
||||
|
||||
DownloadInstaller(
|
||||
installerUrl,
|
||||
installerDestinationPath,
|
||||
progressControls);
|
||||
|
||||
if (!PlatformIdentifier.IsMac())
|
||||
return;
|
||||
|
||||
installerDestinationPath = UnZipMacOsPackage(
|
||||
installerDestinationPath);
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
((IProgressControls)progressControls).HideProgress();
|
||||
|
||||
if (waiter.Exception != null)
|
||||
{
|
||||
((IProgressControls)progressControls).ShowError(
|
||||
waiter.Exception.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (plasticVersion == null)
|
||||
{
|
||||
((IProgressControls)progressControls).ShowError(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.ConnectingError));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(installerDestinationPath))
|
||||
return;
|
||||
|
||||
RunInstaller(
|
||||
installerDestinationPath,
|
||||
progressControls,
|
||||
notify);
|
||||
});
|
||||
}
|
||||
|
||||
static void RunInstaller(
|
||||
string installerPath,
|
||||
ProgressControlsForDialogs progressControls,
|
||||
INotify notify)
|
||||
{
|
||||
progressControls.ProgressData.ProgressPercent = -1;
|
||||
|
||||
((IProgressControls)progressControls).ShowProgress(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.InstallingProgress));
|
||||
|
||||
notify.InstallationStarted();
|
||||
|
||||
MacOSConfigWorkaround configWorkaround = new MacOSConfigWorkaround();
|
||||
|
||||
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
|
||||
waiter.Execute(
|
||||
/*threadOperationDelegate*/ delegate
|
||||
{
|
||||
configWorkaround.CreateClientConfigIfNeeded();
|
||||
|
||||
Process installerProcess =
|
||||
LaunchInstaller.ForPlatform(installerPath);
|
||||
|
||||
if (installerProcess != null)
|
||||
installerProcess.WaitForExit();
|
||||
|
||||
configWorkaround.DeleteClientConfigIfNeeded();
|
||||
},
|
||||
/*afterOperationDelegate*/ delegate
|
||||
{
|
||||
notify.InstallationFinished();
|
||||
((IProgressControls)progressControls).HideProgress();
|
||||
|
||||
if (waiter.Exception != null)
|
||||
{
|
||||
((IProgressControls)progressControls).ShowError(
|
||||
waiter.Exception.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
File.Delete(installerPath);
|
||||
});
|
||||
}
|
||||
|
||||
static void DownloadInstaller(
|
||||
string url,
|
||||
string destinationPath,
|
||||
ProgressControlsForDialogs progressControls)
|
||||
{
|
||||
int bytesProcessed = 0;
|
||||
|
||||
Stream remoteStream = null;
|
||||
Stream localStream = null;
|
||||
WebResponse response = null;
|
||||
|
||||
try
|
||||
{
|
||||
WebRequest request = WebRequest.Create(url);
|
||||
response = request.GetResponse();
|
||||
|
||||
long totalBytes = response.ContentLength;
|
||||
|
||||
if (File.Exists(destinationPath) &&
|
||||
new FileInfo(destinationPath).Length == totalBytes)
|
||||
{
|
||||
UnityEngine.Debug.LogFormat(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.SkippingDownloadFileExists),
|
||||
destinationPath);
|
||||
return;
|
||||
}
|
||||
|
||||
remoteStream = response.GetResponseStream();
|
||||
|
||||
localStream = File.Create(destinationPath);
|
||||
|
||||
byte[] buffer = new byte[100 * 1024];
|
||||
int bytesRead;
|
||||
|
||||
do
|
||||
{
|
||||
bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
|
||||
localStream.Write(buffer, 0, bytesRead);
|
||||
bytesProcessed += bytesRead;
|
||||
|
||||
progressControls.ProgressData.ProgressPercent =
|
||||
GetProgressBarPercent.ForTransfer(
|
||||
bytesProcessed,
|
||||
totalBytes) / 100f;
|
||||
} while (bytesRead > 0);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (response != null)
|
||||
response.Close();
|
||||
|
||||
if (remoteStream != null)
|
||||
remoteStream.Close();
|
||||
|
||||
if (localStream != null)
|
||||
localStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
static string UnZipMacOsPackage(
|
||||
string zipInstallerPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
string pkgInstallerPath = zipInstallerPath.Substring(
|
||||
0, zipInstallerPath.Length - ".zip".Length);
|
||||
|
||||
string unzipCommand = string.Format(
|
||||
"unzip -p \"{0}\" > \"{1}\"",
|
||||
zipInstallerPath, pkgInstallerPath);
|
||||
|
||||
unzipCommand = unzipCommand.Replace("\"", "\"\"");
|
||||
|
||||
ProcessStartInfo processStartInfo = new ProcessStartInfo();
|
||||
processStartInfo.FileName = "/bin/bash";
|
||||
processStartInfo.Arguments = string.Format("-c \"{0}\"", unzipCommand);
|
||||
processStartInfo.UseShellExecute = false;
|
||||
processStartInfo.RedirectStandardOutput = true;
|
||||
processStartInfo.CreateNoWindow = true;
|
||||
|
||||
Process process = Process.Start(processStartInfo);
|
||||
process.WaitForExit();
|
||||
|
||||
return pkgInstallerPath;
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(zipInstallerPath);
|
||||
}
|
||||
}
|
||||
|
||||
static string GetInstallerUrl(
|
||||
string version,
|
||||
bool isCloudEdition)
|
||||
{
|
||||
string edition = isCloudEdition ?
|
||||
"cloudedition" : "full";
|
||||
|
||||
string platform = PlatformIdentifier.IsMac() ?
|
||||
"macosx" : "windows";
|
||||
|
||||
return string.Format(
|
||||
@"https://www.plasticscm.com/download/downloadinstaller/{0}/plasticscm/{1}/{2}",
|
||||
version,
|
||||
platform,
|
||||
edition);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f00521067f54ce541951ab90047cc3f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Codice.Utils;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Welcome
|
||||
{
|
||||
static class GetInstallerTmpFileName
|
||||
{
|
||||
internal static string ForPlatform()
|
||||
{
|
||||
string fileName = Guid.NewGuid().ToString();
|
||||
|
||||
if (PlatformIdentifier.IsWindows())
|
||||
fileName += ".exe";
|
||||
|
||||
if (PlatformIdentifier.IsMac())
|
||||
fileName += ".pkg.zip";
|
||||
|
||||
return Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
fileName);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e8b32f158e489044a2b257700530f05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,49 @@
|
||||
using System.IO;
|
||||
using Codice.Client.Common;
|
||||
using Codice.Utils;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Welcome
|
||||
{
|
||||
class MacOSConfigWorkaround
|
||||
{
|
||||
/* In macOS there is no way to pass a parameter
|
||||
* to the PKG installer to avoid launching
|
||||
* Plastic at the end of the installation process.
|
||||
|
||||
* As a workaround, we can create an empty client.conf in
|
||||
* the user config folder. This way the installer skips
|
||||
* launching Plastic at the end of the installation process.
|
||||
|
||||
* see /01plastic/install/mac/macplastic/Scripts/postinstall
|
||||
|
||||
* Then, we delete the client.conf file if we created it */
|
||||
|
||||
internal void CreateClientConfigIfNeeded()
|
||||
{
|
||||
if (!PlatformIdentifier.IsMac())
|
||||
return;
|
||||
|
||||
string clientConfFile = ConfigFileLocation.GetConfigFilePath(
|
||||
ClientConfig.CLIENT_CONFIG_FILE_NAME);
|
||||
|
||||
if (File.Exists(clientConfFile))
|
||||
return;
|
||||
|
||||
File.Create(clientConfFile).Close();
|
||||
mClientConfigCreated = true;
|
||||
}
|
||||
|
||||
internal void DeleteClientConfigIfNeeded()
|
||||
{
|
||||
if (!mClientConfigCreated)
|
||||
return;
|
||||
|
||||
string clientConfFile = ConfigFileLocation.GetConfigFilePath(
|
||||
ClientConfig.CLIENT_CONFIG_FILE_NAME);
|
||||
|
||||
File.Delete(clientConfFile);
|
||||
}
|
||||
|
||||
bool mClientConfigCreated;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc1e10ffb13c5b548948d8c725368507
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,306 @@
|
||||
using Codice.Client.BaseCommands;
|
||||
using Codice.Client.Common;
|
||||
using PlasticGui;
|
||||
using PlasticGui.WebApi;
|
||||
using Unity.PlasticSCM.Editor.AssetUtils;
|
||||
using Unity.PlasticSCM.Editor.Configuration.CloudEdition.Welcome;
|
||||
using Unity.PlasticSCM.Editor.Configuration.TeamEdition;
|
||||
using Unity.PlasticSCM.Editor.UI;
|
||||
using Unity.PlasticSCM.Editor.UI.Progress;
|
||||
using Unity.PlasticSCM.Editor.Views.CreateWorkspace;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.Views.Welcome
|
||||
{
|
||||
internal class WelcomeView
|
||||
{
|
||||
internal WelcomeView(
|
||||
PlasticWindow parentWindow,
|
||||
CreateWorkspaceView.ICreateWorkspaceListener createWorkspaceListener,
|
||||
IPlasticAPI plasticApi,
|
||||
IPlasticWebRestApi plasticWebRestApi,
|
||||
CmConnection cmConnection)
|
||||
{
|
||||
mParentWindow = parentWindow;
|
||||
mCreateWorkspaceListener = createWorkspaceListener;
|
||||
mPlasticApi = plasticApi;
|
||||
mPlasticWebRestApi = plasticWebRestApi;
|
||||
mCmConnection = cmConnection;
|
||||
|
||||
mConfigureProgress = new ProgressControlsForViews();
|
||||
autoLoginState = AutoLogin.State.Off;
|
||||
}
|
||||
|
||||
internal void Update()
|
||||
{
|
||||
if (mCreateWorkspaceView != null)
|
||||
mCreateWorkspaceView.Update();
|
||||
|
||||
mConfigureProgress.UpdateDeterminateProgress(mParentWindow);
|
||||
}
|
||||
|
||||
internal void OnGUI(bool clientNeedsConfiguration)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.Space(LEFT_MARGIN);
|
||||
|
||||
DoContentViewArea(
|
||||
clientNeedsConfiguration,
|
||||
mIsCreateWorkspaceButtonClicked);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
internal void OnUserClosedConfigurationWindow()
|
||||
{
|
||||
((IProgressControls)mConfigureProgress).HideProgress();
|
||||
|
||||
ClientConfig.Reset();
|
||||
CmConnection.Reset();
|
||||
ClientHandlers.Register();
|
||||
}
|
||||
|
||||
void DoContentViewArea(
|
||||
bool clientNeedsConfiguration,
|
||||
bool isCreateWorkspaceButtonClicked)
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Space(TOP_MARGIN);
|
||||
|
||||
if (isCreateWorkspaceButtonClicked)
|
||||
GetCreateWorkspaceView().OnGUI();
|
||||
else
|
||||
DoSetupViewArea(
|
||||
clientNeedsConfiguration,
|
||||
mConfigureProgress);
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
void DoSetupViewArea(
|
||||
bool clientNeedsConfiguration,
|
||||
ProgressControlsForViews configureProgress)
|
||||
{
|
||||
DoTitleLabel();
|
||||
|
||||
GUILayout.Space(STEPS_TOP_MARGIN);
|
||||
|
||||
bool isStep1Completed =
|
||||
!clientNeedsConfiguration &&
|
||||
!configureProgress.ProgressData.IsOperationRunning;
|
||||
|
||||
DoStepsArea(isStep1Completed, configureProgress.ProgressData);
|
||||
|
||||
GUILayout.Space(BUTTON_MARGIN);
|
||||
|
||||
DoActionButtonsArea(
|
||||
isStep1Completed,
|
||||
configureProgress);
|
||||
|
||||
DoNotificationArea(configureProgress.ProgressData);
|
||||
}
|
||||
|
||||
void DoActionButtonsArea(
|
||||
bool isStep1Completed,
|
||||
ProgressControlsForViews configureProgress)
|
||||
{
|
||||
DoActionButton(
|
||||
isStep1Completed,
|
||||
configureProgress);
|
||||
}
|
||||
|
||||
void DoActionButton(
|
||||
bool isStep1Completed,
|
||||
ProgressControlsForViews configureProgress)
|
||||
{
|
||||
if (!isStep1Completed)
|
||||
{
|
||||
DoConfigureButton(configureProgress);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GUILayout.Button(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.CreateWorkspace),
|
||||
GUILayout.Width(BUTTON_WIDTH)))
|
||||
mIsCreateWorkspaceButtonClicked = true;
|
||||
}
|
||||
|
||||
void DoConfigureButton(ProgressControlsForViews configureProgress)
|
||||
{
|
||||
bool isAutoLoginRunning = autoLoginState > AutoLogin.State.Running && autoLoginState <= AutoLogin.State.InitializingPlastic;
|
||||
GUI.enabled = !(configureProgress.ProgressData.IsOperationRunning || isAutoLoginRunning);
|
||||
|
||||
if (GUILayout.Button(PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.LoginOrSignUp),
|
||||
GUILayout.Width(BUTTON_WIDTH)))
|
||||
{
|
||||
if (autoLoginState > AutoLogin.State.Off && autoLoginState <= AutoLogin.State.InitializingPlastic)
|
||||
{
|
||||
autoLoginState = AutoLogin.State.Running;
|
||||
AutoLogin autoLogin = new AutoLogin();
|
||||
autoLogin.Run();
|
||||
}
|
||||
|
||||
if (autoLoginState != AutoLogin.State.ErrorNoToken)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
((IProgressControls)configureProgress).ShowProgress(string.Empty);
|
||||
|
||||
// Login button defaults to Cloud sign up
|
||||
CloudEditionWelcomeWindow.ShowWindow(
|
||||
mPlasticWebRestApi,
|
||||
mCmConnection,
|
||||
this);
|
||||
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
|
||||
// If client configuration cannot be determined, keep login button default as Cloud
|
||||
// sign in window, but show Enterprise option as well
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(
|
||||
PlasticLocalization.Name.NeedEnterprise.GetString(),
|
||||
UnityStyles.LinkLabel,
|
||||
GUILayout.Width(BUTTON_WIDTH),
|
||||
GUILayout.Height(20)))
|
||||
{
|
||||
TeamEditionConfigurationWindow.ShowWindow(mPlasticWebRestApi, this);
|
||||
}
|
||||
|
||||
GUILayout.Space(BUTTON_MARGIN);
|
||||
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
static void DoStepsArea(
|
||||
bool isStep1Completed,
|
||||
ProgressControlsForViews.Data configureProgressData)
|
||||
{
|
||||
DoLoginOrSignUpStep(isStep1Completed, configureProgressData);
|
||||
|
||||
DoCreatePlasticWorkspaceStep();
|
||||
}
|
||||
|
||||
static void DoLoginOrSignUpStep(
|
||||
bool isStep1Completed,
|
||||
ProgressControlsForViews.Data progressData)
|
||||
{
|
||||
Texture2D stepImage = (isStep1Completed) ? Images.GetStepOkIcon() : Images.GetStep1Icon();
|
||||
|
||||
string stepText = GetConfigurationStepText(progressData, isStep1Completed);
|
||||
|
||||
GUIStyle style = new GUIStyle(EditorStyles.label);
|
||||
style.richText = true;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
DoStepLabel(stepText, stepImage, style);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void DoCreatePlasticWorkspaceStep()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
DoStepLabel(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.CreateAUnityVersionControlWorkspace),
|
||||
Images.GetStep2Icon(),
|
||||
EditorStyles.label);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void DoStepLabel(
|
||||
string text,
|
||||
Texture2D image,
|
||||
GUIStyle style)
|
||||
{
|
||||
GUILayout.Space(STEPS_LEFT_MARGIN);
|
||||
|
||||
GUIContent stepLabelContent = new GUIContent(
|
||||
string.Format(" {0}", text),
|
||||
image);
|
||||
|
||||
GUILayout.Label(
|
||||
stepLabelContent,
|
||||
style,
|
||||
GUILayout.Height(STEP_LABEL_HEIGHT));
|
||||
}
|
||||
|
||||
static void DoTitleLabel()
|
||||
{
|
||||
GUIContent labelContent = new GUIContent(
|
||||
PlasticLocalization.GetString(PlasticLocalization.Name.NextStepsToSetup),
|
||||
Images.GetInfoIcon());
|
||||
|
||||
GUILayout.Label(labelContent, EditorStyles.boldLabel);
|
||||
}
|
||||
|
||||
static void DoNotificationArea(ProgressControlsForViews.Data configureProgressData)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(configureProgressData.NotificationMessage))
|
||||
DrawProgressForViews.ForNotificationArea(configureProgressData);
|
||||
}
|
||||
|
||||
static string GetConfigurationStepText(
|
||||
ProgressControlsForViews.Data progressData,
|
||||
bool isStep1Completed)
|
||||
{
|
||||
string result = PlasticLocalization.GetString(
|
||||
PlasticLocalization.Name.LoginOrSignUpUnityVersionControl);
|
||||
|
||||
if (isStep1Completed)
|
||||
return result;
|
||||
|
||||
if (!progressData.IsOperationRunning)
|
||||
return result;
|
||||
|
||||
return string.Format("<b>{0}</b>", result);
|
||||
}
|
||||
|
||||
CreateWorkspaceView GetCreateWorkspaceView()
|
||||
{
|
||||
if (mCreateWorkspaceView != null)
|
||||
return mCreateWorkspaceView;
|
||||
|
||||
string workspacePath = ProjectPath.FromApplicationDataPath(
|
||||
ApplicationDataPath.Get());
|
||||
|
||||
mCreateWorkspaceView = new CreateWorkspaceView(
|
||||
mParentWindow,
|
||||
mCreateWorkspaceListener,
|
||||
mPlasticApi,
|
||||
mPlasticWebRestApi,
|
||||
workspacePath);
|
||||
|
||||
return mCreateWorkspaceView;
|
||||
}
|
||||
|
||||
internal AutoLogin.State autoLoginState = AutoLogin.State.Off;
|
||||
|
||||
bool mIsCreateWorkspaceButtonClicked = false;
|
||||
|
||||
CreateWorkspaceView mCreateWorkspaceView;
|
||||
readonly ProgressControlsForViews mConfigureProgress;
|
||||
readonly CmConnection mCmConnection;
|
||||
readonly IPlasticAPI mPlasticApi;
|
||||
readonly IPlasticWebRestApi mPlasticWebRestApi;
|
||||
readonly CreateWorkspaceView.ICreateWorkspaceListener mCreateWorkspaceListener;
|
||||
readonly PlasticWindow mParentWindow;
|
||||
|
||||
const int LEFT_MARGIN = 30;
|
||||
const int TOP_MARGIN = 20;
|
||||
const int STEPS_TOP_MARGIN = 5;
|
||||
const int STEPS_LEFT_MARGIN = 12;
|
||||
const int BUTTON_MARGIN = 10;
|
||||
const int STEP_LABEL_HEIGHT = 20;
|
||||
const int BUTTON_WIDTH = 170;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9298a2c04dfc944bbc6ea156f4e2104
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user