// Page Open Transition:
        // http://amadeusw.com/xaml/animated-navigation-universal-app

        /// <summary>
        /// Opens a page as an overlay. It must be closed to return to the page that opened it.
        /// </summary>
        public async Task <object> OpenModal(string page_caption, SmartPage page2open)
        {
            ShellData shell_data = Navigator.ShellData;

            if (shell_data.ManagesSmartPage(this) == false)
            {
                throw new InvalidOperationException("This Page object is not managed by the Ventura Navigator.");
            }

            // Since the page is managed, we are 100% sure the FrameData and TabData will also be found.

            TabData tabdata = shell_data.FindTabData(this);

            if (tabdata.TopMost() != this)
            {
                throw new InvalidOperationException("Only call OpenModal for the topmost Page object.");
            }

            Navigator.CloseAllSatelliteTabs(tabdata.UniqueID);

            page2open.IsModal     = true;
            page2open.PageCaption = page_caption;
            page2open.CloseAction = CloseActionKind.ReleaseTCS;
            page2open.TCS         = new TaskCompletionSource <object>();

            // PushPage MUST come before the await.
            tabdata.PushPage(page2open);

            object result = await page2open.TCS.Task;

            return(result);

            //await Task.CompletedTask; // Dummy task
        }
Пример #2
0
        private void FrameData_ShelvePageEvent(SmartPage page)
        {
            page.InternalDeActivate();

            if (Presenter.Content != null && Presenter.Content.Equals(page))
            {
                Presenter.Content = null;
            }
        }
Пример #3
0
        internal Validator(SmartPage page, T viewmodel)
        {
            _page = page;

            _list = new List <ValidatorItem <T> >();

            _viewmodel = viewmodel;

            _viewmodel.PropertyChanged += Viewmodel_PropertyChanged;
        }
Пример #4
0
        // This event is called and then unhooked.
        private void ChainInto_Page_Loaded(object sender, RoutedEventArgs e)
        {
            SmartPage page = (SmartPage)sender;

            page.Loaded -= ChainInto_Page_Loaded;

            page.InternalPageOpened();

            if (ViewModel.IsActivated)
            {
                page.InternalActivate();
            }
        }
Пример #5
0
        private void FrameData_FrameDeActivatedEvent()
        {
            Update_ActivationRectangle_Color();

            if (ViewModel.SelectedTab != null)
            {
                SmartPage topmost_page = ViewModel.SelectedTab.TopMost();

                if (topmost_page != null)
                {
                    topmost_page.InternalDeActivate();
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Start from scratch. This will repair any animation positioning errors.
        /// </summary>
        private void RedrawCollection()
        {
            if (_canvas == null)
            {
                return;
            }

            _list_of_visuals.Clear();
            _canvas.Children.Clear();

            if (this.PageStack == null)
            {
                return;
            }

            // Create the SingleCrumb classes
            for (int i = 0; i < this.PageStack.Count; i++)
            {
                SmartPage page    = this.PageStack[i];
                bool      isfirst = (i == 0);

                var control = new SingleCrumb {
                    FirstItem = isfirst, Text = page.PageCaption
                };

                // First Add to the visual tree
                _canvas.Children.Add(control);

                // Second create the the Visual
                BreadCrumbVisual item = new BreadCrumbVisual(control);

                // Third, add to the collection of visuals
                _list_of_visuals.Add(item);
            }

            float offset = CalculateOffset();

            foreach (var bcv in _list_of_visuals)
            {
                bcv.Offset           = (float)offset;
                bcv.CalculatedOffset = (float)offset;

                offset += (float)bcv.Width;
            }
        }
        public void OpenSatellite(string tab_caption, string page_caption, SmartPage page2open, string instance_id = null)
        {
            if (instance_id != null && instance_id.Contains("/"))
            {
                throw new ArgumentException("The instance_id cannot contain a '/' character.");
            }

            if (instance_id == null)
            {
                instance_id = Guid.NewGuid().ToString();
            }

            var shelldata = Navigator.ShellData;

            if (shelldata.ManagesSmartPage(this) == false)
            {
                throw new InvalidOperationException("This Page object is not managed by the Ventura Navigator.");
            }

            // Since the page is managed, we are 100% sure the FrameData and TabData will also be found.

            TabData   tabdata_this   = shelldata.FindTabData(this);
            FrameData framedata_this = shelldata.FindFrameData(this);

            if (tabdata_this.TopMost() != this)
            {
                throw new InvalidOperationException("Only call OpenSatellite from the topmost Page object.");
            }

            // Create a unique ID for the satellite tab. For example:
            // MASTERPAGE_UNIQUE_ID + "/" + "COUNTRIESLIST_PAGE" + "/" "INTERNAL ID"
            // MASTERPAGE_UNIQUE_ID + "/" + "ORDERSTATUSLIST_PAGE" + "/" "INTERNAL ID

            string unique_id = tabdata_this.UniqueID + "/" + page2open.GetType().FullName + "/" + instance_id;

            // Check if a tab with the unique_id is already open.
            var found = shelldata.FindTabData(m => m.UniqueID == unique_id);

            // If the tab is found, then select the tab and make it active
            if (found != null)
            {
                var frame = shelldata.FindFrameData(found);
                frame.SelectedTab          = found;
                shelldata.ActiveFrameIndex = frame.Index;
                return;
            }

            // A satellite page is guaranteed not to have satellite pages itself.
            //
            // If this tab is a satellite tab, it is not possible to open another satellite.
            // This is to prevent a tab from becoming both master and satellite at the same time.
            //
            // MASTER       LINKED
            //              MASTER      LINKED
            //                          MASTER        LINKED
            // orders1 ---> order1 ---> orders2 ----> order2
            //
            // Even though we asked for the page to be opened as a satellite page, it will be opened as a modal instead.
            // The return value however, will be received in the SatellitePageClosed event by the caller.
            //

            if (tabdata_this.IsSatellite == true)
            {
                // Open the page as a 'modal' overlay.
                page2open.IsModal     = true;
                page2open.PageCaption = page_caption;
                page2open.CloseAction = CloseActionKind.CloseModal_SatelliteClosedEventOnParentPage;
                page2open.InstanceID  = instance_id;

                tabdata_this.PushPage(page2open);

                return;
            }

            page2open.CloseAction = CloseActionKind.CloseTab_With_SatelliteClosedEventOnMasterTab;
            page2open.InstanceID  = instance_id;

            // Is Left, then right..
            // Is right, then left...
            int opposite_frameindex = 0;

            if (framedata_this.Index == 0)
            {
                opposite_frameindex = 1;
            }

            // Make sure the screen is split
            shelldata.SplitScreen = true;

            // Activate
            shelldata.ActiveFrameIndex = opposite_frameindex;

            // The new tab
            FrameData framedata_satellite = shelldata.Frames[opposite_frameindex];
            var       tabs = framedata_satellite.Tabs;

            TabData tabdata_satellite = new TabData(tab_caption, page_caption, page2open, tabdata_this.ColorInfo, unique_id);

            // Keep satellite tabs of the same mastertab together.
            int insertindex = -1;

            for (int i = tabs.Count - 1; i >= 0; i--)
            {
                if (tabs[i].MasterTabID == tabdata_this.UniqueID)
                {
                    insertindex = i + 1;
                    break;
                }
            }

            if (insertindex == -1)
            {
                framedata_satellite.Tabs.Add(tabdata_satellite);
            }
            else
            {
                framedata_satellite.Tabs.Insert(insertindex, tabdata_satellite);
            }

            // Make the new tab selected.
            framedata_satellite.SelectedTab = tabdata_satellite;
        }
Пример #8
0
        private void FrameData_DisplayAnotherPageEvent(FrameData.PageDisplayReason reason, SmartPage page)
        {
            if (Presenter.Content != null && Presenter.Content.Equals(page))
            {
                return; // content already set. nothing to do.
            }
            if (reason == FrameData.PageDisplayReason.TabSelect)
            {
                Update_ActivationRectangle_Color();
            }

            // Page can be null.

            if (page != null)
            {
                page.Loaded += ChainInto_Page_Loaded;
            }

            Presenter.Content = page; // This will cause the page.Loaded event to be fired.
        }
        /// <summary>
        /// Close the Modal page or close the Tab.
        /// </summary>
        public void ClosePage(object retvar = null)
        {
            ShellData shell_data = Navigator.ShellData;

            if (shell_data.ManagesSmartPage(this) == false)
            {
                throw new InvalidOperationException("This Page object is not managed by the Ventura Navigator.");
            }

            // Find the tab that holds the page in its modalstack.
            TabData tabdata = shell_data.FindTabData(this);

            if (tabdata.TopMost() != this)
            {
                throw new InvalidOperationException("Only call CloseModal for the topmost Page object.");
            }

            Navigator.CloseAllSatelliteTabs(tabdata.UniqueID);

            tabdata.PopPage();

            // The topmost will be null if no pages left on the stack.
            var topmost = tabdata.TopMost();

            if (this.CloseAction == CloseActionKind.CloseTab)
            {
                Navigator.InternalCloseTab(tabdata);
            }
            else if (this.CloseAction == CloseActionKind.ReleaseTCS)
            {
                this.TCS.SetResult(retvar);
            }
            else if (this.CloseAction == CloseActionKind.CloseTab_With_SatelliteClosedEventOnMasterTab)
            {
                Navigator.InternalCloseTab(tabdata);

                TabData tabdata_master = shell_data.FindTabData(tabdata.MasterTabID);

                if (tabdata_master != null)
                {
                    FrameData framedata_master = shell_data.FindFrameData(tabdata_master);

                    // Make the frame containing the master page (for the satellite page) active.
                    shell_data.ActiveFrameIndex = framedata_master.Index;

                    // Make the master page the selected tab.
                    framedata_master.SelectedTab = tabdata_master;

                    SmartPage topmost_master = tabdata_master.TopMost();

                    if (topmost_master != null)
                    {
                        topmost_master.SatellitePageClosed(this.InstanceID, retvar);
                    }
                }
            }
            else if (this.CloseAction == CloseActionKind.CloseModal_SatelliteClosedEventOnParentPage)
            {
                topmost.SatellitePageClosed(this.InstanceID, retvar);
                //await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => topmost.SatellitePageClosed(this.InstanceID, retvar));
            }
        }
Пример #10
0
        /// <summary>
        /// The calculated offset for the first child element inside the Canvas.
        /// </summary>
        //private float _canvas_offset = 0.0f;

        private void PageStack_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                if (e.NewItems.Count != 1)
                {
                    return;
                }

                SmartPage page = e.NewItems[0] as SmartPage;

                bool isfirst = (_canvas.Children.Count == 0);

                var control = new SingleCrumb {
                    FirstItem = isfirst, Text = page.PageCaption
                };

                // First, add to the visual tree
                _canvas.Children.Add(control); // Add the Element to the visual tree

                // Second, create the visual
                BreadCrumbVisual bcv = new BreadCrumbVisual(control);

                float new_offset = CalculateOffset((float)bcv.Width);

                ShiftAllElementsToOffset(new_offset, miliseconds_delay: 0); // was 0

                // The total width before adding the new element.
                double total_width = CalcTotalWidth();

                // Third, add to the visuals collection
                _list_of_visuals.Add(bcv);

                bcv.Offset           = new_offset + (float)total_width;
                bcv.CalculatedOffset = new_offset + (float)total_width;

                var anim = bcv.Compositor.CreateSpringScalarAnimation();
                anim.Period        = TimeSpan.FromMilliseconds(200); // was 50
                anim.DelayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay;
                anim.DelayTime     = TimeSpan.FromMilliseconds(200);
                anim.DampingRatio  = 0.88f; // 0.2f
                anim.StopBehavior  = AnimationStopBehavior.SetToFinalValue;
                anim.InitialValue  = (float)_canvas.ActualWidth;
                anim.FinalValue    = new_offset + (float)total_width;


                //var scopedBatch = bcv.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
                //scopedBatch.Completed += ScopedBatch_Completed;
                bcv.Visual.StartAnimation("Offset.X", anim);

                //scopedBatch.End();
                //bcv.Offset = (float)total_width - (overflow+(float)bcv.Width);
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                if (e.OldItems.Count != 1)
                {
                    return;
                }

                SmartPage page_data = e.OldItems[0] as SmartPage;

                BreadCrumbVisual bcv = _list_of_visuals[_list_of_visuals.Count - 1];

                var anim = bcv.Compositor.CreateSpringScalarAnimation();
                anim.Period = TimeSpan.FromSeconds(0.50); // was 0.05
                //anim.DelayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay;
                //anim.DelayTime = TimeSpan.FromMilliseconds(100);
                anim.DampingRatio = 0.88f; // 0.2f
                anim.StopBehavior = AnimationStopBehavior.SetToFinalValue;
                anim.InitialValue = bcv.CalculatedOffset;
                anim.FinalValue   = (float)_canvas.ActualWidth;

                Action action = () =>
                {
                    _canvas.Children.Remove(bcv.Element); // remove from Visual Tree
                };

                _list_of_visuals.Remove(bcv);

                CompositionScopedBatch scopedBatch = bcv.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation);

                scopedBatch.Comment = _counter.ToString(); _counter++;

                _dictionary.Add(scopedBatch.Comment, action);

                scopedBatch.Completed += ScopedBatch_Completed;
                bcv.Visual.StartAnimation("Offset.X", anim);
                scopedBatch.End();
                //bcv.Offset = (float)total_width - (overflow+(float)bcv.Width);

                float new_offset = CalculateOffset();                          // The offset might have changed as we removed the last item.

                ShiftAllElementsToOffset(new_offset, miliseconds_delay: 1200); // was 300
            }
            else
            {
                RedrawCollection();
            }
        }