123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- namespace FairyGUI
- {
- /// <summary>
- /// Window class.
- /// 窗口使用前首先要设置窗口中需要显示的内容,这通常是在编辑器里制作好的,可以直接使用Window.contentPane进行设置。
- /// 建议把设置contentPane等初始化操作放置到Window.onInit方法中。
- /// 另外,FairyGUI还提供了一套机制用于窗口动态创建。动态创建是指初始时仅指定窗口需要使用的资源,等窗口需要显示时才实际开始构建窗口的内容。
- /// 首先需要在窗口的构造函数中调用Window.addUISource。这个方法需要一个IUISource类型的参数,而IUISource是一个接口,
- /// 用户需要自行实现载入相关UI包的逻辑。当窗口第一次显示之前,IUISource的加载方法将会被调用,并等待载入完成后才返回执行Window.OnInit,然后窗口才会显示。
- ///
- /// 如果你需要窗口显示时播放动画效果,那么覆盖doShowAnimation编写你的动画代码,并且在动画结束后调用onShown。覆盖onShown编写其他需要在窗口显示时处理的业务逻辑。
- /// 如果你需要窗口隐藏时播放动画效果,那么覆盖doHideAnimation编写你的动画代码,并且在动画结束时调用Window.hideImmediately(注意不是直接调用onHide!)。覆盖onHide编写其他需要在窗口隐藏时处理的业务逻辑。
- /// </summary>
- public class Window : GComponent
- {
- /// <summary>
- ///
- /// </summary>
- public bool bringToFontOnClick;
- GComponent _frame;
- GComponent _contentPane;
- GObject _modalWaitPane;
- GObject _closeButton;
- GObject _dragArea;
- GObject _contentArea;
- bool _modal;
- List<IUISource> _uiSources;
- bool _inited;
- bool _loading;
- protected int _requestingCmd;
- #if FAIRYGUI_PUERTS
- public Action __onInit;
- public Action __onShown;
- public Action __onHide;
- public Action __doShowAnimation;
- public Action __doHideAnimation;
- #endif
- public Window()
- : base()
- {
- _uiSources = new List<IUISource>();
- this.tabStopChildren = true;
- bringToFontOnClick = UIConfig.bringWindowToFrontOnClick;
- displayObject.onAddedToStage.Add(__addedToStage);
- displayObject.onRemovedFromStage.Add(__removeFromStage);
- displayObject.onTouchBegin.AddCapture(__touchBegin);
- this.gameObjectName = "Window";
- SetHome(GRoot.inst);
- }
- /// <summary>
- /// Set a UISource to this window. It must call before the window is shown. When the window is first time to show,
- /// UISource.Load is called. Only after all UISource is loaded, the window will continue to init.
- /// 为窗口添加一个源。这个方法建议在构造函数调用。当窗口第一次显示前,UISource的Load方法将被调用,然后只有所有的UISource
- /// 都ready后,窗口才会继续初始化和显示。
- /// </summary>
- /// <param name="source"></param>
- public void AddUISource(IUISource source)
- {
- _uiSources.Add(source);
- }
- /// <summary>
- ///
- /// </summary>
- public GComponent contentPane
- {
- set
- {
- if (_contentPane != value)
- {
- if (_contentPane != null)
- RemoveChild(_contentPane);
- _contentPane = value;
- if (_contentPane != null)
- {
- this.gameObjectName = "Window - " + _contentPane.gameObjectName;
- _contentPane.gameObjectName = "ContentPane";
- AddChild(_contentPane);
- this.SetSize(_contentPane.width, _contentPane.height);
- _contentPane.AddRelation(this, RelationType.Size);
- _contentPane.fairyBatching = true;
- _frame = _contentPane.GetChild("frame") as GComponent;
- if (_frame != null)
- {
- this.closeButton = _frame.GetChild("closeButton");
- this.dragArea = _frame.GetChild("dragArea");
- this.contentArea = _frame.GetChild("contentArea");
- }
- }
- else
- {
- _frame = null;
- this.gameObjectName = "Window";
- }
- }
- }
- get
- {
- return _contentPane;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public GComponent frame
- {
- get { return _frame; }
- }
- /// <summary>
- ///
- /// </summary>
- public GObject closeButton
- {
- get { return _closeButton; }
- set
- {
- if (_closeButton != null)
- _closeButton.onClick.Remove(closeEventHandler);
- _closeButton = value;
- if (_closeButton != null)
- _closeButton.onClick.Add(closeEventHandler);
- }
- }
- /// <summary>
- ///
- /// </summary>
- public GObject dragArea
- {
- get { return _dragArea; }
- set
- {
- if (_dragArea != value)
- {
- if (_dragArea != null)
- {
- _dragArea.draggable = false;
- _dragArea.onDragStart.Remove(__dragStart);
- }
- _dragArea = value;
- if (_dragArea != null)
- {
- GGraph graph = _dragArea as GGraph;
- if (graph != null && graph.shape.isEmpty)
- graph.DrawRect(_dragArea.width, _dragArea.height, 0, Color.clear, Color.clear);
- _dragArea.draggable = true;
- _dragArea.onDragStart.Add(__dragStart);
- }
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- public GObject contentArea
- {
- get { return _contentArea; }
- set { _contentArea = value; }
- }
- /// <summary>
- ///
- /// </summary>
- public GObject modalWaitingPane
- {
- get { return _modalWaitPane; }
- }
- /// <summary>
- ///
- /// </summary>
- public void Show()
- {
- GRoot.inst.ShowWindow(this);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="r"></param>
- public void ShowOn(GRoot r)
- {
- r.ShowWindow(this);
- }
- /// <summary>
- ///
- /// </summary>
- public void Hide()
- {
- if (this.isShowing)
- DoHideAnimation();
- }
- /// <summary>
- /// Hide window immediately, no OnHide will be called.
- /// </summary>
- public void HideImmediately()
- {
- this.root.HideWindowImmediately(this);
- }
- /// <summary>
- /// Make the window be center of the screen.
- /// </summary>
- /// <param name="r"></param>
- /// <param name="restraint">Add relations to ensure keeping center on screen size changed.</param>
- public void CenterOn(GRoot r, bool restraint)
- {
- this.SetXY((int)((r.width - this.width) / 2), (int)((r.height - this.height) / 2));
- if (restraint)
- {
- this.AddRelation(r, RelationType.Center_Center);
- this.AddRelation(r, RelationType.Middle_Middle);
- }
- }
- /// <summary>
- /// Switch show and hide status.
- /// </summary>
- public void ToggleStatus()
- {
- if (isTop)
- Hide();
- else
- Show();
- }
- /// <summary>
- ///
- /// </summary>
- public bool isShowing
- {
- get { return parent != null; }
- }
- /// <summary>
- ///
- /// </summary>
- public bool isTop
- {
- get { return parent != null && parent.GetChildIndex(this) == parent.numChildren - 1; }
- }
- /// <summary>
- ///
- /// </summary>
- public bool modal
- {
- get { return _modal; }
- set { _modal = value; }
- }
- /// <summary>
- ///
- /// </summary>
- public void BringToFront()
- {
- this.root.BringToFront(this);
- }
- /// <summary>
- ///
- /// </summary>
- public void ShowModalWait()
- {
- ShowModalWait(0);
- }
- /// <summary>
- /// Display a modal waiting sign in the front.
- /// 显示一个等待标志在最前面。等待标志的资源可以通过UIConfig.windowModalWaiting。等待标志组件会设置为屏幕大小,请内部做好关联。
- /// 还可以设定一个requestingCmd作为等待的命令字,在CloseModalWait里传入相同的命令字ModalWait将结束,否则CloseModalWait无效。
- /// </summary>
- /// <param name="requestingCmd"></param>
- public void ShowModalWait(int requestingCmd)
- {
- if (requestingCmd != 0)
- _requestingCmd = requestingCmd;
- if (UIConfig.windowModalWaiting != null)
- {
- if (_modalWaitPane == null)
- {
- _modalWaitPane = UIPackage.CreateObjectFromURL(UIConfig.windowModalWaiting);
- _modalWaitPane.SetHome(this);
- }
- LayoutModalWaitPane();
- AddChild(_modalWaitPane);
- }
- }
- virtual protected void LayoutModalWaitPane()
- {
- if (_contentArea != null)
- {
- Vector2 pt = _frame.LocalToGlobal(Vector2.zero);
- pt = this.GlobalToLocal(pt);
- _modalWaitPane.SetXY((int)pt.x + _contentArea.x, (int)pt.y + _contentArea.y);
- _modalWaitPane.SetSize(_contentArea.width, _contentArea.height);
- }
- else
- _modalWaitPane.SetSize(this.width, this.height);
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool CloseModalWait()
- {
- return CloseModalWait(0);
- }
- /// <summary>
- /// Close modal waiting. If rquestingCmd is equal to the value you transfer in ShowModalWait, mowal wait will be closed.
- /// Otherwise, this function has no effect.
- /// 关闭模式等待。如果requestingCmd和ShowModalWait传入的不相同,则这个函数没有任何动作,立即返回。
- /// </summary>
- /// <param name="requestingCmd"></param>
- /// <returns></returns>
- public bool CloseModalWait(int requestingCmd)
- {
- if (requestingCmd != 0)
- {
- if (_requestingCmd != requestingCmd)
- return false;
- }
- _requestingCmd = 0;
- if (_modalWaitPane != null && _modalWaitPane.parent != null)
- RemoveChild(_modalWaitPane);
- return true;
- }
- /// <summary>
- ///
- /// </summary>
- public bool modalWaiting
- {
- get { return (_modalWaitPane != null) && _modalWaitPane.inContainer; }
- }
- /// <summary>
- ///
- /// </summary>
- public void Init()
- {
- if (_inited || _loading)
- return;
- if (_uiSources.Count > 0)
- {
- _loading = false;
- int cnt = _uiSources.Count;
- for (int i = 0; i < cnt; i++)
- {
- IUISource lib = _uiSources[i];
- if (!lib.loaded)
- {
- lib.Load(__uiLoadComplete);
- _loading = true;
- }
- }
- if (!_loading)
- _init();
- }
- else
- _init();
- }
- /// <summary>
- ///
- /// </summary>
- virtual protected void OnInit()
- {
- #if FAIRYGUI_TOLUA
- CallLua("OnInit");
- #endif
- #if FAIRYGUI_PUERTS
- if (__onInit != null)
- __onInit();
- #endif
- }
- /// <summary>
- ///
- /// </summary>
- virtual protected void OnShown()
- {
- #if FAIRYGUI_TOLUA
- CallLua("OnShown");
- #endif
- #if FAIRYGUI_PUERTS
- if (__onShown != null)
- __onShown();
- #endif
- }
- /// <summary>
- ///
- /// </summary>
- virtual protected void OnHide()
- {
- #if FAIRYGUI_TOLUA
- CallLua("OnHide");
- #endif
- #if FAIRYGUI_PUERTS
- if (__onHide != null)
- __onHide();
- #endif
- }
- /// <summary>
- ///
- /// </summary>
- virtual protected void DoShowAnimation()
- {
- #if FAIRYGUI_TOLUA
- if (!CallLua("DoShowAnimation"))
- OnShown();
- #elif FAIRYGUI_PUERTS
- if (__doShowAnimation != null)
- __doShowAnimation();
- else
- OnShown();
- #else
- OnShown();
- #endif
- }
- /// <summary>
- ///
- /// </summary>
- virtual protected void DoHideAnimation()
- {
- #if FAIRYGUI_TOLUA
- if (!CallLua("DoHideAnimation"))
- HideImmediately();
- #elif FAIRYGUI_PUERTS
- if (__doHideAnimation != null)
- __doHideAnimation();
- else
- HideImmediately();
- #else
- HideImmediately();
- #endif
- }
- void __uiLoadComplete()
- {
- int cnt = _uiSources.Count;
- for (int i = 0; i < cnt; i++)
- {
- IUISource lib = _uiSources[i];
- if (!lib.loaded)
- return;
- }
- _loading = false;
- _init();
- }
- void _init()
- {
- _inited = true;
- OnInit();
- if (this.isShowing)
- DoShowAnimation();
- }
- override public void Dispose()
- {
- if (_modalWaitPane != null && _modalWaitPane.parent == null)
- _modalWaitPane.Dispose();
- //正在加载资源的异步过程中发生意外关闭 应该取消正在加载的load
- if (_loading)
- {
- for (int i = 0; i < _uiSources.Count; ++i)
- {
- _uiSources[i].Cancel();
- }
- }
-
- #if FAIRYGUI_PUERTS
- __onInit = null;
- __onShown = null;
- __onHide = null;
- __doShowAnimation = null;
- __doHideAnimation = null;
- #endif
- base.Dispose();
- }
- virtual protected void closeEventHandler(EventContext context)
- {
- Hide();
- }
- void __addedToStage()
- {
- if (!_inited)
- Init();
- else
- DoShowAnimation();
- }
- void __removeFromStage()
- {
- CloseModalWait();
- OnHide();
- }
- private void __touchBegin(EventContext context)
- {
- if (this.isShowing && bringToFontOnClick)
- {
- BringToFront();
- }
- }
- private void __dragStart(EventContext context)
- {
- context.PreventDefault();
- this.StartDrag((int)context.data);
- }
- }
- }
|