diff --git a/README.md b/README.md
index 8303d6a..be38b72 100644
--- a/README.md
+++ b/README.md
@@ -2,80 +2,59 @@
A declarative library for building reactive user interface. Built over [UniMob](https://github.com/codewriter-packages/UniMob).
-## Core concepts
+## Getting Started
-Widgets are the building blocks of a app’s user interface, and each widget is an immutable declaration of part of the user interface.
-Widgets form a hierarchy based on composition.
+#### 1. Create view
-UniMob.UI comes with a suite of powerful basic widgets, of which the following are commonly used:
-
-> **[Row](./Runtime/Widgets/Row.cs), [Column](./Runtime/Widgets/Column.cs)**
-> These widgets let you create layouts in both the horizontal (Row) and vertical (Column) directions.
->
->**[ZStack](./Runtime/Widgets/ZStack.cs)**
->A Stack widget lets you place widgets on top of each other in paint order.
->
->**[Container](./Runtime/Widgets/Container.cs)**
->The Container widget lets you create a rectangular visual element that has background color and custom size.
-
-So what does code that uses UniMob.UI look like?
+View are regular MonoBehaviour that should be attached to gameObject.
```csharp
-using UniMob;
using UniMob.UI;
-using UniMob.UI.Widgets;
-using UnityEngine;
-public class CounterApp : UniMobUIApp
+public class CounterView : View
{
- [Atom] private int Counter { get; set; }
+ public UnityEngine.UI.Text counterText;
+ public UnityEngine.UI.Button incrementButton;
- protected override Widget Build(BuildContext context)
+ // initial setup
+ protected override void Awake()
{
- return new Container {
- BackgroundColor = Color.cyan,
- Child = new Column {
- Children = {
- new UniMobText(WidgetSize.Fixed(400, 50)) {
- Value = "Tap count: " + Counter,
- FontSize = 40,
- },
- new UniMobButton {
- OnClick = () => Counter += 1,
- Child = new UniMobText(WidgetSize.Fixed(400, 50)) {
- Value = "Increment",
- FontSize = 40,
- }
- }
- }
- }
- };
- }
-}
-```
+ base.Awake();
-More code samples are located in [UniMob.UI Samples](https://github.com/codewriter-packages/UniMob.UI-Samples) repository.
+ incrementButton.Click(() => State.Increment);
+ }
-## Custom widgets
+ // update view with data provided by State
+ // Render() is called automatically when data changes
+ // so view always be synchronized with state
+ protected override void Render()
+ {
+ counterText.text = "Conter: " + State.Counter;
+ }
+}
-Built-in widgets provide basic functionality, but modern games requires more complex and unique interfaces. You can create your own widgets to implement it.
+// describe data required for view
+public interface IConterState : IViewState {
+ Counter { get; set; }
+}
+```
-#### 1. Create widget
+#### 2. Create widget
-The widget contains the immutable data that is required for a user interface part.
+A widget is an immutable description of an interface element. May contain additional data if necessary.
```csharp
using UniMob.UI;
-public class RealCounterWidget : StatefulWidget
+public class CounterWidget : StatefulWidget
{
public int IncrementStep { get; set; }
- public override State CreateState() => new RealCounterState();
+ public override State CreateState() => new CounterState();
}
```
-#### 2. Create state
+#### 3. Create state
The State provides data for the View and optionally contains mutable state of this interface part.
@@ -83,45 +62,94 @@ The State provides data for the View and optionally contains mutable state of th
using UniMob;
using UniMob.UI;
-public class RealCounterState : ViewState
+public class CounterState : ViewState, ICounterState
{
- public override WidgetViewReference View => WidgetViewReference.Resource("Prefabs/Real Counter View");
-
+ // where to load the view from?
+ public override WidgetViewReference View {
+ get => WidgetViewReference.Resource("Prefabs/Counter View");
+ }
+
[Atom] public int Counter { get; private set; }
public void Increment()
{
+ // atom modification will automatically update UI
Counter += Widget.IncrementStep;
}
}
```
-#### 3. Create view
-
-View describes how data provided by State should be rendered on the screen.
+#### 3. Run app
```csharp
+using UniMob;
using UniMob.UI;
-public class RealCounterView : View
+public class CounterApp : UniMobUIApp
{
- public UnityEngine.UI.Text counterText;
- public UnityEngine.UI.Button incrementButton;
-
- protected override void Awake()
+ protected override Widget Build(BuildContext context)
{
- base.Awake();
-
- incrementButton.Click(() => State.Increment);
+ return new ConterWidget();
}
+}
+```
- protected override void Render()
- {
- counterText.text = State.Counter.ToString();
- }
+## Widget Composition
+
+Widgets are the building blocks of a app’s user interface.
+Widgets form a hierarchy based on composition.
+
+UniMob.UI comes with a suite of powerful basic widgets, of which the following are commonly used:
+
+> **[Row](./Runtime/Widgets/Row.cs), [Column](./Runtime/Widgets/Column.cs)**
+> These widgets let you create layouts in both the horizontal (Row) and vertical (Column) directions.
+>
+>**[ZStack](./Runtime/Widgets/ZStack.cs)**
+>A Stack widget lets you place widgets on top of each other in paint order.
+>
+>**[Container](./Runtime/Widgets/Container.cs)**
+>The Container widget lets you create a rectangular visual element that has background color and custom size.
+>
+>**[Scroll Grid Flow](./Runtime/Widgets/ScrollGridFlow.cs)**
+>The ScrollGridFlow widget lets you create a virtualized scrollable grid of elements.
+
+Composition of widgets allows you to build complex custom interfaces that will automatically update when needed.
+
+```csharp
+private Widget Build(BuildContext context) {
+ return new ScrollGridFlow {
+ CrossAxisAlignment = CrossAxisAlignment.Center,
+ MaxCrossAxisExtent = 750.0f,
+ Children = {
+ this.BuildDailyOffers(),
+
+ this.BuildGemsHeader(),
+ this.BuildGemsSlots(),
+
+ this.BuildGoldHeader(),
+ this.BuildGoldSlots(),
+ }
+ };
}
+
+private IEnumerable BuildDailyOffers() {
+ return this.DailyOffersModel
+ .GetAllOffers()
+ .Where(offer => offer.Visible) // subscribe to 'Visible' atom
+ .Select(offer => this.BuildDailyOffer(offer.Id);
+}
+
+private Widget BuildDailyOffer(string offerId) {
+ return new DailyOfferWidget(offerId) {
+ Key = Key.Of($"store_item_{offerId}")
+ };
+}
+
+// ...
```
+More code samples are located in [UniMob.UI Samples](https://github.com/codewriter-packages/UniMob.UI-Samples) repository.
+
## How to Install
Minimal Unity Version is 2019.3.