Beispiel #1
0
        /// <summary>
        /// Display a notification to display on top right corner of canvas
        /// and display message passed as param
        /// </summary>
        /// <param name="content">The target content to display.</param>
        internal void CreateRealTimeInfoWindow(string content)
        {
            //Search a UIElement with the Name "statusBarPanel" inside the Dynamo VisualTree
            UIElement hostUIElement = Guide.FindChild(mainRootElement, "statusBarPanel");

            // When popup already exist, replace the content
            if (exitTourPopup != null && exitTourPopup.IsOpen)
            {
                exitTourPopup.TextContent = content;
            }
            else
            {
                // Otherwise creates the RealTimeInfoWindow popup and set up all the needed values
                // to show the popup over the Dynamo workspace
                exitTourPopup = new RealTimeInfoWindow()
                {
                    VerticalOffset   = ExitTourVerticalOffset,
                    HorizontalOffset = ExitTourHorizontalOffset,
                    Placement        = PlacementMode.Left,
                    TextContent      = content
                };

                if (hostUIElement != null)
                {
                    exitTourPopup.PlacementTarget = hostUIElement;
                }
                exitTourPopup.IsOpen = true;
            }
        }
Beispiel #2
0
        /// <summary>
        /// This method will update the Target in case the UI Automation was executed and the Popup was waiting for a specific Window to be opened
        /// </summary>
        internal void UpdatePlacementTarget()
        {
            if (stepUIPopup == null)
            {
                return;
            }
            //This means that the HostPopupInfo.HostUIElementString is in a different Window than DynamoView
            if (!string.IsNullOrEmpty(HostPopupInfo.WindowName))
            {
                Window ownedWindow = Guide.FindWindowOwned(HostPopupInfo.WindowName, MainWindow as Window);
                if (ownedWindow == null)
                {
                    return;
                }
                HostPopupInfo.HostUIElement = ownedWindow;
                stepUIPopup.PlacementTarget = ownedWindow;
                UpdateLocation();
            }
            //This case will be used for UIElements that are in the Dynamo VisualTree but they are shown until there is a user interaction (like the SideBar cases)
            var hostUIElement = Guide.FindChild(MainWindow, HostPopupInfo.HostUIElementString);

            if (hostUIElement == null)
            {
                return;
            }
            HostPopupInfo.HostUIElement = hostUIElement;
            stepUIPopup.PlacementTarget = hostUIElement;
            UpdateLocation();
        }
Beispiel #3
0
        /// <summary>
        /// This method will update the CutOff rectangle size everytime that the step change
        /// </summary>
        /// <param name="bVisible">It will say if the CutOff Area will be disabled or enabled</param>
        private void SetCutOffSectionSize(bool bVisible)
        {
            if (HostPopupInfo.CutOffRectArea == null)
            {
                return;
            }
            if (bVisible)
            {
                //This will validate that HostPopupInfo.HostUIElement is in the MainWindow VisualTree otherwise the TransformToAncestor() will crash
                var foundUIElement = Guide.FindChild(MainWindow, HostPopupInfo.HostUIElementString);
                if (foundUIElement == null)
                {
                    return;
                }

                Point relativePoint = HostPopupInfo.HostUIElement.TransformToAncestor(MainWindow)
                                      .Transform(new Point(0, 0));

                var holeWidth  = HostPopupInfo.HostUIElement.DesiredSize.Width + HostPopupInfo.CutOffRectArea.WidthBoxDelta;
                var holeHeight = HostPopupInfo.HostUIElement.DesiredSize.Height + HostPopupInfo.CutOffRectArea.HeightBoxDelta;

                if (StepGuideBackground.CutOffBackgroundArea != null)
                {
                    StepGuideBackground.CutOffBackgroundArea.CutOffRect = new Rect(relativePoint.X, relativePoint.Y, holeWidth, holeHeight);
                }
            }
            else
            {
                StepGuideBackground.ClearCutOffSection();
            }
        }
Beispiel #4
0
        /// <summary>
        /// This method will return a new HostControlInfo object populated with the information passed as parameter
        /// Basically this method store the information coming from Step and search the UIElement in the main WPF VisualTree
        /// </summary>
        /// <param name="jsonStepInfo">Step that contains all the info deserialized from the Json file</param>
        /// <returns></returns>
        private HostControlInfo CreateHostControl(HostControlInfo jsonHostControlInfo)
        {
            //We use the HostControlInfo copy construtor
            var popupInfo = new HostControlInfo(jsonHostControlInfo, mainRootElement);

            //If the CutOff area was defined in the json file then a section of the background overlay will be removed
            if (jsonHostControlInfo.CutOffRectArea != null)
            {
                popupInfo.CutOffRectArea = new CutOffArea()
                {
                    WidthBoxDelta  = jsonHostControlInfo.CutOffRectArea.WidthBoxDelta,
                    HeightBoxDelta = jsonHostControlInfo.CutOffRectArea.HeightBoxDelta
                };
            }

            //If the Highlight area was defined in the json file then a rectangle will be highlighted in the Overlay
            if (jsonHostControlInfo.HighlightRectArea != null)
            {
                //We use the HighlightArea copy construtor
                popupInfo.HighlightRectArea = new HighlightArea(jsonHostControlInfo.HighlightRectArea);
            }

            //The host_ui_element read from the json file need to exists otherwise the host will be null
            UIElement hostUIElement = Guide.FindChild(mainRootElement, popupInfo.HostUIElementString);

            if (hostUIElement != null)
            {
                popupInfo.HostUIElement = hostUIElement;
            }

            return(popupInfo);
        }
        /// <summary>
        /// This method will be executed when packages search window is opened, so it can identify the close button of the window
        /// </summary>
        /// <param name="stepInfo"></param>
        /// <param name="uiAutomationData"></param>
        /// <param name="enableFunction"></param>
        /// <param name="currentFlow"></param>
        internal static void ExecuteClosePackagesSearch(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            if (enableFunction)
            {
                CurrentExecutingStep = stepInfo;

                if (stepInfo.ExitGuide != null)
                {
                    exitGuide = stepInfo.ExitGuide;
                }

                Window ownedWindow = Guide.FindWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window);

                foreach (var handler in uiAutomationData.AutomaticHandlers)
                {
                    if (ownedWindow == null)
                    {
                        return;
                    }

                    CloseButtonSearchPackages        = Guide.FindChild(ownedWindow, handler.HandlerElement) as Button;
                    CloseButtonSearchPackages.Click += CloseButton_Click;
                }
            }
            else
            {
                if (CloseButtonSearchPackages != null)
                {
                    CloseButtonSearchPackages.Click -= CloseButton_Click;
                }
            }
        }
 internal static void EnableNextButton(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
 {
     if (searchPackagesLoaded)
     {
         var nextButton = Guide.FindChild((CurrentExecutingStep.StepUIPopup as PopupWindow).mainPopupGrid, uiAutomationData.ElementName) as Button;
         if (nextButton != null)
         {
             nextButton.IsEnabled = true;
         }
     }
 }
Beispiel #7
0
        /// <summary>
        /// This method will be executed when the OnGuidedTourStart event is raised
        /// </summary>
        /// <param name="args">This parameter will contain the GuideName as a string</param>
        private void TourStarted(GuidedTourStateEventArgs args)
        {
            tourStarted = true;

            currentGuide = (from guide in Guides where guide.Name.Equals(args.GuideName) select guide).FirstOrDefault();
            if (currentGuide != null)
            {
                //Show background overlay
                guideBackgroundElement.Visibility   = Visibility.Visible;
                currentGuide.GuideBackgroundElement = guideBackgroundElement;
                currentGuide.MainWindow             = mainRootElement;
                currentGuide.LibraryView            = Guide.FindChild(mainRootElement, libraryViewName);
                currentGuide.Initialize();
                currentGuide.Play();
                GuidesValidationMethods.CurrentExecutingGuide = currentGuide;
            }
        }
Beispiel #8
0
        /// <summary>
        /// Show the tooltip in the DynamoUI, first execute UI Automation, then Prevalidation, then calculate target host and finally highlight an element
        /// </summary>
        internal void Show(Guide.GuideFlow currentFlow)
        {
            //In case the UIAutomation info is set for the Step we execute all the UI Automation actions when the Next button is pressed
            if (UIAutomation != null)
            {
                foreach (var automation in UIAutomation)
                {
                    ExecuteUIAutomationStep(automation, true, currentFlow);
                }
            }

            //If the PreValidation info was read from the json file then is executed and it will decide which Step should be shown and which not
            if (PreValidationInfo != null)
            {
                ExecutePreValidation();
            }

            //After the UI Automation is done we need to calculate the Target (if is not in DynamoView)
            CalculateTargetHost();

            //After the Popup.PlacementTarget was recalculated (or calculated) then we proceed to put the cut off section
            SetCutOffSectionSize(true);

            //After UI Automation and calculate the target we need to highlight the element (otherwise probably won't exist)
            SetHighlightSection(true);

            if (HostPopupInfo.WindowName != null && HostPopupInfo.WindowName.Equals(nameof(LibraryView)))
            {
                var automationStep = (from automation in UIAutomation
                                      where automation.Name.Equals(calculateLibraryFuncName)
                                      select automation).FirstOrDefault();
                GuidesValidationMethods.CalculateLibraryItemLocation(this, automationStep, true, Guide.GuideFlow.CURRENT);
            }


            stepUIPopup.IsOpen = true;

            if (this.StepUIPopup is PopupWindow popupWindow)
            {
                if (Guide.FindChild((popupWindow).mainPopupGrid, NextButton) is Button nextbuttonFound)
                {
                    nextbuttonFound.Focus();
                }
            }
        }
        /// <summary>
        /// This method will be executed when passing from Step 2 to Step 3 in the Packages guide, so it will show the TermsOfUse Window in case it was not accepted yet
        /// </summary>
        /// <param name="stepInfo"></param>
        /// <param name="uiAutomationData"></param>
        /// <param name="enableFunction"></param>
        /// <param name="currentFlow"></param>
        internal static void ExecuteTermsOfServiceFlow(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            CurrentExecutingStep = stepInfo;

            if (stepInfo.ExitGuide != null)
            {
                exitGuide = stepInfo.ExitGuide;
            }

            //When enableFunction = true, means we want to show the TermsOfUse Window (this is executed in the UIAutomation step in the Show() method)
            if (enableFunction)
            {
                //If the TermsOfService is not accepted yet it will show the TermsOfUseView otherwise it will show the PackageManagerSearchView
                stepInfo.DynamoViewModelStep.ShowPackageManagerSearch(null);
                Window ownedWindow = Guide.FindWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window);

                foreach (var handler in uiAutomationData.AutomaticHandlers)
                {
                    if (ownedWindow == null)
                    {
                        return;
                    }
                    UIElement element = Guide.FindChild(ownedWindow, handler.HandlerElement);

                    //When the Accept button is pressed in the TermsOfUseView then we need to move to the next Step
                    if (element != null)
                    {
                        ManageEventHandler(element, handler.HandlerElementEvent, handler.ExecuteMethod);
                    }
                }
            }
            //When enableFunction = false, means we are hiding (closing) the TermsOfUse Window due that we are moving to the next Step or we are exiting the Guide
            else
            {
                Window ownedWindow = Guide.FindWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window);
                if (ownedWindow == null)
                {
                    return;
                }

                //Tries to close the TermsOfUseView or the PackageManagerSearchView if they were opened previously
                Guide.CloseWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Creates the background for the GuidedTour
        /// </summary>
        private void CreateBackground()
        {
            Window mainWindow = Window.GetWindow(mainRootElement);

            if (guideBackgroundElement == null)
            {
                guideBackgroundElement = new GuideBackground(mainWindow)
                {
                    Name = guideBackgroundName,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment   = VerticalAlignment.Top,
                    Visibility          = Visibility.Hidden
                };

                Grid mainGrid = Guide.FindChild(mainRootElement, mainGridName) as Grid;
                mainGrid.Children.Add(guideBackgroundElement);
                Grid.SetColumnSpan(guideBackgroundElement, 5);
                Grid.SetRowSpan(guideBackgroundElement, 6);
            }
        }
        /// <summary>
        /// This method will subscribe the Next button from the Step8 Popup for clicking the Package already installed (then it will be expanded).
        /// </summary>
        /// <param name="stepInfo">Information about the Step</param>
        /// <param name="uiAutomationData">Specific UI Automation step that is being executed</param>
        /// <param name="enableFunction">it says if the functionality should be enabled or disabled</param>
        /// <param name="currentFlow">The current flow of the Guide can be FORWARD or BACKWARD</param>
        internal static void SubscribeNextButtonClickEvent(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            CurrentExecutingStep = stepInfo;
            //if there is not handler then the function should return
            if (uiAutomationData.AutomaticHandlers == null || uiAutomationData.AutomaticHandlers.Count == 0)
            {
                return;
            }
            //Due that only one handler was configured we get the first one
            var automaticHandler = uiAutomationData.AutomaticHandlers.FirstOrDefault();
            //Find the NextButton inside the Popup
            var nextbuttonFound = Guide.FindChild((CurrentExecutingStep.StepUIPopup as PopupWindow).mainPopupGrid, automaticHandler.HandlerElement) as Button;

            if (nextbuttonFound == null)
            {
                return;
            }
            //Add or Remove the handler assigned to the Button.Click
            ManageEventHandler(nextbuttonFound, automaticHandler.HandlerElementEvent, automaticHandler.ExecuteMethod, enableFunction);
        }
        /// <summary>
        /// This method will subcribe the menu "Packages->Search for a Package" MenuItem to the Next event so when is pressed we will moved to the next Step
        /// </summary>
        /// <param name="stepInfo">Information about the Step</param>
        /// <param name="uiAutomationData">Information about UI Automation that is being executed</param>
        /// <param name="enableFunction">Variable used to know if we are executing the automation or undoing changes</param>
        /// <param name="currentFlow">Current Guide Flow</param>
        internal static void SubscribeSearchForPackagesOption(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            CurrentExecutingStep = stepInfo;

            //We try to find the WindowElementNameString (in this case the MenuItem) in the DynamoView VisualTree
            var foundUIElement = Guide.FindChild(CurrentExecutingStep.MainWindow, CurrentExecutingStep.HostPopupInfo.HighlightRectArea.WindowElementNameString) as MenuItem;

            if (foundUIElement == null)
            {
                return;
            }
            if (enableFunction)
            {
                //Executed then Showing the Step
                foundUIElement.Click += SearchForPackage_Click;
            }
            else
            {
                //Just executed when exiting the Guide or when passing to the next Step
                foundUIElement.Click -= SearchForPackage_Click;
            }
        }
        /// <summary>
        /// This method will be executed when passing from Step 6 to Step 7 in the Packages guide, so it will subscribe the install button event
        /// </summary>
        /// <param name="stepInfo"></param>
        /// <param name="uiAutomationData"></param>
        /// <param name="enableFunction"></param>
        /// <param name="currentFlow"></param>
        internal static void ExecuteInstallPackagesFlow(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            CurrentExecutingStep = stepInfo;
            Window ownedWindow = Guide.FindWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window);


            if (enableFunction)
            {
                if (ownedWindow != null)
                {
                    viewModel = ownedWindow.DataContext as PackageManagerSearchViewModel;
                }

                Button buttonElement = Guide.FindChild(ownedWindow, stepInfo.HostPopupInfo.HostUIElementString) as Button;
                viewModel.PackageManagerClientViewModel.Downloads.CollectionChanged += Downloads_CollectionChanged;
            }
            else
            {
                //Tries to close the TermsOfUseView or the PackageManagerSearchView if they were opened previously
                Guide.CloseWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window);
            }
        }
        /// <summary>
        /// This method will be used to subscribe a method to the Button.Click event of the ViewDetails button located in the PackageManagerSearch Window
        /// </summary>
        /// <param name="stepInfo">Information about the Step</param>
        /// <param name="uiAutomationData">Information about UI Automation that is being executed</param>
        /// <param name="enableFunction">Variable used to know if we are executing the automation or undoing changes</param>
        /// <param name="currentFlow">Current Guide Flow</param>
        internal static void SubscribeViewDetailsEvent(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            CurrentExecutingStep = stepInfo;
            PackageManagerSearchView packageManager = Guide.FindWindowOwned(stepInfo.HostPopupInfo.WindowName, stepInfo.MainWindow as Window) as PackageManagerSearchView;

            if (packageManager == null)
            {
                return;
            }
            Button foundElement = Guide.FindChild(packageManager, stepInfo.HostPopupInfo.HighlightRectArea.WindowElementNameString) as Button;

            if (foundElement == null)
            {
                return;
            }
            if (enableFunction)
            {
                foundElement.Click += ViewDetails_Click;
            }
            else
            {
                foundElement.Click -= ViewDetails_Click;
            }
        }
Beispiel #15
0
        /// <summary>
        /// This function will highlight a Window element (the element can be located in DynamoView or another Window or can be a MenuItem
        /// <param name="bVisible">Indicates if the highlight should be applied or removed</param>
        internal void HighlightWindowElement(bool bVisible)
        {
            //Check if the HighlightRectArea was provided in the json file and the HostUIElement was found in the DynamoView VisualTree
            if (HostPopupInfo.HighlightRectArea == null || HostPopupInfo.HostUIElement == null)
            {
                return;
            }
            //Check if the WindowElementNameString was provided in the json and is not empty
            if (string.IsNullOrEmpty(HostPopupInfo.HighlightRectArea.WindowElementNameString))
            {
                return;
            }

            //If is MenuItem type means that the Popup.TargetPlacement will be calculated dinamically
            if (HostPopupInfo.HighlightRectArea.UIElementTypeString.Equals(typeof(MenuItem).Name))
            {
                //We try to find the WindowElementNameString (in this case the MenuItem) in the DynamoView VisualTree
                var foundUIElement = Guide.FindChild(HostPopupInfo.HostUIElement, HostPopupInfo.HighlightRectArea.WindowElementNameString);

                if (foundUIElement != null)
                {
                    var subMenuItem = foundUIElement as MenuItem;

                    //If the HighlightRectArea.WindowElementNameString described is a MenuItem (Dynamo menu) then we need to add the Rectangle dynamically to the Template
                    HighlightMenuItem(subMenuItem, bVisible);
                }
            }
            //The HighlightRectArea.UIElementTypeString was provided but the type is DynamoView then we will search the element in the DynamoView VisualTree
            else if (HostPopupInfo.HighlightRectArea.UIElementTypeString.Equals(typeof(DynamoView).Name))
            {
                string highlightColor = HostPopupInfo.HighlightRectArea.HighlightColor;

                //Find the in the DynamoView VisualTree the specified Element (WindowElementNameString)
                var hostUIElement = Guide.FindChild(MainWindow, HostPopupInfo.HighlightRectArea.WindowElementNameString);

                if (hostUIElement == null)
                {
                    return;
                }

                //If the Element was found we need to calculate the X,Y coordinates based in the UIElement Ancestor
                Point relativePoint = hostUIElement.TransformToAncestor(MainWindow)
                                      .Transform(new Point(0, 0));

                var holeWidth  = hostUIElement.DesiredSize.Width + HostPopupInfo.HighlightRectArea.WidthBoxDelta;
                var holeHeight = hostUIElement.DesiredSize.Height + HostPopupInfo.HighlightRectArea.HeightBoxDelta;

                //Activate the Highlight rectangle from the GuideBackground
                StepGuideBackground.HighlightBackgroundArea.SetHighlighRectSize(relativePoint.Y, relativePoint.X, holeWidth, holeHeight);

                if (string.IsNullOrEmpty(highlightColor))
                {
                    StepGuideBackground.GuideHighlightRectangle.Stroke = Brushes.Transparent;
                }
                else
                {
                    //This section will put the desired color in the Highlight rectangle (read from the json file)
                    var converter = new BrushConverter();
                    var brush     = (Brush)converter.ConvertFromString(highlightColor);
                    StepGuideBackground.GuideHighlightRectangle.Stroke = brush;
                }
            }
            //This case is for when the item to be highlighted is inside the LibraryView (WebBrowser component)
            else if (HostPopupInfo.HighlightRectArea.UIElementTypeString.Equals(typeof(WebBrowser).Name))
            {
                //We need to access the WebBrowser instance and call a js function to highlight the html div border of the item
                HighlightLibraryItem(bVisible);
            }
            //If the UIElementTypeString is not a MenuItem and also not a DynamoView we need to find the Window in the OwnedWindows and search the element inside it
            else
            {
                string highlightColor = HostPopupInfo.HighlightRectArea.HighlightColor;
                Window ownedWindow    = Guide.FindWindowOwned(HostPopupInfo.HighlightRectArea.WindowName, MainWindow as Window);
                if (ownedWindow == null)
                {
                    return;
                }
                UIElement foundElement = Guide.FindChild(ownedWindow, HostPopupInfo.HighlightRectArea.WindowElementNameString);
                switch (HostPopupInfo.HighlightRectArea.UIElementTypeString.ToUpper())
                {
                //We need to highlight a Button (if the Button template doesn't have a grid then the template needs to be updated)
                case "BUTTON":
                    var buttonElement = foundElement as Button;
                    if (buttonElement == null)
                    {
                        return;
                    }

                    //We will be searching for the Grid name provided in the json file and then add the Highlight Rectangle
                    var bordersGrid = buttonElement.Template.FindName(HostPopupInfo.HighlightRectArea.UIElementGridContainer, buttonElement) as Grid;
                    if (bordersGrid == null)
                    {
                        return;
                    }

                    if (bVisible)
                    {
                        var buttonRectangle = CreateRectangle(bordersGrid, HostPopupInfo.HighlightRectArea.HighlightColor);
                        //The Rectangle will be added dynamically in a specific step and then when passing to next step we will remove it
                        bordersGrid.Children.Add(buttonRectangle);
                    }
                    else
                    {
                        //When we need to undo the highlight we find the Rectangle and remove it
                        var buttonRectangle = bordersGrid.Children.OfType <Rectangle>().Where(rect => rect.Name.Equals("HighlightRectangle")).FirstOrDefault();
                        if (buttonRectangle != null)
                        {
                            bordersGrid.Children.Remove(buttonRectangle);
                        }
                    }
                    break;
                }
            }
        }
Beispiel #16
0
        /// <summary>
        /// This method will execute an UIAutomation action over a specific UIElement
        /// </summary>
        /// <param name="uiAutomationData">UIAutomation info read from a json file</param>
        /// <param name="enableUIAutomation">Enable/Disable the automation action for a specific UIElement</param>
        private void ExecuteUIAutomationStep(StepUIAutomation uiAutomationData, bool enableUIAutomation, Guide.GuideFlow currentFlow)
        {
            var popupBorderName = "SubmenuBorder";
            //This section will search the UIElement dynamically in the Dynamo VisualTree in which an automation action will be executed
            UIElement automationUIElement = Guide.FindChild(MainWindow, uiAutomationData.Name);

            if (automationUIElement != null)
            {
                uiAutomationData.UIElementAutomation = automationUIElement;
            }

            switch (uiAutomationData.ControlType)
            {
            case StepUIAutomation.UIControlType.MENUITEM:
                if (uiAutomationData.UIElementAutomation == null)
                {
                    return;
                }
                MenuItem menuEntry = uiAutomationData.UIElementAutomation as MenuItem;
                if (menuEntry == null)
                {
                    return;
                }
                switch (uiAutomationData.Action)
                {
                case StepUIAutomation.UIAction.OPEN:
                    menuEntry.IsSubmenuOpen    = enableUIAutomation;
                    menuEntry.StaysOpenOnClick = enableUIAutomation;
                    break;
                }
                //Means that the Popup location needs to be updated after the MenuItem is opened
                if (uiAutomationData.UpdatePlacementTarget)
                {
                    //We need to find the border inside the MenuItem.Popup so we can get its Width (this template is defined in MenuStyleDictionary.xaml)
                    var menuPopupBorder = menuEntry.Template.FindName(popupBorderName, menuEntry) as Border;
                    if (menuPopupBorder == null)
                    {
                        return;
                    }

                    //We need to do this substraction so the Step Popup wil be located at the end of the MenuItem Popup.
                    stepUIPopup.HorizontalOffset = (menuPopupBorder.ActualWidth - menuEntry.ActualWidth) + HostPopupInfo.HorizontalPopupOffSet;
                    UpdatePopupLocationInvoke(stepUIPopup);
                }
                break;

            //In this case the UI Automation will be done using a Function located in the static class GuidesValidationMethods
            case StepUIAutomation.UIControlType.FUNCTION:
                MethodInfo builderMethod   = typeof(GuidesValidationMethods).GetMethod(uiAutomationData.Name, BindingFlags.Static | BindingFlags.NonPublic);
                object[]   parametersArray = new object[] { this, uiAutomationData, enableUIAutomation, currentFlow };
                builderMethod.Invoke(null, parametersArray);
                //If UpdatePlacementTarget = true then means that a new Window was opened after executing the funtion then we need to update the Popup.PlacementTarget
                if (uiAutomationData.UpdatePlacementTarget)
                {
                    UpdatePlacementTarget();
                }
                break;

            //In this case the UI Automation will be done over a WPF Button
            case StepUIAutomation.UIControlType.BUTTON:
                if (string.IsNullOrEmpty(uiAutomationData.WindowName))
                {
                    return;
                }

                //This means that the Button is in a PopupWindow (instead of the DynamoView) so we need to find the button and then apply the automation
                if (uiAutomationData.WindowName.Equals(WindowNamePopup))
                {
                    //Finds the Button inside the PopupWindow
                    var buttonFound = Guide.FindChild((stepUIPopup as PopupWindow).mainPopupGrid, uiAutomationData.Name) as Button;
                    if (buttonFound == null)
                    {
                        return;
                    }

                    switch (uiAutomationData.Action)
                    {
                    case StepUIAutomation.UIAction.DISABLE:
                        if (enableUIAutomation)
                        {
                            buttonFound.IsEnabled = false;
                        }
                        else
                        {
                            buttonFound.IsEnabled = true;
                        }
                        break;
                    }
                }
                break;

            case StepUIAutomation.UIControlType.JSFUNCTION:
                if (string.IsNullOrEmpty(uiAutomationData.JSFunctionName))
                {
                    return;
                }
                //We need to create a new list for the parameters due that we will be adding the enableUIAutomation boolean value
                var parametersJSFunction = new List <object>(uiAutomationData.JSParameters);
                parametersJSFunction.Add(enableUIAutomation);
                //Create the array for the parameters that will be sent to the JS Function
                object[] jsParameters = parametersJSFunction.ToArray();
                //Create the array for the paramateres that will be sent to the WebBrowser.InvokeScript Method
                object[] parametersInvokeScript = new object[] { uiAutomationData.JSFunctionName, jsParameters };
                //Execute the JS function with the provided parameters
                ResourceUtilities.ExecuteJSFunction(MainWindow, HostPopupInfo, parametersInvokeScript);
                break;
            }
        }
Beispiel #17
0
        /// <summary>
        /// This method will execute an UIAutomation action over a specific UIElement
        /// </summary>
        /// <param name="uiAutomationData">UIAutomation info read from a json file</param>
        /// <param name="enableUIAutomation">Enable/Disable the automation action for a specific UIElement</param>
        private void ExecuteUIAutomationStep(StepUIAutomation uiAutomationData, bool enableUIAutomation, Guide.GuideFlow currentFlow)
        {
            //This section will search the UIElement dynamically in the Dynamo VisualTree in which an automation action will be executed
            UIElement automationUIElement = Guide.FindChild(MainWindow, uiAutomationData.Name);

            if (automationUIElement != null)
            {
                uiAutomationData.UIElementAutomation = automationUIElement;
            }

            switch (uiAutomationData.ControlType)
            {
            case StepUIAutomation.UIControlType.MENUITEM:
                if (uiAutomationData.UIElementAutomation == null)
                {
                    return;
                }
                MenuItem menuEntry = uiAutomationData.UIElementAutomation as MenuItem;
                if (menuEntry == null)
                {
                    return;
                }
                switch (uiAutomationData.Action)
                {
                case StepUIAutomation.UIAction.OPEN:
                    menuEntry.IsSubmenuOpen    = enableUIAutomation;
                    menuEntry.StaysOpenOnClick = enableUIAutomation;
                    break;
                }
                break;

            //In this case the UI Automation will be done using a Function located in the static class GuidesValidationMethods
            case StepUIAutomation.UIControlType.FUNCTION:
                MethodInfo builderMethod   = typeof(GuidesValidationMethods).GetMethod(uiAutomationData.Name, BindingFlags.Static | BindingFlags.NonPublic);
                object[]   parametersArray = new object[] { this, uiAutomationData, enableUIAutomation, currentFlow };
                builderMethod.Invoke(null, parametersArray);
                //If UpdatePlacementTarget = true then means that a new Window was opened after executing the funtion then we need to update the Popup.PlacementTarget
                if (uiAutomationData.UpdatePlacementTarget)
                {
                    UpdatePlacementTarget();
                }
                break;

            //In this case the UI Automation will be done over a WPF Button
            case StepUIAutomation.UIControlType.BUTTON:
                if (string.IsNullOrEmpty(uiAutomationData.WindowName))
                {
                    return;
                }

                //This means that the Button is in a PopupWindow (instead of the DynamoView) so we need to find the button and then apply the automation
                if (uiAutomationData.WindowName.Equals(WindowNamePopup))
                {
                    //Finds the Button inside the PopupWindow
                    var buttonFound = Guide.FindChild((stepUIPopup as PopupWindow).mainPopupGrid, uiAutomationData.Name) as Button;
                    if (buttonFound == null)
                    {
                        return;
                    }

                    switch (uiAutomationData.Action)
                    {
                    case StepUIAutomation.UIAction.DISABLE:
                        if (enableUIAutomation)
                        {
                            buttonFound.IsEnabled = false;
                        }
                        else
                        {
                            buttonFound.IsEnabled = true;
                        }
                        break;
                    }
                }
                break;
            }
        }
Beispiel #18
0
 /// <summary>
 /// GuidesManager Constructor
 /// </summary>
 /// <param name="root">root item of the main Dynamo Window </param>
 /// <param name="dynViewModel"></param>
 public GuidesManager(UIElement root, DynamoViewModel dynViewModel)
 {
     mainRootElement        = root;
     dynamoViewModel        = dynViewModel;
     guideBackgroundElement = Guide.FindChild(root, guideBackgroundName) as GuideBackground;
 }
        /// <summary>
        /// This method will be opening the SideBar Package Details (or closing it when enableFunction = false)
        /// </summary>
        /// <param name="stepInfo">Information about the Step</param>
        /// <param name="uiAutomationData">Information about UI Automation that is being executed</param>
        /// <param name="enableFunction">Variable used to know if we are executing the automation or undoing changes</param>
        /// <param name="currentFlow">Current Guide Flow</param>
        internal static void ExecuteViewDetailsSideBar(Step stepInfo, StepUIAutomation uiAutomationData, bool enableFunction, GuideFlow currentFlow)
        {
            const string packageDetailsName      = "Package Details";
            const string closeButtonName         = "CloseButton";
            const string packageSearchWindowName = "PackageSearch";

            CurrentExecutingStep = stepInfo;
            var stepMainWindow       = stepInfo.MainWindow as Window;
            var packageDetailsWindow = Guide.FindChild(stepMainWindow, stepInfo.HostPopupInfo.HostUIElementString) as UserControl;

            if (enableFunction)
            {
                //This section will open the Package Details Sidebar
                PackageManagerSearchView packageManager = Guide.FindWindowOwned(packageSearchWindowName, stepMainWindow) as PackageManagerSearchView;
                if (packageManager == null)
                {
                    return;
                }
                PackageManagerSearchViewModel packageManagerViewModel = packageManager.DataContext as PackageManagerSearchViewModel;

                //If the results in the PackageManagerSearch are null then we cannot open the Package Detail tab
                if (packageManagerViewModel == null || packageManagerViewModel.SearchResults.Count == 0)
                {
                    return;
                }

                //We take the first result from the PackageManagerSearch
                PackageManagerSearchElementViewModel packageManagerSearchElementViewModel = packageManagerViewModel.SearchResults[0];
                if (packageManagerSearchElementViewModel == null)
                {
                    return;
                }

                if (packageDetailsWindow == null)
                {
                    packageManagerViewModel.ViewPackageDetailsCommand.Execute(packageManagerSearchElementViewModel.Model);
                }

                //The PackageDetails sidebar is using events when is being shown then we need to execute those events before setting the Popup.PlacementTarget.
                //otherwise the sidebar will not be present (and we don't have host for the Popup) and the Popup will be located out of the Dynamo window
                CurrentExecutingStep.MainWindow.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
            }
            else
            {
                //This section will close the Package Details Sidebar (just in case is still opened),
                //due that the sidebar (UserControl) is inserted inside a TabItem the only way to close is by using the method dynamoView.CloseExtensionTab
                var dynamoView = (stepMainWindow as DynamoView);
                if (packageDetailsWindow == null)
                {
                    return;
                }
                //In order to close the Package Details tab we need first to get the Tab, then get the Close button and finally call the event to close it
                TabItem tabitem = dynamoView.ExtensionTabItems.OfType <TabItem>().SingleOrDefault(n => n.Header.ToString() == packageDetailsName);
                if (tabitem == null)
                {
                    return;
                }
                //Get the Close button from the PackageDetailsView
                Button closeButton = Guide.FindChild(tabitem, closeButtonName) as Button;
                if (closeButton == null)
                {
                    return;
                }
                dynamoView.CloseExtensionTab(closeButton, null);
            }
        }