// // Copyright (C) 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // namespace Google.Android.AppBundle.Editor.Internal.PlayServices { using UnityEditor; using UnityEngine; /// /// Window which displays a scrollable text area and two buttons at the bottom. /// public class TextAreaDialog : EditorWindow { /// /// Delegate type, called when a button is clicked. /// public delegate void ButtonClicked(TextAreaDialog dialog); /// /// Delegate called when a button is clicked. /// public ButtonClicked buttonClicked; /// /// Whether this window should be modal. /// NOTE: This emulates modal behavior by re-acquiring focus when it's lost. /// public bool modal = true; /// /// Set the text to display in the summary area of the window. /// public string summaryText = ""; /// /// Set the text to display on the "yes" (left-most) button. /// public string yesText = ""; /// /// Set the text to display on the "no" (right-most) button. /// public string noText = ""; /// /// Set the text to display in the scrollable text area. /// public string bodyText = ""; /// /// Result of yes / no button press. true if the "yes" button was pressed, false if the /// "no" button was pressed. Defaults to "false". /// public bool result = false; /// /// Whether either button was clicked. /// private bool yesNoClicked = false; /// /// Current position of the scrollbar. /// public Vector2 scrollPosition; /// /// Get the existing text area window or create a new one. /// /// Title to display on the window. /// Reference to this class public static TextAreaDialog CreateTextAreaDialog(string title) { TextAreaDialog window = (TextAreaDialog)EditorWindow.GetWindow(typeof(TextAreaDialog), true, title, true); window.Initialize(); return window; } public virtual void Initialize() { yesText = ""; noText = ""; summaryText = ""; bodyText = ""; result = false; yesNoClicked = false; scrollPosition = new Vector2(0, 0); minSize = new Vector2(300, 200); position = new Rect(UnityEngine.Screen.width / 3, UnityEngine.Screen.height / 3, minSize.x * 2, minSize.y * 2); } // Draw the GUI. protected virtual void OnGUI() { GUILayout.BeginVertical(); GUILayout.Label(summaryText, EditorStyles.boldLabel); scrollPosition = GUILayout.BeginScrollView(scrollPosition); // Unity text elements can only display up to a small X number of characters (rumors // are ~65k) so generate a set of labels one for each subset of the text being // displayed. int bodyTextOffset = 0; System.Collections.Generic.List bodyTextList = new System.Collections.Generic.List(); const int chunkSize = 5000; // Conservative chunk size < 65k characters. while (bodyTextOffset < bodyText.Length) { int readSize = chunkSize; readSize = bodyTextOffset + readSize >= bodyText.Length ? bodyText.Length - bodyTextOffset : readSize; bodyTextList.Add(bodyText.Substring(bodyTextOffset, readSize)); bodyTextOffset += readSize; } foreach (string bodyTextChunk in bodyTextList) { float pixelHeight = EditorStyles.wordWrappedLabel.CalcHeight( new GUIContent(bodyTextChunk), position.width); EditorGUILayout.SelectableLabel(bodyTextChunk, EditorStyles.wordWrappedLabel, GUILayout.Height(pixelHeight)); } GUILayout.EndScrollView(); bool yesPressed = false; bool noPressed = false; GUILayout.BeginHorizontal(); if (yesText != "") yesPressed = GUILayout.Button(yesText); if (noText != "") noPressed = GUILayout.Button(noText); GUILayout.EndHorizontal(); GUILayout.EndVertical(); // If yes or no buttons were pressed, call the buttonClicked delegate. if (yesPressed || noPressed) { yesNoClicked = true; if (yesPressed) { result = true; } else if (noPressed) { result = false; } // TODO: figure out why the click delegate wasn't being called (need to force Close) if (buttonClicked == null) { Close(); } else { buttonClicked(this); } } } // Optionally make the dialog modal. protected virtual void OnLostFocus() { if (modal) Focus(); } // If the window is destroyed click the no button if a listener is attached. protected virtual void OnDestroy() { if (!yesNoClicked) { result = false; if (buttonClicked != null) buttonClicked(this); } } } }