You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
657 lines
19 KiB
657 lines
19 KiB
using UnityEngine; |
|
using FairyGUI.Utils; |
|
|
|
namespace FairyGUI |
|
{ |
|
/// <summary> |
|
/// GButton class. |
|
/// </summary> |
|
public class GButton : GComponent, IColorGear |
|
{ |
|
/// <summary> |
|
/// Play sound when button is clicked. |
|
/// </summary> |
|
public NAudioClip sound; |
|
|
|
/// <summary> |
|
/// Volume of the click sound. (0-1) |
|
/// </summary> |
|
public float soundVolumeScale; |
|
|
|
/// <summary> |
|
/// For radio or checkbox. if false, the button will not change selected status on click. Default is true. |
|
/// 如果为true,对于单选和多选按钮,当玩家点击时,按钮会自动切换状态。设置为false,则不会。默认为true。 |
|
/// </summary> |
|
public bool changeStateOnClick; |
|
|
|
/// <summary> |
|
/// Show a popup on click. |
|
/// 可以为按钮设置一个关联的组件,当按钮被点击时,此组件被自动弹出。 |
|
/// </summary> |
|
public GObject linkedPopup; |
|
|
|
protected GObject _titleObject; |
|
protected GObject _iconObject; |
|
protected Controller _relatedController; |
|
protected string _relatedPageId; |
|
|
|
ButtonMode _mode; |
|
bool _selected; |
|
string _title; |
|
string _icon; |
|
string _selectedTitle; |
|
string _selectedIcon; |
|
Controller _buttonController; |
|
int _downEffect; |
|
float _downEffectValue; |
|
bool _downScaled; |
|
|
|
bool _down; |
|
bool _over; |
|
|
|
EventListener _onChanged; |
|
|
|
public const string UP = "up"; |
|
public const string DOWN = "down"; |
|
public const string OVER = "over"; |
|
public const string SELECTED_OVER = "selectedOver"; |
|
public const string DISABLED = "disabled"; |
|
public const string SELECTED_DISABLED = "selectedDisabled"; |
|
|
|
public GButton() |
|
{ |
|
sound = UIConfig.buttonSound; |
|
soundVolumeScale = UIConfig.buttonSoundVolumeScale; |
|
changeStateOnClick = true; |
|
_downEffectValue = 0.8f; |
|
_title = string.Empty; |
|
} |
|
|
|
/// <summary> |
|
/// Dispatched when the button status was changed. |
|
/// 如果为单选或多选按钮,当按钮的选中状态发生改变时,此事件触发。 |
|
/// </summary> |
|
public EventListener onChanged |
|
{ |
|
get { return _onChanged ?? (_onChanged = new EventListener(this, "onChanged")); } |
|
} |
|
|
|
/// <summary> |
|
/// Icon of the button. |
|
/// </summary> |
|
override public string icon |
|
{ |
|
get |
|
{ |
|
return _icon; |
|
} |
|
set |
|
{ |
|
_icon = value; |
|
value = (_selected && _selectedIcon != null) ? _selectedIcon : _icon; |
|
if (_iconObject != null) |
|
_iconObject.icon = value; |
|
UpdateGear(7); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Title of the button |
|
/// </summary> |
|
public string title |
|
{ |
|
get |
|
{ |
|
return _title; |
|
} |
|
set |
|
{ |
|
_title = value; |
|
if (_titleObject != null) |
|
_titleObject.text = (_selected && _selectedTitle != null) ? _selectedTitle : _title; |
|
UpdateGear(6); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Same of the title. |
|
/// </summary> |
|
override public string text |
|
{ |
|
get { return this.title; } |
|
set { this.title = value; } |
|
} |
|
|
|
/// <summary> |
|
/// Icon value on selected status. |
|
/// </summary> |
|
public string selectedIcon |
|
{ |
|
get |
|
{ |
|
return _selectedIcon; |
|
} |
|
set |
|
{ |
|
_selectedIcon = value; |
|
value = (_selected && _selectedIcon != null) ? _selectedIcon : _icon; |
|
if (_iconObject != null) |
|
_iconObject.icon = value; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Title value on selected status. |
|
/// </summary> |
|
public string selectedTitle |
|
{ |
|
get |
|
{ |
|
return _selectedTitle; |
|
} |
|
set |
|
{ |
|
_selectedTitle = value; |
|
if (_titleObject != null) |
|
_titleObject.text = (_selected && _selectedTitle != null) ? _selectedTitle : _title; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Title color. |
|
/// </summary> |
|
public Color titleColor |
|
{ |
|
get |
|
{ |
|
GTextField tf = GetTextField(); |
|
if (tf != null) |
|
return tf.color; |
|
else |
|
return Color.black; |
|
} |
|
set |
|
{ |
|
GTextField tf = GetTextField(); |
|
if (tf != null) |
|
{ |
|
tf.color = value; |
|
UpdateGear(4); |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// |
|
/// </summary> |
|
public Color color |
|
{ |
|
get { return this.titleColor; } |
|
set { this.titleColor = value; } |
|
} |
|
|
|
/// <summary> |
|
/// |
|
/// </summary> |
|
public int titleFontSize |
|
{ |
|
get |
|
{ |
|
GTextField tf = GetTextField(); |
|
if (tf != null) |
|
return tf.textFormat.size; |
|
else |
|
return 0; |
|
} |
|
set |
|
{ |
|
GTextField tf = GetTextField(); |
|
if (tf != null) |
|
{ |
|
TextFormat format = tf.textFormat; |
|
format.size = value; |
|
tf.textFormat = format; |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// If the button is in selected status. |
|
/// </summary> |
|
public bool selected |
|
{ |
|
get |
|
{ |
|
return _selected; |
|
} |
|
|
|
set |
|
{ |
|
if (_mode == ButtonMode.Common) |
|
return; |
|
|
|
if (_selected != value) |
|
{ |
|
_selected = value; |
|
SetCurrentState(); |
|
if (_selectedTitle != null && _titleObject != null) |
|
_titleObject.text = _selected ? _selectedTitle : _title; |
|
if (_selectedIcon != null) |
|
{ |
|
string str = _selected ? _selectedIcon : _icon; |
|
if (_iconObject != null) |
|
_iconObject.icon = str; |
|
} |
|
if (_relatedController != null |
|
&& parent != null |
|
&& !parent._buildingDisplayList) |
|
{ |
|
if (_selected) |
|
{ |
|
_relatedController.selectedPageId = _relatedPageId; |
|
if (_relatedController.autoRadioGroupDepth) |
|
parent.AdjustRadioGroupDepth(this, _relatedController); |
|
} |
|
else if (_mode == ButtonMode.Check && _relatedController.selectedPageId == _relatedPageId) |
|
_relatedController.oppositePageId = _relatedPageId; |
|
} |
|
} |
|
|
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Button mode. |
|
/// </summary> |
|
/// <seealso cref="ButtonMode"/> |
|
public ButtonMode mode |
|
{ |
|
get |
|
{ |
|
return _mode; |
|
} |
|
set |
|
{ |
|
if (_mode != value) |
|
{ |
|
if (value == ButtonMode.Common) |
|
this.selected = false; |
|
_mode = value; |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// A controller is connected to this button, the activate page of this controller will change while the button status changed. |
|
/// 对应编辑器中的单选控制器。 |
|
/// </summary> |
|
public Controller relatedController |
|
{ |
|
get |
|
{ |
|
return _relatedController; |
|
} |
|
set |
|
{ |
|
if (value != _relatedController) |
|
{ |
|
_relatedController = value; |
|
_relatedPageId = null; |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// |
|
/// </summary> |
|
public string relatedPageId |
|
{ |
|
get |
|
{ |
|
return _relatedPageId; |
|
} |
|
set |
|
{ |
|
_relatedPageId = value; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Simulates a click on this button. |
|
/// 模拟点击这个按钮。 |
|
/// </summary> |
|
/// <param name="downEffect">If the down effect will simulate too.</param> |
|
public void FireClick(bool downEffect, bool clickCall = false) |
|
{ |
|
if (downEffect && _mode == ButtonMode.Common) |
|
{ |
|
SetState(OVER); |
|
|
|
Timers.inst.Add(0.1f, 1, (object param) => { SetState(DOWN); }); |
|
Timers.inst.Add(0.2f, 1, |
|
(object param) => |
|
{ |
|
SetState(UP); |
|
if (clickCall) |
|
{ |
|
onClick.Call(); |
|
} |
|
} |
|
); |
|
} |
|
else |
|
{ |
|
if (clickCall) |
|
{ |
|
onClick.Call(); |
|
} |
|
} |
|
__click(); |
|
} |
|
|
|
/// <summary> |
|
/// |
|
/// </summary> |
|
/// <returns></returns> |
|
public GTextField GetTextField() |
|
{ |
|
if (_titleObject is GTextField) |
|
return (GTextField)_titleObject; |
|
else if (_titleObject is GLabel) |
|
return ((GLabel)_titleObject).GetTextField(); |
|
else if (_titleObject is GButton) |
|
return ((GButton)_titleObject).GetTextField(); |
|
else |
|
return null; |
|
} |
|
|
|
protected void SetState(string val) |
|
{ |
|
if (_buttonController != null) |
|
_buttonController.selectedPage = val; |
|
|
|
if (_downEffect == 1) |
|
{ |
|
int cnt = this.numChildren; |
|
if (val == DOWN || val == SELECTED_OVER || val == SELECTED_DISABLED) |
|
{ |
|
Color color = new Color(_downEffectValue, _downEffectValue, _downEffectValue); |
|
for (int i = 0; i < cnt; i++) |
|
{ |
|
GObject obj = this.GetChildAt(i); |
|
if ((obj is IColorGear) && !(obj is GTextField)) |
|
((IColorGear)obj).color = color; |
|
} |
|
} |
|
else |
|
{ |
|
for (int i = 0; i < cnt; i++) |
|
{ |
|
GObject obj = this.GetChildAt(i); |
|
if ((obj is IColorGear) && !(obj is GTextField)) |
|
((IColorGear)obj).color = Color.white; |
|
} |
|
} |
|
} |
|
else if (_downEffect == 2) |
|
{ |
|
if (val == DOWN || val == SELECTED_OVER || val == SELECTED_DISABLED) |
|
{ |
|
if (!_downScaled) |
|
{ |
|
_downScaled = true; |
|
SetScale(this.scaleX * _downEffectValue, this.scaleY * _downEffectValue); |
|
} |
|
} |
|
else |
|
{ |
|
if (_downScaled) |
|
{ |
|
_downScaled = false; |
|
SetScale(this.scaleX / _downEffectValue, this.scaleY / _downEffectValue); |
|
} |
|
} |
|
} |
|
} |
|
|
|
protected void SetCurrentState() |
|
{ |
|
if (this.grayed && _buttonController != null && _buttonController.HasPage(DISABLED)) |
|
{ |
|
if (_selected) |
|
SetState(SELECTED_DISABLED); |
|
else |
|
SetState(DISABLED); |
|
} |
|
else |
|
{ |
|
if (_selected) |
|
SetState(_over ? SELECTED_OVER : DOWN); |
|
else |
|
SetState(_over ? OVER : UP); |
|
} |
|
} |
|
|
|
override public void HandleControllerChanged(Controller c) |
|
{ |
|
base.HandleControllerChanged(c); |
|
|
|
if (_relatedController == c) |
|
this.selected = _relatedPageId == c.selectedPageId; |
|
} |
|
|
|
override protected void HandleGrayedChanged() |
|
{ |
|
if (_buttonController != null && _buttonController.HasPage(DISABLED)) |
|
{ |
|
if (this.grayed) |
|
{ |
|
if (_selected) |
|
SetState(SELECTED_DISABLED); |
|
else |
|
SetState(DISABLED); |
|
} |
|
else |
|
{ |
|
if (_selected) |
|
SetState(DOWN); |
|
else |
|
SetState(UP); |
|
} |
|
} |
|
else |
|
base.HandleGrayedChanged(); |
|
} |
|
|
|
override protected void ConstructExtension(ByteBuffer buffer) |
|
{ |
|
buffer.Seek(0, 6); |
|
|
|
_mode = (ButtonMode)buffer.ReadByte(); |
|
string str = buffer.ReadS(); |
|
if (str != null) |
|
sound = UIPackage.GetItemAssetByURL(str) as NAudioClip; |
|
soundVolumeScale = buffer.ReadFloat(); |
|
_downEffect = buffer.ReadByte(); |
|
_downEffectValue = buffer.ReadFloat(); |
|
if (_downEffect == 2) |
|
SetPivot(0.5f, 0.5f, this.pivotAsAnchor); |
|
|
|
_buttonController = GetController("button"); |
|
_titleObject = GetChild("title"); |
|
_iconObject = GetChild("icon"); |
|
if (_titleObject != null) |
|
_title = _titleObject.text; |
|
if (_iconObject != null) |
|
_icon = _iconObject.icon; |
|
|
|
if (_mode == ButtonMode.Common) |
|
SetState(UP); |
|
|
|
displayObject.onRollOver.Add(__rollover); |
|
displayObject.onRollOut.Add(__rollout); |
|
displayObject.onTouchBegin.Add(__touchBegin); |
|
displayObject.onTouchEnd.Add(__touchEnd); |
|
displayObject.onRemovedFromStage.Add(__removedFromStage); |
|
displayObject.onClick.Add(__click); |
|
} |
|
|
|
override public void Setup_AfterAdd(ByteBuffer buffer, int beginPos) |
|
{ |
|
base.Setup_AfterAdd(buffer, beginPos); |
|
|
|
if (!buffer.Seek(beginPos, 6)) |
|
return; |
|
|
|
if ((ObjectType)buffer.ReadByte() != packageItem.objectType) |
|
return; |
|
|
|
string str; |
|
|
|
str = buffer.ReadS(); |
|
if (str != null) |
|
this.title = str; |
|
str = buffer.ReadS(); |
|
if (str != null) |
|
this.selectedTitle = str; |
|
str = buffer.ReadS(); |
|
if (str != null) |
|
this.icon = str; |
|
str = buffer.ReadS(); |
|
if (str != null) |
|
this.selectedIcon = str; |
|
if (buffer.ReadBool()) |
|
this.titleColor = buffer.ReadColor(); |
|
int iv = buffer.ReadInt(); |
|
if (iv != 0) |
|
this.titleFontSize = iv; |
|
iv = buffer.ReadShort(); |
|
if (iv >= 0) |
|
_relatedController = parent.GetControllerAt(iv); |
|
_relatedPageId = buffer.ReadS(); |
|
|
|
str = buffer.ReadS(); |
|
if (str != null) |
|
sound = UIPackage.GetItemAssetByURL(str) as NAudioClip; |
|
if (buffer.ReadBool()) |
|
soundVolumeScale = buffer.ReadFloat(); |
|
|
|
this.selected = buffer.ReadBool(); |
|
} |
|
|
|
private void __rollover() |
|
{ |
|
if (_buttonController == null || !_buttonController.HasPage(OVER)) |
|
return; |
|
|
|
_over = true; |
|
if (_down) |
|
return; |
|
|
|
if (this.grayed && _buttonController.HasPage(DISABLED)) |
|
return; |
|
|
|
SetState(_selected ? SELECTED_OVER : OVER); |
|
} |
|
|
|
private void __rollout() |
|
{ |
|
if (_buttonController == null || !_buttonController.HasPage(OVER)) |
|
return; |
|
|
|
_over = false; |
|
if (_down) |
|
return; |
|
|
|
if (this.grayed && _buttonController.HasPage(DISABLED)) |
|
return; |
|
|
|
SetState(_selected ? DOWN : UP); |
|
} |
|
|
|
private void __touchBegin(EventContext context) |
|
{ |
|
if (context.inputEvent.button != 0) |
|
return; |
|
|
|
_down = true; |
|
context.CaptureTouch(); |
|
|
|
if (_mode == ButtonMode.Common) |
|
{ |
|
if (this.grayed && _buttonController != null && _buttonController.HasPage(DISABLED)) |
|
SetState(SELECTED_DISABLED); |
|
else |
|
SetState(DOWN); |
|
} |
|
|
|
if (linkedPopup != null) |
|
{ |
|
if (linkedPopup is Window) |
|
((Window)linkedPopup).ToggleStatus(); |
|
else |
|
this.root.TogglePopup(linkedPopup, this); |
|
} |
|
} |
|
|
|
private void __touchEnd() |
|
{ |
|
if (_down) |
|
{ |
|
_down = false; |
|
if (_mode == ButtonMode.Common) |
|
{ |
|
if (this.grayed && _buttonController != null && _buttonController.HasPage(DISABLED)) |
|
SetState(DISABLED); |
|
else if (_over) |
|
SetState(OVER); |
|
else |
|
SetState(UP); |
|
} |
|
else |
|
{ |
|
if (!_over |
|
&& _buttonController != null |
|
&& (_buttonController.selectedPage == OVER || _buttonController.selectedPage == SELECTED_OVER)) |
|
{ |
|
SetCurrentState(); |
|
} |
|
} |
|
} |
|
} |
|
|
|
private void __removedFromStage() |
|
{ |
|
if (_over) |
|
__rollout(); |
|
} |
|
|
|
private void __click() |
|
{ |
|
if (sound != null && sound.nativeClip != null) |
|
Stage.inst.PlayOneShotSound(sound.nativeClip, soundVolumeScale); |
|
|
|
if (_mode == ButtonMode.Check) |
|
{ |
|
if (changeStateOnClick) |
|
{ |
|
this.selected = !_selected; |
|
DispatchEvent("onChanged", null); |
|
} |
|
} |
|
else if (_mode == ButtonMode.Radio) |
|
{ |
|
if (changeStateOnClick && !_selected) |
|
{ |
|
this.selected = true; |
|
DispatchEvent("onChanged", null); |
|
} |
|
} |
|
else |
|
{ |
|
if (_relatedController != null) |
|
_relatedController.selectedPageId = _relatedPageId; |
|
} |
|
} |
|
} |
|
}
|
|
|