Example #1
0
 /// <summary>
 /// Setup the slide edges
 /// </summary>
 private void calcSlideEdges()
 {
     if (_slideStartLocations == null)
     {
         double sum    = 0;
         var    widths = Enumerable.Range(0, SlideStrip.Items.Count)
                         .Select(index => SlideStrip.ContainerFromIndex(index) as ContentPresenter)
                         .Select(container => _orientation == FullPanelOrientation.Horizontal ? container.ActualWidth : container.ActualHeight)
                         .Select(w => sum += w);
         _slideStartLocations              = widths
                                          .ToArray();
     }
 }
Example #2
0
        public FullTalkAsStripView()
        {
            this.InitializeComponent();
            this.WhenActivated(disposeOfMe =>
            {
                disposeOfMe(this.OneWayBind(ViewModel, x => x.Pages, y => y.SlideStrip.ItemsSource));

                // If the ESC key or backbutton is hit, we want to navigate back.
                var keyrelease = SlideStrip.Events().KeyDown
                                 .Where(keys => ViewModel != null);

                keyrelease
                .Where(keys => keys.Key == VirtualKey.Escape)
                .Do(keys => keys.Handled = true)
                .Subscribe(e => Locator.Current.GetService <RoutingState>().NavigateBack.Execute(null));

                backButton.WireAsBackButton();

                // Forward and backwards arrows.
                // Tricky because if we calcCurrentPage while in the middle of the scroll we won't
                // get a scroll to the item we want. So we need to aggregate those while running.
                var isScrollInProgress = theScrollViewer
                                         .Events().ViewChanged
                                         .Select(sc => sc.IsIntermediate);

                var keysByScrolling = keyrelease
                                      .Select(k => Tuple.Create(k, calcKeyMoveRequest(k)))
                                      .Where(k => k.Item2 != 0)
                                      .Do(k => k.Item1.Handled = true)
                                      .Select(k => k.Item2)
                                      .BatchByStream(isScrollInProgress);

                keysByScrolling
                .Where(info => !info.Item1)
                .Subscribe(info => info.Item2.Subscribe(delta => ViewModel.PageMove.Execute(calcCurrentPage() + delta)));

                keysByScrolling
                .Where(info => info.Item1)
                .SelectMany(async info => await info.Item2.Sum())
                .Where(d => d != 0)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(delta => ViewModel.PageMove.Execute(delta + calcCurrentPage()));

                // We can't tell what size things are in here (which we need for scrolling, etc.) until
                // we have a clue as to what the layout is. So, we have to wait for that to go.
                var widthOfItemsChanged = SlideStrip.Events().SizeChanged
                                          .Select(_ => SlideStrip.ActualHeight)
                                          .Throttle(TimeSpan.FromMilliseconds(100))
                                          .DistinctUntilChanged();

                disposeOfMe(widthOfItemsChanged
                            .Subscribe(_ => _slideStartLocations = null));

                // And when we get asked to bring a page into view...
                disposeOfMe(this.WhenAny(x => x.ViewModel, x => x.Value)
                            .Where(x => x != null)
                            .Subscribe(vm =>
                {
                    vm.MoveToPage
                    .CombineLatest(widthOfItemsChanged, (pn, width) => pn)
                    .ObserveOn(RxApp.MainThreadScheduler)
                    .Where(pn => SlideStrip.ContainerFromIndex(0) != null)
                    .Select(pn => getSlideEdge(pn))
                    .Subscribe(loc =>
                    {
                        if (_orientation == FullPanelOrientation.Horizontal)
                        {
                            theScrollViewer.ChangeView(loc, null, null);
                        }
                        else
                        {
                            theScrollViewer.ChangeView(null, loc, null);
                        }
                    });
                }));

                // Make the back button visible if there is any movement - scrolling or otherwise.
                var buttonRelatedMovement =
                    Observable.Merge(
                        this.Events().PointerMoved.Select(x => Unit.Default),
                        this.Events().Tapped.Select(x => Unit.Default)
                        );

                var makeVisible = buttonRelatedMovement
                                  .Select(x => true);

                var makeInvisible = buttonRelatedMovement
                                    .Select(x => Observable.Return(false).Delay(TimeSpan.FromSeconds(3)))
                                    .Switch();

                Observable.Merge(makeVisible, makeInvisible)
                .DistinctUntilChanged()
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(v => backButton.Visibility = v ? Windows.UI.Xaml.Visibility.Visible : Windows.UI.Xaml.Visibility.Collapsed);
                backButton.Visibility = Windows.UI.Xaml.Visibility.Collapsed;

                // Setup the rendering helper - when they are in frame, cause a rendering to happen. When they
                // are out of frame, then turn off showing everything!
                _holder = new OnScreenTrackingHelper(
                    theScrollViewer,
                    (uiElement, inViewPort) =>
                {
                    if (uiElement is PDFPageUserControl)
                    {
                        (uiElement as PDFPageUserControl).ShowPDF = inViewPort;
                    }
                }
                    )
                {
                    ItemsWaitingInTheWings = 2
                };

                this.Events().Unloaded
                .Subscribe(t => _holder.Unload());

                // We want to capture key strokes, etc. By default we don't have
                // the focus, so grab it.
                Focus(Windows.UI.Xaml.FocusState.Programmatic);

                // The orientation of this pannel will affect how we calc the arrow key stuff.
                _orientation = theScrollViewer.VerticalScrollMode == ScrollMode.Disabled ? FullPanelOrientation.Horizontal : FullPanelOrientation.Vertical;
            });
        }