예제 #1
0
        /// <summary>
        /// Fires OnPanelAvailable on the UI thread.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="panel"></param>
        private async void FireOnPanelAvailable(IContentPanelHost host, IContentPanelBase panelBase)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
            {
                try
                {
                    // First tell the post it has a host
                    panelBase.OnHostAdded(host);

                    // Then tell the host it has a panel.
                    host.OnPanelAvailable(panelBase);
                }
                catch (Exception e)
                {
                    App.BaconMan.MessageMan.DebugDia("FireOnPanelAvailable failed", e);
                    App.BaconMan.TelemetryMan.ReportUnexpectedEvent(this, "FireOnPanelAvailableFailed", e);
                }
            });
        }
예제 #2
0
        /// <summary>
        /// Fires FireOnPanelStolen on the UI thread.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="panel"></param>
        private async Task FireOnRemovePanel(IContentPanelHost host, IContentPanelBase panelBase)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
            {
                try
                {
                    // Tell the panel the host is gone
                    panelBase.OnHostRemoved();

                    // And remove the panel.
                    host.OnRemovePanel(panelBase);
                }
                catch (Exception e)
                {
                    App.BaconMan.MessageMan.DebugDia("FireOnRemovePanel failed", e);
                    App.BaconMan.TelemetryMan.ReportUnexpectedEvent(this, "FireOnRemovePanelFailed", e);
                }
            });
        }
예제 #3
0
        /// <summary>
        /// When fired the source given should fall back to a web
        /// browser instead of a complex control.
        /// </summary>
        public async void FallbackToWebrowser(ContentPanelSource source)
        {
            IContentPanelHost hostToReport = null;
            IContentPanelBase panelToKill  = null;

            // Fire on load complete so if someone else was waiting on us they will
            // move on.
            OnContentLoadComplete(source.Id);

            // Lock
            lock (m_currentPanelList)
            {
                // Make sure we have it.
                if (m_currentPanelList.ContainsKey(source.Id))
                {
                    // Grab the panel to kill and the host to tell.
                    ContentListElement element = m_currentPanelList[source.Id];
                    hostToReport = element.Host;
                    panelToKill  = element.PanelBase;

                    // Null the post and update our state
                    element.PanelBase = null;
                    element.State     = ContentState.Unloaded;
                }
                else
                {
                    return;
                }
            }

            // Remove the panel
            if (hostToReport != null && panelToKill != null)
            {
                await FireOnRemovePanel(hostToReport, panelToKill);
            }

            // Kill the panel
            if (panelToKill != null)
            {
                await FireOnDestroyContent(panelToKill);

                panelToKill = null;
            }

            ContentPanelSource sourceToCreate = null;
            bool isVisible = false;

            // Now lock again
            lock (m_currentPanelList)
            {
                // Make sure we still have it.
                if (m_currentPanelList.ContainsKey(source.Id))
                {
                    ContentListElement element = m_currentPanelList[source.Id];
                    if (element.State == ContentState.Unloaded)
                    {
                        // Grab the element again and set the new state.
                        isVisible = element.IsVisible;
                        element.Source.ForceWeb = true;
                        sourceToCreate          = element.Source;
                        element.State           = ContentState.PendingCreation;
                    }
                    else
                    {
                        // if we are not in the same state get out of here.
                        return;
                    }
                }
                else
                {
                    return;
                }
            }

            if (sourceToCreate != null)
            {
                BeginLoadContent(sourceToCreate, isVisible);
            }
        }
예제 #4
0
 /// <summary>
 /// Fires FireOnDestroyContnet on the UI thread.
 /// </summary>
 /// <param name="host"></param>
 /// <param name="panel"></param>
 private async Task FireOnDestroyContent(IContentPanelBase panelBase)
 {
     await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
     {
         try
         {
             panelBase.OnDestroyContent();
         }
         catch (Exception e)
         {
             App.BaconMan.MessageMan.DebugDia("FireOnRemovePanel failed", e);
             App.BaconMan.TelemetryMan.ReportUnexpectedEvent(this, "FireOnRemovePanelFailed", e);
         }
     });
 }
예제 #5
0
        /// <summary>
        /// Called by hosts when they want to get a panel
        /// </summary>
        /// <param name="panelId"></param>
        public async void RegisterForPanel(IContentPanelHost host, string panelId)
        {
            // Indicates if we should fire content loading.
            IContentPanelHost fireContentLoadingHost = null;

            // Used to fire the on panel available event.
            IContentPanelBase returnPanelBase = null;

            // Used to hold a past host if there is one.
            IContentPanelHost pastHost = null;

            // Used to hold the host we will tell is unloaded.
            IContentPanelHost fireUnloadedHost = null;


            // Check to see if the panel exists
            lock (m_currentPanelList)
            {
                // We already have it
                if (m_currentPanelList.ContainsKey(panelId))
                {
                    ContentListElement element = m_currentPanelList[panelId];

                    if (element.Host == null)
                    {
                        // We don't have a host, add ourselves.
                        element.Host = host;
                        if (element.State == ContentState.Created)
                        {
                            // If the control is already created fire the on control available right now.
                            returnPanelBase = element.PanelBase;
                        }
                        else if (element.State == ContentState.PendingCreation)
                        {
                            // If the content is being created tell the panel that.
                            fireContentLoadingHost = element.Host;
                        }
                        else if (element.State == ContentState.Unloaded)
                        {
                            fireUnloadedHost = element.Host;
                        }
                    }
                    else
                    {
                        // We already have a host, grab the host so we can kill it
                        // but make sure to null it so the post doesn't load while we are killing it.
                        pastHost     = element.Host;
                        element.Host = null;

                        // If the control is already created remove it from the old host.
                        if (element.State == ContentState.Created)
                        {
                            // If the control is already created fire the on control available right now.
                            returnPanelBase = element.PanelBase;
                        }
                    }
                }
                else
                {
                    // We don't have it, make an entry so when we get it
                    // we will be called back if one is created.
                    ContentListElement element = new ContentListElement()
                    {
                        Host  = host,
                        State = ContentState.NotAllowed
                    };
                    m_currentPanelList.Add(panelId, element);
                }
            }

            // If we have a past host we are transferring.
            if (pastHost != null)
            {
                // If we have a panel already we need to remove it.
                if (returnPanelBase != null)
                {
                    await FireOnRemovePanel(pastHost, returnPanelBase);
                }

                // Now that the old host is gone, register again.
                RegisterForPanel(host, panelId);
                return;
            }

            // Out of lock, fire the event if we have a panel
            if (returnPanelBase != null)
            {
                FireOnPanelAvailable(host, returnPanelBase);
            }

            // Or if we have content loading.
            if (fireContentLoadingHost != null)
            {
                FireOnContentPreloading(fireContentLoadingHost);
            }

            // Or if we have unloaded content.
            if (fireUnloadedHost != null)
            {
                FireOnPanelUnloaded(fireUnloadedHost);
            }
        }
예제 #6
0
        /// <summary>
        /// Fired when the current panel should be cleared.
        /// </summary>
        /// <param name="panel"></param>
        public void OnRemovePanel(IContentPanelBase panelBase)
        {
            lock(this)
            {
                // Release the panel
                m_currentPanelBase = null;
            }

            // Clear out the UI
            ui_contentRoot.Children.Clear();

            // Set loading.
            ToggleProgress(true, false);
        }
예제 #7
0
        /// <summary>
        /// Called when we have a panel.
        /// </summary>
        /// <param name="panel"></param>
        public void OnPanelAvailable(IContentPanelBase panelBase)
        {
            lock(this)
            {
                // Capture the panel
                m_currentPanelBase = panelBase;
            }

            // Setup loading.
            SetupLoading();

            // Setup error text
            SetupGenericMessage();

            // Setup NSFW
            SetupNsfwBlock();

            // Add the panel to the UI.
            UserControl userControl = (UserControl)panelBase.Panel;
            ui_contentRoot.Children.Add(userControl);
        }
예제 #8
0
        /// <summary>
        /// If the content is allowed it will be unloaded. It will remain in this state until
        /// a panel that wasn't it becomes visible.
        /// </summary>
        public async void UnloadContent(string sourceId)
        {
            string            idToCallLoadCompleteOn = null;
            IContentPanelHost hostToTakeFrom         = null;
            IContentPanelBase panelToDestory         = null;

            // Lock the list.
            lock (m_currentPanelList)
            {
                // Make sure we have the id
                if (!m_currentPanelList.ContainsKey(sourceId))
                {
                    return;
                }

                // Get the element.
                ContentListElement element = m_currentPanelList[sourceId];

                // Make sure we have something to do here.
                if (element.State == ContentState.NotAllowed || element.State == ContentState.Unloaded)
                {
                    return;
                }

                if (element.State == ContentState.PendingCreation)
                {
                    // The object is either being created or delay loaded. If we set the status to
                    // unloaded this will kill the object when created.
                    element.State = ContentState.Unloaded;

                    // Make sure it isn't in the delay load list
                    m_delayLoadQueue.Remove(element.Source);

                    // Grab the id so we can call load complete on the id.
                    // This will ensure if this is the post we are waiting on
                    // the delay load will move on.
                    idToCallLoadCompleteOn = element.Source.Id;
                }
                else
                {
                    // We are created, grab the panel
                    panelToDestory    = element.PanelBase;
                    element.PanelBase = null;

                    // Set our state to unloaded.
                    element.State = ContentState.Unloaded;

                    // If we have a host we need to remove it from the host. It is safe to steal
                    // the panel and host from the list because this panel will not be reset into
                    // the UI until it is created again (which won't be this panel)
                    if (element.Host != null)
                    {
                        hostToTakeFrom = element.Host;
                    }
                }
            }

            // If we have an id call on load complete. This will cause delay load
            // to move on if this was the elemet it was waiting on.
            if (idToCallLoadCompleteOn != null)
            {
                OnContentLoadComplete(idToCallLoadCompleteOn);
            }

            // If we have a source and a panel, take it from the host.
            if (hostToTakeFrom != null && panelToDestory != null)
            {
                await FireOnRemovePanel(hostToTakeFrom, panelToDestory);

                // #todo tell the host it was unloaded so they can put up UI.
            }

            // If we have a panel destroy it.
            if (panelToDestory != null)
            {
                await FireOnDestroyContent(panelToDestory);
            }
        }
예제 #9
0
        public async void UnRegisterForPanel(IContentPanelHost host, string panelId)
        {
            // Fist we need to see if there was a panel.
            IContentPanelBase removePanelBase = null;

            lock (m_currentPanelList)
            {
                // Make sure we have an entry.
                if (!m_currentPanelList.ContainsKey(panelId))
                {
                    return;
                }

                ContentListElement element = m_currentPanelList[panelId];

                // Important! Make sure this host is the correct host for the panel!
                // This can happen if two hosts register for the same id, but the newer will
                // replace the older one. But we don't want the older to unregister and kill
                // the entry for the newer host.
                // The host can also be null if we are in the process of switching.
                if (element.Host == null || !element.Host.Id.Equals(host.Id))
                {
                    // Try to find the panel in our back stack.
                    IContentPanelHost removeStackHost = null;
                    foreach (IContentPanelHost stackHost in element.PastHosts)
                    {
                        if (stackHost.Id.Equals(host.Id))
                        {
                            removeStackHost = stackHost;
                            break;
                        }
                    }

                    // If found remove it, if it is in this stack it isn't registered anywhere.
                    if (removeStackHost != null)
                    {
                        element.PastHosts.Remove(removeStackHost);
                    }
                    else
                    {
                        // This is odd, report it.
                        App.BaconMan.MessageMan.DebugDia("panel removed that wasn't active or in the panel stack");
                        if (Debugger.IsAttached)
                        {
                            Debugger.Break();
                        }
                    }

                    // Get out of here.
                    return;
                }

                removePanelBase = m_currentPanelList[panelId].PanelBase;
            }

            // If we got a panel back clear it out
            if (removePanelBase != null)
            {
                await FireOnRemovePanel(host, removePanelBase);
            }

            IContentPanelHost restoreHost = null;

            // Now actually clear the host
            lock (m_currentPanelList)
            {
                // Make sure we have an entry.
                if (!m_currentPanelList.ContainsKey(panelId))
                {
                    return;
                }

                // Remove the current host.
                ContentListElement element = m_currentPanelList[panelId];
                element.Host = null;

                // If we have a past host restore it.
                if (element.PastHosts.Count > 0)
                {
                    // Get the host
                    restoreHost = element.PastHosts[0];
                    element.PastHosts.RemoveAt(0);
                }

                // If we the state isn't allowed and we don't have a host to restore
                // delete this entry because no one wants it.
                if (element.State == ContentState.NotAllowed && restoreHost == null)
                {
                    m_currentPanelList.Remove(panelId);
                }
            }

            // If we have a panel to restore call register on it.
            if (restoreHost != null)
            {
                RegisterForPanel(restoreHost, panelId);
            }
        }