//
// ToolbarWrapper.cs
//
// Author:
// toadicus <>
//
// Copyright (c) 2013 toadicus
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
using System;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace VOID
{
///
/// Wraps a Toolbar clickable button, after fetching it from a foreign assembly.
///
internal class ToolbarButtonWrapper
{
protected static System.Type ToolbarManager;
protected static object TBManagerInstance;
protected static MethodInfo TBManagerAdd;
///
/// Wraps the ToolbarManager class, if present.
///
/// true, if ToolbarManager is wrapped, false otherwise.
protected static bool TryWrapToolbarManager()
{
if (ToolbarManager == null)
{
Tools.PostDebugMessage(string.Format(
"{0}: Loading ToolbarManager.",
"ToolbarButtonWrapper"
));
ToolbarManager = AssemblyLoader.loadedAssemblies
.Select(a => a.assembly.GetExportedTypes())
.SelectMany(t => t)
.FirstOrDefault(t => t.FullName == "Toolbar.ToolbarManager");
Tools.PostDebugMessage(string.Format(
"{0}: Loaded ToolbarManager. Getting Instance.",
"ToolbarButtonWrapper"
));
if (ToolbarManager == null)
{
return false;
}
TBManagerInstance = ToolbarManager.GetProperty(
"Instance",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static
)
.GetValue(null, null);
Tools.PostDebugMessage(string.Format(
"{0}: Got ToolbarManager Instance '{1}'. Getting 'add' method.",
"ToolbarButtonWrapper",
TBManagerInstance
));
TBManagerAdd = ToolbarManager.GetMethod("add");
Tools.PostDebugMessage(string.Format(
"{0}: Got ToolbarManager Instance 'add' method. Loading IButton.",
"ToolbarButtonWrapper"
));
}
return true;
}
///
/// Gets a value indicating whether is present.
///
/// true, if ToolbarManager is wrapped, false otherwise.
public static bool ToolbarManagerPresent
{
get
{
return TryWrapToolbarManager();
}
}
///
/// If ToolbarManager is present, initializes a new instance of the class.
///
/// Namespace, usually the plugin name.
/// Identifier, unique per namespace.
/// If ToolbarManager is present, a new object, null otherwise.
public static ToolbarButtonWrapper TryWrapToolbarButton(string ns, string id)
{
if (ToolbarManagerPresent)
{
object button = TBManagerAdd.Invoke(TBManagerInstance, new object[] { ns, id });
Tools.PostDebugMessage(string.Format(
"{0}: Added Button '{1}' with ToolbarManager. Getting 'Text' property",
"ToolbarButtonWrapper",
button.ToString()
));
return new ToolbarButtonWrapper(button);
}
else
{
return null;
}
}
protected System.Type IButton;
protected object Button;
protected PropertyInfo ButtonText;
protected PropertyInfo ButtonTextColor;
protected PropertyInfo ButtonTexturePath;
protected PropertyInfo ButtonToolTip;
protected PropertyInfo ButtonVisible;
protected PropertyInfo ButtonVisibility;
protected PropertyInfo ButtonEnalbed;
protected PropertyInfo ButtonImportant;
protected EventInfo ButtonOnClick;
protected EventInfo ButtonOnMouseEnter;
protected EventInfo ButtonOnMouseLeave;
protected MethodInfo ButtonDestroy;
protected System.Type GameScenesVisibilityType;
///
/// The text displayed on the button. Set to null to hide text.
///
///
/// The text can be changed at any time to modify the button's appearance. Note that since this will also
/// modify the button's size, this feature should be used sparingly, if at all.
///
///
public string Text
{
get
{
return this.ButtonText.GetValue(this.Button, null) as String;
}
set
{
this.ButtonText.SetValue(this.Button, value, null);
}
}
///
/// The color the button text is displayed with. Defaults to Color.white.
///
///
/// The text color can be changed at any time to modify the button's appearance.
///
public Color TextColor
{
get
{
return (Color)this.ButtonTextColor.GetValue(this.Button, null);
}
set
{
this.ButtonTextColor.SetValue(this.Button, value, null);
}
}
///
/// The path of a texture file to display an icon on the button. Set to null to hide icon.
///
///
///
/// A texture path on a button will have precedence over text. That is, if both text and texture path
/// have been set on a button, the button will show the texture, not the text.
///
///
/// The texture size must not exceed 24x24 pixels.
///
///
/// The texture path must be relative to the "GameData" directory, and must not specify a file name suffix.
/// Valid example: MyAddon/Textures/icon_mybutton
///
///
/// The texture path can be changed at any time to modify the button's appearance.
///
///
///
public string TexturePath
{
get
{
return this.ButtonTexturePath.GetValue(this.Button, null) as string;
}
set
{
this.ButtonTexturePath.SetValue(this.Button, value, null);
}
}
///
/// The button's tool tip text. Set to null if no tool tip is desired.
///
///
/// Tool Tip Text Should Always Use Headline Style Like This.
///
public string ToolTip
{
get
{
return this.ButtonToolTip.GetValue(this.Button, null) as string;
}
set
{
this.ButtonToolTip.SetValue(this.Button, value, null);
}
}
///
/// Whether this button is currently visible or not. Can be used in addition to or as a replacement for .
///
public bool Visible
{
get
{
return (bool)this.ButtonVisible.GetValue(this.Button, null);
}
set
{
this.ButtonVisible.SetValue(this.Button, value, null);
}
}
///
/// Whether this button is currently enabled (clickable) or not. This will not affect the player's ability to
/// position the button on their screen.
///
public bool Enabled
{
get
{
return (bool)this.ButtonEnalbed.GetValue(this.Button, null);
}
set
{
this.ButtonEnalbed.SetValue(this.Button, value, null);
}
}
///
/// Whether this button is currently "important." Set to false to return to normal button behaviour.
///
///
///
/// This can be used to temporarily force the button to be shown on the screen regardless of the toolbar being
/// currently in auto-hidden mode. For example, a button that signals the arrival of a private message in a
/// chat room could mark itself as "important" as long as the message has not been read.
///
///
/// Setting this property does not change the appearance of the button. use to
/// change the button's icon.
///
///
/// This feature should be used only sparingly, if at all, since it forces the button to be displayed on screen
/// even when it normally wouldn't.
///
///
/// true if important; otherwise, false.
public bool Important
{
get
{
return (bool)this.ButtonImportant.GetValue(this.Button, null);
}
set
{
this.ButtonImportant.SetValue(this.Button, value, null);
}
}
private ToolbarButtonWrapper()
{
}
///
/// Initializes a new instance of the class.
///
/// Namespace, usually the plugin name.
/// Identifier, unique per namespace.
protected ToolbarButtonWrapper(object button)
{
this.Button = button;
this.IButton = AssemblyLoader.loadedAssemblies
.Select(a => a.assembly.GetExportedTypes())
.SelectMany(t => t)
.FirstOrDefault(t => t.FullName == "Toolbar.IButton");
Tools.PostDebugMessage(string.Format(
"{0}: Loaded IButton. Adding Button with ToolbarManager.",
this.GetType().Name
));
this.ButtonText = this.IButton.GetProperty("Text");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'Text' property. Getting 'TextColor' property.",
this.GetType().Name
));
this.ButtonTextColor = this.IButton.GetProperty("TextColor");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'TextColor' property. Getting 'TexturePath' property.",
this.GetType().Name
));
this.ButtonTexturePath = this.IButton.GetProperty("TexturePath");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'TexturePath' property. Getting 'ToolTip' property.",
this.GetType().Name
));
this.ButtonToolTip = this.IButton.GetProperty("ToolTip");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'ToolTip' property. Getting 'Visible' property.",
this.GetType().Name
));
this.ButtonVisible = this.IButton.GetProperty("Visible");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'Visible' property. Getting 'Visibility' property.",
this.GetType().Name
));
this.ButtonVisibility = this.IButton.GetProperty("Visibility");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'Visibility' property. Getting 'Enabled' property.",
this.GetType().Name
));
this.ButtonEnalbed = this.IButton.GetProperty("Enabled");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'Enabled' property. Getting 'OnClick' event.",
this.GetType().Name
));
this.ButtonImportant = this.IButton.GetProperty("Important");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'Enabled' property. Getting 'OnClick' event.",
this.GetType().Name
));
this.ButtonOnClick = this.IButton.GetEvent("OnClick");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'OnClick' event '{1}'. Getting 'OnMouseEnter' event.",
this.GetType().Name,
this.ButtonOnClick.ToString()
));
this.ButtonOnMouseEnter = this.IButton.GetEvent("OnMouseEnter");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'OnMouseEnter' event '{1}'. Getting 'OnMouseLeave' event.",
this.GetType().Name,
this.ButtonOnClick.ToString()
));
this.ButtonOnMouseLeave = this.IButton.GetEvent("OnMouseLeave");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'OnMouseLeave' event '{1}'. Getting 'Destroy' method.",
this.GetType().Name,
this.ButtonOnClick.ToString()
));
this.ButtonDestroy = this.IButton.GetMethod("Destroy");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'Destroy' property '{1}'. Loading GameScenesVisibility class.",
this.GetType().Name,
this.ButtonDestroy.ToString()
));
this.GameScenesVisibilityType = AssemblyLoader.loadedAssemblies
.Select(a => a.assembly.GetExportedTypes())
.SelectMany(t => t)
.FirstOrDefault(t => t.FullName == "Toolbar.GameScenesVisibility");
Tools.PostDebugMessage(string.Format(
"{0}: Got 'GameScenesVisibility' class '{1}'.",
this.GetType().Name,
this.GameScenesVisibilityType.ToString()
));
Tools.PostDebugMessage("ToolbarButtonWrapper built!");
}
///
/// Adds event handler to receive "on click" events.
///
///
///
/// ToolbarButtonWrapper button = ...
/// button.AddButtonClickHandler(
/// (e) =>
/// {
/// Debug.Log("button clicked, mouseButton: " + e.Mousebutton");
/// }
/// );
///
///
/// Delegate to handle "on click" events
public void AddButtonClickHandler(Action