Exemplo n.º 1
0
        public static IDisposable Bind <T>(
            IReactiveProperty <T> propertyA,
            IReactiveProperty <T> propertyB,
            BindingTypes bindingTypes = BindingTypes.Default)
        {
            var propertyBBinding = propertyB
                                   .DistinctUntilChanged()
                                   .Subscribe(x => propertyA.Value = x);

            if (bindingTypes == BindingTypes.OneWay)
            {
                return(propertyBBinding);
            }

            var propertyABinding = propertyA
                                   .DistinctUntilChanged()
                                   .Subscribe(x => propertyB.Value = x);

            return(new CompositeDisposable(propertyABinding, propertyBBinding));
        }
Exemplo n.º 2
0
        // Start is called before the first frame update
        protected override void Start()
        {
            m_CategoryPagerView.items.Value = m_Categories;

            var categoryObservable = category as IObservable <CategoryEnum>;
            var isDragAndDropping  = new BoolReactiveProperty(false);

            // If we have at least one category, start with it
            if (m_Categories.Length > 0)
            {
                categoryObservable = categoryObservable.StartWith(m_Categories[0].category);
            }

            // Change the catalogue pager whenever the category button is pressed or the color changes.
            Observable.Merge(
                categoryObservable
                .DistinctUntilChanged()
                .AsUnitObservable(),
                flipped.DistinctUntilChanged()
                .AsUnitObservable(),
                color.DistinctUntilChanged()
                .AsUnitObservable()
                )
            .Subscribe(ignored =>
            {
                var catalogueItems = m_Asset[category.Value, color.Value]
                                     .Select(item => new CatalogueItem()
                {
                    flipped = flipped.Value,
                    asset   = item
                })
                                     .ToArray();

                m_CataloguePagerView.items.Value = catalogueItems;

                if (m_Brush.Value != null)
                {
                    var index = Array.FindIndex(catalogueItems,
                                                item => item.asset.name == m_Brush.Value.catalogueItem.asset.name);

                    if (index >= 0)
                    {
                        // If the color or flip state changed, it now changed here
                        var brush = new BrushItem()
                        {
                            catalogueItem = catalogueItems[index]
                        };
                        m_Brush.SetValueAndForceNotify(brush);
                    }
                }

                var hit = new EventHitBuilder()
                          .SetEventCategory("profile creator")
                          .SetEventAction("brush")
                          .SetEventLabel($"category={category.Value}, color={color.Value}, flipped={flipped.Value}")
                          .SetEventValue(drawingView.stampItems.Count);
                GoogleAnalyticsV4.getInstance().LogEvent(hit);
            })
            .AddTo(this);

            category.Value = m_Categories[0].category;

            // Whenever we click on a catalogue item, set that image as the current brush, then stamp its pixels onto
            // the drawing image with our brush when it is clicked
            m_CataloguePagerView.OnCatalogueItemPointerClickAsObservable()
            .Subscribe(tuple =>
            {
                // If we clicked instead of dragged the item, we're definitely not dragging
                isDragAndDropping.Value = false;
                brush.Value             = new BrushItem()
                {
                    catalogueItem = tuple.Item2
                };
            })
            .AddTo(this);

            // If we switch into the screen view that contains the editing profile text, copy in the image to it
            m_UiScreenView.onScreenBeginTransition.AsObservable()
            .Where(targetScreen => targetScreen == m_EditingProfileTextScreen.screenIndex)
            .Subscribe(ignored => { Drawing.PostDrawing(drawingView, m_EditingProfileTextDrawingView); })
            .AddTo(this);

            // Drawing code
            var opaque      = new Color(1f, 1f, 1f, 1f);
            var transparent = new Color(1f, 1f, 1f, m_PreviewBrushTransparency);

            // Draw a preview of the brush
            var previewBrush = new GameObject("Preview Brush");
            var previewImage = previewBrush.AddComponent <Image>();

            // The preview image brush naturally should not receive raycasts / should not block
            previewImage.raycastTarget = false;
            var previewBrushTransform = previewBrush.transform as RectTransform;

            Debug.Assert(previewBrushTransform != null, nameof(previewBrushTransform) + " != null");

            // Changes the preview's sprite as long as the brush is not null. The brush is actually set inactive later.
            // Also reacts to when the flipping setting changes.
            brush
            .Where(b => brush.Value != null && brush.Value.sprite != null)
            .Subscribe(b =>
            {
                previewImage.sprite = b.sprite;
                previewImage.rectTransform.localScale =
                    new Vector3(b.flipped ? -1.0f : 1f, 1f, 1f);
                previewImage.SetNativeSize();
            })
            .AddTo(this);

            // Move the preview brush along with the mouse as long as there is a brush selected
            // Whether or not it will be visible depends on which layer it's on and whether or not we're on a mobile
            // device. Mobile devices do not show the preview when the item was just clicked. The layer is changed later.
            Observable.EveryUpdate()
            .Where(ignored => isActiveAndEnabled)
            .Subscribe(ignored =>
            {
                if (brush.Value == null ||
                    Application.isMobilePlatform && !isDragAndDropping.Value)
                {
                    previewBrush.SetActive(false);
                    return;
                }

                previewBrush.SetActive(true);
                var pointer           = ContinuousStandaloneInputModule.instance.pointerEventData;
                var isOverDrawingView = pointer.pointerCurrentRaycast.gameObject ==
                                        m_DrawingView.raycastTarget.gameObject;

                previewImage.color = isDragAndDropping.Value ? isOverDrawingView ? opaque : transparent : opaque;
                previewBrushTransform.transform.position = BrushPosition(pointer);
            })
            .AddTo(this);


            // When we are drag and dropping, put the preview brush on the root canvas layer so that its totally in
            // the foreground. Otherwise, put it in the preview layer so it only appears when the user's pointer is
            // hovering over the drawing canvas
            isDragAndDropping.StartWith(false)
            .Subscribe(dragging =>
            {
                previewBrushTransform.SetParent(dragging ? m_ScreenRectTransform : m_DrawingView.previewLayer);
            })
            .AddTo(this);

            // Draw the brush when it is stamped
            var foreground = m_DrawingView.stampLayer;

            m_DrawingView.OnPointerClickAsObservable()
            .Where(ignored => brush.Value != null)
            .Subscribe(pointer => { Stamp(pointer, foreground, brush.Value.flipped); })
            .AddTo(this);

            // Enable drag and dropping a specific sprite. Temporarily switches the brush and activates drag and drop mode
            m_CataloguePagerView
            .OnCatalogueItemBeginDragAsObservable()
            .Subscribe(tuple =>
            {
                isDragAndDropping.Value = true;
                brush.Value             = new BrushItem()
                {
                    catalogueItem = tuple.Item2
                };
            })
            .AddTo(this);

            // Stamp when we stop dragging a catalogue item
            m_CataloguePagerView
            .OnCatalogueItemEndDragAsObservable()
            .Subscribe(tuple =>
            {
                isDragAndDropping.Value = false;
                // If we're over the drawing view, we should stamp the sprite
                var isOverDrawingView = tuple.Item1.pointerCurrentRaycast.gameObject ==
                                        m_DrawingView.raycastTarget.gameObject;
                if (isOverDrawingView)
                {
                    Stamp(tuple.Item1, m_DrawingView.stampLayer, tuple.Item2.flipped);
                }

                // Then clear the brush no matter what
                brush.Value = null;
            })
            .AddTo(this);

            // Toggle the flip automatically if this particular asset is configured to do so
            stampEvents.Where(stamp => stamp != null && stamp.brush.flipsAfterStamp)
            .Subscribe(stamp => { flipped.Value = !flipped.Value; })
            .AddTo(this);

            drawingView.stampItems.ObserveCountChanged(true)
            .Subscribe(count => { m_CanUndo.Value = count > 0; })
            .AddTo(this);

            // Save as the user stamps
            stampEvents
            .Subscribe(stampEvent =>
            {
                // This throttles internally
                SaveGameController.instance.Save();

                if (stampEvent != null)
                {
                    // Analytics
                    var hit = new EventHitBuilder()
                              .SetEventCategory("profile creator")
                              .SetEventAction("stamp")
                              .SetEventLabel(stampEvent.brush.sprite.name)
                              .SetEventValue(drawingView.stampItems.Count);
                    GoogleAnalyticsV4.getInstance().LogEvent(hit);
                }
            })
            .AddTo(this);
        }
Exemplo n.º 3
0
 public static IDisposable BindTextTo(this Text label, IReactiveProperty <string> textProperty)
 {
     return(textProperty.DistinctUntilChanged()
            .Subscribe(x => label.text = x));
 }