Пример #1
0
        public async Task PreparePropertyDescriptorAsync()
        {
            if (string.IsNullOrEmpty(XamlCodeFile))
            {
                return;
            }

            if (_propertyDescriptor == null)
            {
                // Get Xaml code
                using (var codeStream = await StreamHelper.GetPackagedFileStreamAsync($"Patterns/{Name}/{XamlCodeFile}"))
                {
                    XamlCode = await codeStream.ReadTextAsync(Encoding.UTF8);

                    // Look for @[] values and generate associated properties
                    var regularExpression = new Regex(@"@\[(?<name>.+?)(:(?<type>.+?):(?<value>.+?)(:(?<parameters>.+?))?(:(?<options>.*))*)?\]@?");

                    _propertyDescriptor = new PropertyDescriptor {
                        Expando = new ExpandoObject()
                    };
                    var proxy = (IDictionary <string, object>)_propertyDescriptor.Expando;

                    foreach (Match match in regularExpression.Matches(XamlCode))
                    {
                        var label = match.Groups["name"].Value;
                        var name  = label.Replace(" ", string.Empty); // Allow us to have nicer display names, but create valid properties.
                        var type  = match.Groups["type"].Value;
                        var value = match.Groups["value"].Value;

                        var existingOption = _propertyDescriptor.Options.Where(o => o.Name == name).FirstOrDefault();

                        if (existingOption == null && string.IsNullOrWhiteSpace(type))
                        {
                            throw new NotSupportedException($"Unrecognized short identifier '{name}'; Define type and parameters of property in first occurance in {XamlCodeFile}.");
                        }

                        if (Enum.TryParse(type, out PropertyKind kind))
                        {
                            if (existingOption != null)
                            {
                                if (existingOption.Kind != kind)
                                {
                                    throw new NotSupportedException($"Multiple options with same name but different type not supported: {XamlCodeFile}:{name}");
                                }

                                continue;
                            }

                            PropertyOptions options;

                            switch (kind)
                            {
                            case PropertyKind.Slider:
                            case PropertyKind.DoubleSlider:
                                try
                                {
                                    var sliderOptions = new SliderPropertyOptions {
                                        DefaultValue = double.Parse(value)
                                    };
                                    var parameters    = match.Groups["parameters"].Value;
                                    var split         = parameters.Split('-');
                                    int minIndex      = 0;
                                    int minMultiplier = 1;
                                    if (string.IsNullOrEmpty(split[0]))
                                    {
                                        minIndex      = 1;
                                        minMultiplier = -1;
                                    }

                                    sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex]);
                                    sliderOptions.MaxValue = double.Parse(split[minIndex + 1]);
                                    if (split.Length > 2 + minIndex)
                                    {
                                        sliderOptions.Step = double.Parse(split[split.Length - 1]);
                                    }

                                    options = sliderOptions;
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})");
                                    TrackingManager.TrackException(ex);
                                    continue;
                                }

                                break;

                            case PropertyKind.TimeSpan:
                                try
                                {
                                    var sliderOptions = new SliderPropertyOptions {
                                        DefaultValue = TimeSpan.FromMilliseconds(double.Parse(value))
                                    };
                                    var parameters    = match.Groups["parameters"].Value;
                                    var split         = parameters.Split('-');
                                    int minIndex      = 0;
                                    int minMultiplier = 1;
                                    if (string.IsNullOrEmpty(split[0]))
                                    {
                                        minIndex      = 1;
                                        minMultiplier = -1;
                                    }

                                    sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex]);
                                    sliderOptions.MaxValue = double.Parse(split[minIndex + 1]);
                                    if (split.Length > 2 + minIndex)
                                    {
                                        sliderOptions.Step = double.Parse(split[split.Length - 1]);
                                    }

                                    options = sliderOptions;
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})");
                                    TrackingManager.TrackException(ex);
                                    continue;
                                }

                                break;

                            case PropertyKind.Enum:
                                try
                                {
                                    options = new PropertyOptions();
                                    var split    = value.Split('.');
                                    var typeName = string.Join(".", split.Take(split.Length - 1));
                                    var enumType = LookForTypeByName(typeName);
                                    options.DefaultValue = Enum.Parse(enumType, split.Last());
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine($"Unable to parse enum from {value}({ex.Message})");
                                    TrackingManager.TrackException(ex);
                                    continue;
                                }

                                break;

                            case PropertyKind.Bool:
                                try
                                {
                                    options = new PropertyOptions {
                                        DefaultValue = bool.Parse(value)
                                    };
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine($"Unable to parse bool from {value}({ex.Message})");
                                    continue;
                                }

                                break;

                            case PropertyKind.Brush:
                                try
                                {
                                    options = new PropertyOptions {
                                        DefaultValue = value
                                    };
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine($"Unable to parse bool from {value}({ex.Message})");
                                    TrackingManager.TrackException(ex);
                                    continue;
                                }

                                break;

                            default:
                                options = new PropertyOptions {
                                    DefaultValue = value
                                };
                                break;
                            }

                            options.Label           = label;
                            options.Name            = name;
                            options.OriginalString  = match.Value;
                            options.Kind            = kind;
                            options.IsTwoWayBinding = options.OriginalString.EndsWith("@");
                            proxy[name]             = new ValueHolder(options.DefaultValue);

                            _propertyDescriptor.Options.Add(options);
                        }
                    }
                }
            }
        }
Пример #2
0
 private void GitHub_OnClick(object sender, RoutedEventArgs e)
 {
     TrackingManager.TrackEvent("Link", GitHub.NavigateUri.ToString());
 }
Пример #3
0
        private async void InfoAreaPivot_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (InfoAreaPivot.SelectedItem != null)
            {
                if (DataContext is Pattern pattern)
                {
                    TrackingManager.TrackEvent("PropertyGrid", (InfoAreaPivot.SelectedItem as FrameworkElement)?.Name, pattern.Name);
                }
            }

            if (HamburgerMenu.CurrentPattern == null)
            {
                return;
            }

            if (InfoAreaPivot.SelectedItem == PropertiesPivotItem)
            {
                // If we switch to the Properties Panel, we want to use a binded version of the Xaml Code.
                if (HamburgerMenu.CurrentPattern.HasXAMLCode)
                {
                    _lastRenderedProperties = true;

                    var t = UpdateXamlRenderAsync(HamburgerMenu.CurrentPattern.BindedXamlCode);
                }

                return;
            }

            if (HamburgerMenu.CurrentPattern.HasXAMLCode && InfoAreaPivot.SelectedItem == XamlPivotItem && _lastRenderedProperties)
            {
                // Use this flag so we don't re-render the XAML tab if we're switching from tabs other than the properties one.
                _lastRenderedProperties = false;

                // If we switch to the Live Preview, then we want to use the Value based Text
                XamlCodeRenderer.Text = HamburgerMenu.CurrentPattern.UpdatedXamlCode;

                var t = UpdateXamlRenderAsync(HamburgerMenu.CurrentPattern.UpdatedXamlCode);
                await XamlCodeRenderer.RevealPositionAsync(new Position(1, 1));

                XamlCodeRenderer.Focus(FocusState.Programmatic);
                return;
            }

            if (HamburgerMenu.CurrentPattern.HasXAMLCode && InfoAreaPivot.SelectedItem == XamlReadOnlyPivotItem)
            {
                // Update Read-Only XAML tab on non-desktop devices to show changes to Properties
                XamlReadOnlyCodeRenderer.XamlSource = HamburgerMenu.CurrentPattern.UpdatedXamlCode;
            }

            if (HamburgerMenu.CurrentPattern.HasCSharpCode && InfoAreaPivot.SelectedItem == CSharpPivotItem)
            {
                CSharpCodeRenderer.CSharpSource = await HamburgerMenu.CurrentPattern.GetCSharpSourceAsync();

                return;
            }

            if (HamburgerMenu.CurrentPattern.HasJavaScriptCode && InfoAreaPivot.SelectedItem == JavaScriptPivotItem)
            {
                JavaScriptCodeRenderer.JavaScriptSource = await HamburgerMenu.CurrentPattern.GetJavaScriptSourceAsync();

                return;
            }
        }
Пример #4
0
 private async void DocumentationTextblock_OnLinkClicked(object sender, LinkClickedEventArgs e)
 {
     TrackingManager.TrackEvent("Link", e.Link);
     await Launcher.LaunchUriAsync(new Uri(e.Link));
 }
Пример #5
0
        private async void NavigationFrame_Navigating(object sender, NavigatingCancelEventArgs navigationEventArgs)
        {
            ProcessPatternEditorTime();

            MenuCategory category;

            if (navigationEventArgs.Parameter == null)
            {
                DataContext = null;
                HamburgerMenu.CurrentPattern = null;
                category = navigationEventArgs.Parameter as MenuCategory;

                if (category != null)
                {
                    TrackingManager.TrackPage($"{navigationEventArgs.SourcePageType.Name} - {category.Name}");
                }
                else
                {
                    TrackingManager.TrackPage($"{navigationEventArgs.SourcePageType.Name}");
                }

                HideInfoArea();
            }
            else
            {
                TrackingManager.TrackPage(navigationEventArgs.SourcePageType.Name);
                Commands.Clear();
                ShowInfoArea();

                var patternName = navigationEventArgs.Parameter.ToString();
                HamburgerMenu.CurrentPattern = await Patterns.GetPatternByName(patternName);

                DataContext = HamburgerMenu.CurrentPattern;

                if (HamburgerMenu.CurrentPattern == null)
                {
                    HideInfoArea();
                    return;
                }

                category = await Patterns.GetCategoryByPattern(HamburgerMenu.CurrentPattern);

                await Patterns.PushRecentPattern(HamburgerMenu.CurrentPattern);

                var propertyDesc = HamburgerMenu.CurrentPattern.PropertyDescriptor;

                InfoAreaPivot.Items.Clear();

                if (propertyDesc != null)
                {
                    _xamlRenderer.DataContext = propertyDesc.Expando;
                }

                Title.Text = HamburgerMenu.CurrentPattern.Name;

                if (propertyDesc != null && propertyDesc.Options.Count > 0)
                {
                    InfoAreaPivot.Items.Add(PropertiesPivotItem);
                }

                if (HamburgerMenu.CurrentPattern.HasXAMLCode)
                {
                    if (AnalyticsInfo.VersionInfo.GetDeviceFormFactor() != DeviceFormFactor.Desktop || HamburgerMenu.CurrentPattern.DisableXamlEditorRendering)
                    {
                        // Only makes sense (and works) for now to show Live Xaml on Desktop, so fallback to old system here otherwise.
                        XamlReadOnlyCodeRenderer.XamlSource = HamburgerMenu.CurrentPattern.UpdatedXamlCode;

                        InfoAreaPivot.Items.Add(XamlReadOnlyPivotItem);
                    }
                    else
                    {
                        XamlCodeRenderer.Text = HamburgerMenu.CurrentPattern.UpdatedXamlCode;

                        InfoAreaPivot.Items.Add(XamlPivotItem);

                        _xamlCodeRendererSupported = true;
                    }

                    InfoAreaPivot.SelectedIndex = 0;
                }

                if (HamburgerMenu.CurrentPattern.HasCSharpCode)
                {
                    CSharpCodeRenderer.CSharpSource = await this.HamburgerMenu.CurrentPattern.GetCSharpSourceAsync();

                    InfoAreaPivot.Items.Add(CSharpPivotItem);
                }

                if (HamburgerMenu.CurrentPattern.HasJavaScriptCode)
                {
                    JavaScriptCodeRenderer.CSharpSource = await this.HamburgerMenu.CurrentPattern.GetJavaScriptSourceAsync();

                    InfoAreaPivot.Items.Add(JavaScriptPivotItem);
                }

                if (!string.IsNullOrEmpty(HamburgerMenu.CurrentPattern.CodeUrl))
                {
                    GitHub.NavigateUri = new Uri(HamburgerMenu.CurrentPattern.CodeUrl);
                    GitHub.Visibility  = Visibility.Visible;
                }
                else
                {
                    GitHub.Visibility = Visibility.Collapsed;
                }

                if (HamburgerMenu.CurrentPattern.HasDocumentation)
                {
                    var docs = await this.HamburgerMenu.CurrentPattern.GetDocumentationAsync();

                    if (!string.IsNullOrWhiteSpace(docs))
                    {
                        DocumentationTextblock.Text = docs;
                        InfoAreaPivot.Items.Add(DocumentationPivotItem);
                    }
                }

                if (InfoAreaPivot.Items.Count == 0)
                {
                    HideInfoArea();
                }

                HamburgerMenu.Title = $"{category.Name} > {HamburgerMenu.CurrentPattern?.Name}";
                ApplicationView.SetTitle(this, $"{category.Name} > {HamburgerMenu.CurrentPattern?.Name}");
            }
        }