v0.1 UIKit Trial
v 0.1.1 Making a UITodoList of UGUI with QFramework Framework
Design sketch
- Start operation
- Open UIPanel and pass in values
using System.Collections.Generic; using UnityEngine; namespace QFramework.ToDoList { public class UIApp : MonoBehaviour { // Start is called before the first frame update public ToDoList model = new ToDoList(); void Start() { QF.Res.ResMgr.Init(); UIMgr.SetResolution(540, 1136, 0); //Call in the new Panel and pass in the model UIMgr.OpenPanel<Panel>(new PanelData() { model = model }); } } public class ToDoList { public List<TodoItem> mTodoItems = new List<TodoItem>() { new TodoItem(){Completed=false, Content="Go grocery shopping"} , new TodoItem(){Completed=false, Content="Business"} }; } public class TodoItem { public bool Completed; public string Content; } }
- Then look at the code for the Panel generated by QF.
uiData in the OnInit method is passed in through UIMgr.OpenPanel<Panel> and then output to Text
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace QFramework.ToDoList { using System.Text; using UnityEngine.UI; public class PanelData : QFramework.UIPanelData { //Add model to assign values outside public ToDoList model; } public partial class Panel : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { throw new System.NotImplementedException(); } protected override void OnInit(QFramework.IUIData uiData) { //Here is the value passed in through UIMgr. OpenPanel < Panel > and then output to Text. mData = uiData as PanelData ?? new PanelData(); // please add init code here var contentText = new StringBuilder(); mData.model.mTodoItems.ForEach( item => { contentText.AppendLine(item.Content); } ); Text.text = contentText.ToString(); } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } } }
- The effect is as follows.
- User Data Display of UI Element
Q Framework is too powerful. It can only be said that Liangda is very strong.
Bind can choose Element
After generating the current UITodolist, you can access Content and Componented via UITdom
- That's what happened.
- Modified code UIApp remains unchanged
using System.Collections.Generic; using UnityEngine; namespace QFramework.ToDoList { public class UIApp : MonoBehaviour { // Start is called before the first frame update public ToDoList model = new ToDoList(); void Start() { QF.Res.ResMgr.Init(); UIMgr.SetResolution(540, 1136, 0); //Call in the new Panel and pass in the model UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = model }); } } public class ToDoList { public List<TodoItem> mTodoItems = new List<TodoItem>() { new TodoItem(){Completed=false, Content="Go grocery shopping"} , new TodoItem(){Completed=false, Content="Business"} }; } public class TodoItem { public bool Completed; public string Content; } }
namespace QFramework.ToDoList { using QF.Extensions; public class UITodoListData : QFramework.UIPanelData { public ToDoList model; } public partial class UITodoList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { throw new System.NotImplementedException(); } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UITodoListData ?? new UITodoListData(); // please add init code here var contentText = new System.Text.StringBuilder(); mData.model.mTodoItems.ForEach( item => { UITodoItem.Instantiate() . Parent(Content) .LocalIdentity() //Add a method .ApplySelfTo( (self) =>{self.Init(item ); } ) .Show() ; } ); } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } } }
- The code generated by UITodoItem is like this
using UnityEngine; using UnityEngine.UI; using QFramework; namespace QFramework.ToDoList { public partial class UITodoItem { [SerializeField] public UnityEngine.UI.Text Content; [SerializeField] public UnityEngine.UI.Toggle Completed; public void Clear() { Content = null; Completed = null; } public override string ComponentName { get { return "UITodoItem";} } } }
namespace QFramework.ToDoList { public partial class UITodoItem : UIElement { //TodoItem item; private void Awake() { } public void Init(TodoItem item) { //this.item = item; this.Content.text = item.Content; this.Completed.isOn = item.Completed; } protected override void OnBeforeDestroy() { } } }
- UI message mechanism of QFramework
Send and receive messages via event mechanism
The code is as follows: TodoItem toggle sends a message after the state changes
namespace QFramework.ToDoList { public partial class UITodoItem : UIElement { TodoItem mItem; private void Awake() { } public void Init(TodoItem item) { this.mItem = item; this.Content.text = mItem.Content; this.Completed.isOn = mItem.Completed; this.Completed.onValueChanged.AddListener((b) => { mItem.Completed = b; SendEvent(UITodoListEvent.OnDataChanged); }); } protected override void OnBeforeDestroy() { } } }
- UITODOList Registration Message Number Registration Message Number
namespace QFramework.ToDoList { using System.Linq; using QF.Extensions; public class UITodoListData : QFramework.UIPanelData { public ToDoList model; } //Message number to be registered public enum UITodoListEvent { Start = QMgrID.UI, OnDataChanged, End, } public partial class UITodoList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { if (eventId == (int)UITodoListEvent.OnDataChanged) { OnDataChanged(); } } public void OnDataChanged() { Content.DestroyAllChild(); var contentText = new System.Text.StringBuilder(); mData.model.mTodoItems.Where((item) => !item.Completed) .ForEach( item => { UITodoItem.Instantiate() .Parent(Content) .LocalIdentity() //Add a method .ApplySelfTo((self) => { self.Init(item); }) .Show(); } ); } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UITodoListData ?? new UITodoListData(); // please add init code here OnDataChanged(); //Registration message RegisterEvent(UITodoListEvent.OnDataChanged); } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } } }
- Construction of UIAPP for TodoList
using System.Collections.Generic; using UnityEngine; namespace QFramework.ToDoList { public class UIApp : MonoBehaviour { // Start is called before the first frame update public ToDoList model = new ToDoList(); void Start() { QF.Res.ResMgr.Init(); UIMgr.SetResolution(540, 1136, 0); //Call in the new Panel and pass in the model UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = model }); } } public class ToDoList { public List<TodoItem> mTodoItems = new List<TodoItem>() { new TodoItem(){Completed=false, Content="Go grocery shopping"} , new TodoItem(){Completed=false, Content="Business"} }; } public class TodoItem { public bool Completed; public string Content; } }
- The effect is this.
- Add to-do TodoListItem through InputField
Add InputField Apply Prefabricated Weight Regeneration Code at this time, please rest assured that the code written before will not be lost oh
The UITodoItem code remains unchanged
namespace QFramework.ToDoList { public partial class UITodoItem : UIElement { TodoItem mItem; private void Awake() { } public void Init(TodoItem item) { this.mItem = item; this.Content.text = mItem.Content; this.Completed.isOn = mItem.Completed; this.Completed.onValueChanged.AddListener((b) => { mItem.Completed = b; SendEvent(UITodoListEvent.OnDataChanged); }); } protected override void OnBeforeDestroy() { } } }
- Add Inputfield Event Registration Message
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace QFramework.ToDoList { using System.Linq; using QF.Extensions; public class UITodoListData : QFramework.UIPanelData { public ToDoList model; } //Message number to be registered public enum UITodoListEvent { Start = QMgrID.UI, OnDataChanged, End, } public partial class UITodoList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { if (eventId == (int)UITodoListEvent.OnDataChanged) { OnDataChanged(); } } public void OnDataChanged() { Content.DestroyAllChild(); var contentText = new System.Text.StringBuilder(); mData.model.mTodoItems.Where((item) => !item.Completed) .ForEach( item => { UITodoItem.Instantiate() .Parent(Content) .LocalIdentity() //Add a method .ApplySelfTo((self) => { self.Init(item); }) .Show(); } ); } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UITodoListData ?? new UITodoListData(); // please add init code here OnDataChanged(); //Registration message RegisterEvent(UITodoListEvent.OnDataChanged); InputField.onEndEdit.AddListener(Content => { mData.model.mTodoItems.Add(new TodoItem() { Completed = false, Content = Content }); //// Call update method or send message mechanism to update message // OnDataChanged(); SendEvent(UITodoListEvent.OnDataChanged); InputField.text=string.Empty; }); } //// I've tried calling this method to work, but viewing the API is not recommended. // protected override void RegisterUIEvent() // { // QF.Log.I("Registration Event"); // InputField.onEndEdit.AddListener(Content => // { // mData.model.mTodoItems.Add(new TodoItem() { Completed = false, Content = Content }); // //// Call update method or send message mechanism to update message // // OnDataChanged(); // SendEvent(UITodoListEvent.OnDataChanged); // InputField.text=string.Empty; // }); // } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } } }
- APPUI has not changed
using System.Collections.Generic; using UnityEngine; namespace QFramework.ToDoList { public class UIApp : MonoBehaviour { // Start is called before the first frame update public ToDoList model = new ToDoList(); void Start() { QF.Res.ResMgr.Init(); //UIMgr.SetResolution(540, 1136, 0); //Call in the new Panel and pass in the model UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = model }); } } public class ToDoList { public List<TodoItem> mTodoItems = new List<TodoItem>() { new TodoItem(){Completed=false, Content="Go grocery shopping"} , new TodoItem(){Completed=false, Content="Business"}, new TodoItem(){Completed=true, Content="At work"}, }; } public class TodoItem { public bool Completed; public string Content; } }
Then we make a completed list.
I won't add a namespace for this class because I created it on two projects.
Modify the prefabricated TODOList
Change the Item of the uncompleted list to this
Other things haven't changed much.
Then the UIComponentedList is stored as a prefabricated tag to regenerate the code.
Then we modify the code in Todolist to add a button event to jump open and pass in the parameters of the model
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; using TestUIManager; using QFramework.ToDoList; using System.Linq; using QF.Extensions; using QFramework; public class UITodoListData : QFramework.UIPanelData { public ToDoList model = new ToDoList(); } //Message number to be registered public enum UITodoListEvent { Start = QMgrID.UI, OnDataChanged, End, } public partial class UITodoList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { if (eventId == (int)UITodoListEvent.OnDataChanged) { OnDataChanged(); } } public void OnDataChanged() { Content.DestroyAllChild(); var contentText = new System.Text.StringBuilder(); mData.model.mTodoItems.Where((item) => !item.Completed) .ForEach( item => { UITodoItem.Instantiate() .Parent(Content) .LocalIdentity() //Add a method .ApplySelfTo((self) => { self.Init(item); }) .Show(); } ); } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UITodoListData ?? new UITodoListData(); // please add init code here OnDataChanged(); //Registration message RegisterEvent(UITodoListEvent.OnDataChanged); InputField.onEndEdit.AddListener(Content => { mData.model.mTodoItems.Add(new TodoItem() { Completed = false, Content = Content }); //// Call update method or send message mechanism to update message // OnDataChanged(); SendEvent(UITodoListEvent.OnDataChanged); InputField.text = string.Empty; }); Button.onClick.AddListener(() => { CloseSelf(); UIMgr.OpenPanel<UICompletedList>(new UICompletedListData() { model = mData.model }); }); } //// I've tried calling this method to work, but viewing the API is not recommended. // protected override void RegisterUIEvent() // { // QF.Log.I("Registration Event"); // InputField.onEndEdit.AddListener(Content => // { // mData.model.mTodoItems.Add(new TodoItem() { Completed = false, Content = Content }); // //// Call update method or send message mechanism to update message // // OnDataChanged(); // SendEvent(UITodoListEvent.OnDataChanged); // InputField.text=string.Empty; // }); // } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } }
Modify the code UICompletedList
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using QF.Extensions; using QFramework; using QFramework.ToDoList; using UnityEngine; using UnityEngine.UI; public class UICompletedListData : QFramework.UIPanelData { public ToDoList model = new ToDoList(); } public enum UIconmentListEvent { Start = UITodoListEvent.End, OnDataChanged, End, } public partial class UICompletedList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { if (eventId == (int)UIconmentListEvent.OnDataChanged) { OnDataChanged(); } } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UICompletedListData ?? new UICompletedListData(); // please add init code here OnDataChanged(); RegisterEvent(UIconmentListEvent.OnDataChanged); BtnBack.onClick.AddListener(() => { CloseSelf(); UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = mData.model }); }); } public void OnDataChanged() { Content.DestroyAllChild(); var contentText = new System.Text.StringBuilder(); mData.model.mTodoItems.Where((item) => item.Completed) .ForEach( item => { UICompletedTodoItem.Instantiate() .Parent(Content) .LocalIdentity() //Add a method .ApplySelfTo((self) => { self.Init(item); }) .Show(); } ); } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } }
Then modify the code of UICompletedTodoItem
public partial class UICompletedTodoItem : UIElement { public TodoItem mItem; private void Awake() { } public void Init(TodoItem item) { this.mItem = item; this.Content.text = this.mItem.Content; this.Completed.isOn = mItem.Completed; this.Completed.onValueChanged.AddListener((b) => { mItem.Completed = b; SendEvent(UIconmentListEvent.OnDataChanged); }); } protected override void OnBeforeDestroy() { } }
- That's the end result.
- Serialized save list
To attach the code, you just need to modify the UIApp code.
public class UIApp : MonoBehaviour { ToDoList mModel; void Start() { mModel = ToDoList.Load(); QF.Res.ResMgr.Init(); //UIMgr.SetResolution(540, 1136, 0); //Call in the new Panel and pass in the model UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = mModel }); } private void OnApplicationQuit() { mModel.Save(); } } public class ToDoList { public List<TodoItem> mTodoItems = new List<TodoItem>(); public static ToDoList Load() { var jsonCentent = PlayerPrefs.GetString("TodoListData", string.Empty); if (jsonCentent.IsNullOrEmpty()) { return new ToDoList(); } else { return jsonCentent.FromJson<ToDoList>(); } } public void Save() { PlayerPrefs.SetString("TodoListData", this.ToJson()); } } public class TodoItem { public bool Completed; public string Content; }
The effect is the function of record preservation.
Adding Modification + Refactoring Code
Summary code refactoring
UIAPP code
public class UIApp : MonoBehaviour { ToDoList mModel; void Start() { mModel = ToDoList.Load(); QF.Res.ResMgr.Init(); //UIMgr.SetResolution(540, 1136, 0); //Call in the new Panel and pass in the model UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = mModel }); } private void OnApplicationQuit() { mModel.Save(); } } public class ToDoList { public List<TodoItem> mTodoItems = new List<TodoItem>(); public static ToDoList Load() { var jsonCentent = PlayerPrefs.GetString("TodoListData", string.Empty); if (jsonCentent.IsNullOrEmpty()) { return new ToDoList(); } else { return jsonCentent.FromJson<ToDoList>(); } } public void Save() { PlayerPrefs.SetString("TodoListData", this.ToJson()); } } public class TodoItem { public bool Completed; public string Content; }
UITodoList code
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; using TestUIManager; using QFramework.ToDoList; using System.Linq; using QF.Extensions; using QFramework; public class UITodoListData : QFramework.UIPanelData { public ToDoList model = new ToDoList(); } //Message number to be registered public enum UITodoListEvent { Start = QMgrID.UI, OnDataChanged, OnTodoItemSelect, End, } public class OnTodoItemSelectedMsg : QMsg { public TodoItem ItemData; public OnTodoItemSelectedMsg(TodoItem itemData) : base((int)UITodoListEvent.OnTodoItemSelect) { ItemData = itemData; } } public partial class UITodoList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { if (eventId == (int)UITodoListEvent.OnDataChanged) { OnDataChanged(); } else if (eventId == (int)UITodoListEvent.OnTodoItemSelect) { var mMsg = msg as OnTodoItemSelectedMsg; //Debug.Log(mMsg.ItemData.Content); UIInputContent.ModifyState(mMsg.ItemData); } } public void OnDataChanged() { Content.OnDataChange(UITodoItem, mData.model); } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UITodoListData ?? new UITodoListData(); // please add init code here OnDataChanged(); RegisterEvent(UITodoListEvent.OnDataChanged); RegisterEvent(UITodoListEvent.OnTodoItemSelect); Button.onClick.AddListener(() => { CloseSelf(); UIMgr.OpenPanel<UICompletedList>(new UICompletedListData() { model = mData.model }); }); UIInputContent.Init(mData.model); } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } }
UI code completed by UICompletedList
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using QF.Extensions; using QFramework; using QFramework.ToDoList; using UnityEngine; using UnityEngine.UI; public class UICompletedListData : QFramework.UIPanelData { public ToDoList model = new ToDoList(); } public enum UIconmentListEvent { Start = UITodoListEvent.End, OnDataChanged, End, } public partial class UICompletedList : QFramework.UIPanel { protected override void ProcessMsg(int eventId, QFramework.QMsg msg) { if (eventId == (int)UIconmentListEvent.OnDataChanged) { OnDataChanged(); } } protected override void OnInit(QFramework.IUIData uiData) { mData = uiData as UICompletedListData ?? new UICompletedListData(); // please add init code here OnDataChanged(); RegisterEvent(UIconmentListEvent.OnDataChanged); BtnBack.onClick.AddListener(() => { CloseSelf(); UIMgr.OpenPanel<UITodoList>(new UITodoListData() { model = mData.model }); }); } public void OnDataChanged() { Content.DestroyAllChild(); var contentText = new System.Text.StringBuilder(); mData.model.mTodoItems.Where((item) => item.Completed) .ForEach( item => { UICompletedTodoItem.Instantiate() .Parent(Content) .LocalIdentity() //Add a method .ApplySelfTo((self) => { self.Init(item); }) .Show(); } ); } protected override void OnOpen(QFramework.IUIData uiData) { } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } }
UIInputContent code
//Two states are added, one is added and the other is modified. public enum UIInputContentState { Create, Modify, } public partial class UIInputContent : UIElement { private UIInputContentState mState; public UIInputContentState State { get { return mState; } private set { if (mState != value) { mState = value; OnStateChanged.InvokeGracefully(); } } } public TodoItem mSelectedItemModel; public Action OnStateChanged; private ToDoList mTodoListModel; private void Awake() { InputField.onEndEdit.AddListener(Content => { if (State == UIInputContentState.Create) { if (Input.GetKey(KeyCode.Return)) { mTodoListModel.mTodoItems.Add(new TodoItem() { Completed = false, Content = Content }); SendEvent(UITodoListEvent.OnDataChanged); } InputField.text = string.Empty; } }); BtnCancal.onClick.AddListener(() => { CreateState(); }); BtnUpdate.onClick.AddListener(() => { mSelectedItemModel.Content = InputField.text; SendEvent(UITodoListEvent.OnDataChanged); CreateState(); }); InputField.onValueChanged.AddListener((content) => { if (State == UIInputContentState.Modify) { if (BtnUpdate.interactable && content == mSelectedItemModel.Content) { BtnUpdate.interactable = false; } else if (!BtnUpdate.interactable && content != mSelectedItemModel.Content) { BtnUpdate.interactable = true; } } }); } public void CreateState() { BtnUpdate.Hide(); BtnCancal.Hide(); State = UIInputContentState.Create; InputField.text = string.Empty; } public void Init(ToDoList todoListModel) { mTodoListModel = todoListModel; } public void ModifyState(TodoItem selectItem) { mSelectedItemModel = selectItem; State = UIInputContentState.Modify; BtnUpdate.Show(); BtnUpdate.interactable = false; BtnCancal.Show(); InputField.text = mSelectedItemModel.Content; } protected override void OnBeforeDestroy() { } }
UICompleteTODOItem code
public partial class UICompletedTodoItem : UIElement { public TodoItem mItem; private void Awake() { } public void Init(TodoItem item) { this.mItem = item; this.Content.text = this.mItem.Content; this.Completed.isOn = mItem.Completed; this.Completed.onValueChanged.AddListener((b) => { mItem.Completed = b; SendEvent(UIconmentListEvent.OnDataChanged); }); } protected override void OnBeforeDestroy() { } }
UIListCtrl code
public partial class UIListCtrl : UIElement { private void Awake() { } protected override void OnBeforeDestroy() { } public void OnDataChange(UITodoItem itemPrefab, ToDoList model) { this.DestroyAllChild(); model.mTodoItems.Where((item) => !item.Completed) .ForEach( item => { itemPrefab.Instantiate() .Parent(this) .LocalIdentity() //Add a method .ApplySelfTo((self) => { self.Init(item); }) .Show(); } ); } }
UITODOItem code
public partial class UITodoItem : UIElement { TodoItem mItem; private void Awake() { } public void Init(TodoItem item) { this.mItem = item; this.Content.text = mItem.Content; this.Completed.isOn = mItem.Completed; this.Completed.onValueChanged.AddListener((b) => { mItem.Completed = b; SendEvent(UITodoListEvent.OnDataChanged); }); Button.onClick.AddListener(() => { Debug.Log("Selective UI"); SendMsg(new OnTodoItemSelectedMsg(mItem)); }); } protected override void OnBeforeDestroy() { } }
Continuous updates...