using System.Collections.Generic; using FairyGUI.Utils; using System; namespace FairyGUI { /// <summary> /// Controller class. /// 控制器类。控制器的创建和设计需通过编辑器完成,不建议使用代码创建。 /// 最常用的方法是通过selectedIndex获得或改变控制器的活动页面。如果要获得控制器页面改变的通知,使用onChanged事件。 /// </summary> public class Controller : EventDispatcher { /// <summary> /// Name of the controller /// 控制器名称。 /// </summary> public string name; internal GComponent parent; internal bool autoRadioGroupDepth; internal bool changing; int _selectedIndex; int _previousIndex; List<string> _pageIds; List<string> _pageNames; List<ControllerAction> _actions; EventListener _onChanged; static uint _nextPageId; public Controller() { _pageIds = new List<string>(); _pageNames = new List<string>(); _selectedIndex = -1; _previousIndex = -1; } public void Dispose() { RemoveEventListeners(); } /// <summary> /// When controller page changed. /// 当控制器活动页面改变时,此事件被触发。 /// </summary> public EventListener onChanged { get { return _onChanged ?? (_onChanged = new EventListener(this, "onChanged")); } } /// <summary> /// Current page index. /// 获得或设置当前活动页面索引。 /// </summary> public int selectedIndex { get { return _selectedIndex; } set { if (_selectedIndex != value) { if (value > _pageIds.Count - 1) throw new IndexOutOfRangeException("" + value); changing = true; _previousIndex = _selectedIndex; _selectedIndex = value; parent.ApplyController(this); DispatchEvent("onChanged", null); changing = false; } } } /// <summary> /// Set current page index, no onChanged event. /// 通过索引设置当前活动页面,和selectedIndex的区别在于,这个方法不会触发onChanged事件。 /// </summary> /// <param name="value">Page index</param> public void SetSelectedIndex(int value) { if (_selectedIndex != value) { if (value > _pageIds.Count - 1) throw new IndexOutOfRangeException("" + value); changing = true; _previousIndex = _selectedIndex; _selectedIndex = value; parent.ApplyController(this); changing = false; } } /// <summary> /// Set current page by name, no onChanged event. /// 通过页面名称设置当前活动页面,和selectedPage的区别在于,这个方法不会触发onChanged事件。 /// </summary> /// <param name="value">Page name</param> public void SetSelectedPage(string value) { int i = _pageNames.IndexOf(value); if (i == -1) i = 0; this.SetSelectedIndex(i); } /// <summary> /// Current page name. /// 获得当前活动页面名称 /// </summary> public string selectedPage { get { if (_selectedIndex == -1) return null; else return _pageNames[_selectedIndex]; } set { int i = _pageNames.IndexOf(value); if (i == -1) i = 0; this.selectedIndex = i; } } [Obsolete("Use previousIndex")] public int previsousIndex { get { return _previousIndex; } } /// <summary> /// Previouse page index. /// 获得上次活动页面索引 /// </summary> public int previousIndex { get { return _previousIndex; } } /// <summary> /// Previous page name. /// 获得上次活动页面名称。 /// </summary> public string previousPage { get { if (_previousIndex == -1) return null; else return _pageNames[_previousIndex]; } } /// <summary> /// Page count of this controller. /// 获得页面数量。 /// </summary> public int pageCount { get { return _pageIds.Count; } } /// <summary> /// Get page name by an index. /// 通过页面索引获得页面名称。 /// </summary> /// <param name="index">Page index</param> /// <returns>Page Name</returns> public string GetPageName(int index) { return _pageNames[index]; } /// <summary> /// Get page id by an index. /// 通过页面索引获得页面id。 /// </summary> /// <param name="index">Page index</param> /// <returns>Page Id</returns> public string GetPageId(int index) { return _pageIds[index]; } /// <summary> /// Get page id by name /// </summary> /// <param name="aName"></param> /// <returns></returns> public string GetPageIdByName(string aName) { int i = _pageNames.IndexOf(aName); if (i != -1) return _pageIds[i]; else return null; } /// <summary> /// Add a new page to this controller. /// </summary> /// <param name="name">Page name</param> public void AddPage(string name) { if (name == null) name = string.Empty; AddPageAt(name, _pageIds.Count); } /// <summary> /// Add a new page to this controller at a certain index. /// </summary> /// <param name="name">Page name</param> /// <param name="index">Insert position</param> public void AddPageAt(string name, int index) { string nid = "_" + (_nextPageId++); if (index == _pageIds.Count) { _pageIds.Add(nid); _pageNames.Add(name); } else { _pageIds.Insert(index, nid); _pageNames.Insert(index, name); } } /// <summary> /// Remove a page. /// </summary> /// <param name="name">Page name</param> public void RemovePage(string name) { int i = _pageNames.IndexOf(name); if (i != -1) { _pageIds.RemoveAt(i); _pageNames.RemoveAt(i); if (_selectedIndex >= _pageIds.Count) this.selectedIndex = _selectedIndex - 1; else parent.ApplyController(this); } } /// <summary> /// Removes a page at a certain index. /// </summary> /// <param name="index"></param> public void RemovePageAt(int index) { _pageIds.RemoveAt(index); _pageNames.RemoveAt(index); if (_selectedIndex >= _pageIds.Count) this.selectedIndex = _selectedIndex - 1; else parent.ApplyController(this); } /// <summary> /// Remove all pages. /// </summary> public void ClearPages() { _pageIds.Clear(); _pageNames.Clear(); if (_selectedIndex != -1) this.selectedIndex = -1; else parent.ApplyController(this); } /// <summary> /// Check if the controller has a page. /// </summary> /// <param name="aName">Page name.</param> /// <returns></returns> public bool HasPage(string aName) { return _pageNames.IndexOf(aName) != -1; } internal int GetPageIndexById(string aId) { return _pageIds.IndexOf(aId); } internal string GetPageNameById(string aId) { int i = _pageIds.IndexOf(aId); if (i != -1) return _pageNames[i]; else return null; } internal string selectedPageId { get { if (_selectedIndex == -1) return string.Empty; else return _pageIds[_selectedIndex]; } set { int i = _pageIds.IndexOf(value); if (i != -1) this.selectedIndex = i; } } internal string oppositePageId { set { int i = _pageIds.IndexOf(value); if (i > 0) this.selectedIndex = 0; else if (_pageIds.Count > 1) this.selectedIndex = 1; } } internal string previousPageId { get { if (_previousIndex == -1) return null; else return _pageIds[_previousIndex]; } } public void RunActions() { if (_actions != null) { int cnt = _actions.Count; for (int i = 0; i < cnt; i++) { _actions[i].Run(this, previousPageId, selectedPageId); } } } public void Setup(ByteBuffer buffer) { int beginPos = buffer.position; buffer.Seek(beginPos, 0); name = buffer.ReadS(); autoRadioGroupDepth = buffer.ReadBool(); buffer.Seek(beginPos, 1); int cnt = buffer.ReadShort(); _pageIds.Capacity = cnt; _pageNames.Capacity = cnt; for (int i = 0; i < cnt; i++) { _pageIds.Add(buffer.ReadS()); _pageNames.Add(buffer.ReadS()); } int homePageIndex = 0; if (buffer.version >= 2) { int homePageType = buffer.ReadByte(); switch (homePageType) { case 1: homePageIndex = buffer.ReadShort(); break; case 2: homePageIndex = _pageNames.IndexOf(UIPackage.branch); if (homePageIndex == -1) homePageIndex = 0; break; case 3: homePageIndex = _pageNames.IndexOf(UIPackage.GetVar(buffer.ReadS())); if (homePageIndex == -1) homePageIndex = 0; break; } } buffer.Seek(beginPos, 2); cnt = buffer.ReadShort(); if (cnt > 0) { if (_actions == null) _actions = new List<ControllerAction>(cnt); for (int i = 0; i < cnt; i++) { int nextPos = buffer.ReadUshort(); nextPos += buffer.position; ControllerAction action = ControllerAction.CreateAction((ControllerAction.ActionType)buffer.ReadByte()); action.Setup(buffer); _actions.Add(action); buffer.position = nextPos; } } if (parent != null && _pageIds.Count > 0) _selectedIndex = homePageIndex; else _selectedIndex = -1; } } }