public static void Create() { var lightTheme = new OriginalLightTheme(); var darkTheme = new OriginalDarkTheme(); var path = new BehaviorSubject <string>(string.Empty); var refresh = new BehaviorSubject <Unit>(Unit.Default); var image = path .CombineLatest(refresh, ((p, _) => p)) .Select(p => AbsoluteFilePath.TryParse(p) .Where(f => File.Exists(f.NativePath)) .Select( absPath => absPath.NativePath.EndsWith(".svg") ? (IImage) new SvgImage(() => File.OpenRead(absPath.NativePath)) : new MultiResolutionImage( new[] { new ImageStream(new Ratio <Pixels, Points>(1), () => File.OpenRead(absPath.NativePath)) })) .Or(() => (IImage) new SvgImage(() => new MemoryStream(FallbackImage)))); var content = Layout.Dock().Top( Layout.Dock() .Left(Label.Create("Path: ", font: Theme.DefaultFont, color: Theme.DefaultText).CenterVertically()) .Right(Buttons.DefaultButton("Refresh", Command.Enabled(() => refresh.OnNext(Unit.Default)))) .Fill(ThemedTextBox.Create(path.AsProperty()))) .Fill(Layout.SubdivideHorizontally(ImageVersionsRowForTheme(image, darkTheme), ImageVersionsRowForTheme(image, lightTheme))) .WithBackground(Theme.PanelBackground); Application.Desktop.CreateSingletonWindow( Observable.Return(true), dialog => new Window { Title = Observable.Return("Icon preview"), Size = Property.Create <Optional <Size <Points> > >(new Size <Points>(600, 600)).ToOptional(), Content = content, Background = Theme.PanelBackground, Foreground = Theme.DefaultText, Border = Separator.MediumStroke }); }
public ExtractClassViewModel( IContext context, string suggestedName, IObservable <HashSet <string> > allClassNames, IClassExtractor classExtractor, IFileSystem fileSystem, IProject project) { _className = Property.Create(suggestedName); _createInNewFile = Property.Create(false); var newFileNameSubject = new BehaviorSubject <string>(""); var hasEditedFileName = false; _newFileName = newFileNameSubject.AsProperty( isReadOnly: _createInNewFile.Select(check => check == false), write: (name, save) => { hasEditedFileName = true; newFileNameSubject.OnNext(name); }); _className.Subscribe( name => { if (!hasEditedFileName) { var filename = name.Replace(".", System.IO.Path.DirectorySeparatorChar.ToString()) + ".ux"; newFileNameSubject.OnNext(filename); } }); var action = _className.CombineLatest( allClassNames, _createInNewFile, _newFileName, project.RootDirectory, (name, allClasses, toNewFile, fileName, projectPath) => { // Don't care about whitespace at beginning or end name = name.Trim(); if (name.IsNullOrEmpty()) { return(new ValidatedAction("")); } if (name.Any(char.IsWhiteSpace)) { return(new ValidatedAction("Class name can't contain whitespaces")); } if (!ClassNameValidationRegexp.IsMatch(name)) { return(new ValidatedAction("Class name is not valid")); } if (allClasses.Contains(name)) { return(new ValidatedAction("Class name already in use")); } if (toNewFile) { var relativePath = RelativeFilePath.TryParse(fileName); if (!relativePath.HasValue) { return(new ValidatedAction("Not a valid filename")); } if (!fileName.EndsWith(".ux")) { return(new ValidatedAction("Filename must end in .ux")); } if (fileSystem.Exists(projectPath.Combine(relativePath.Value))) { return(new ValidatedAction("The file already exists")); } if (fileName.IsNullOrEmpty()) { return(new ValidatedAction("Filename can not be empty")); } } return(new ValidatedAction( () => { // A Task is returned by this method, however, we don't do anything with it // and just let it finish in the background classExtractor.ExtractClass( element: context.CurrentSelection, name: name, fileName: toNewFile ? Optional.Some(RelativeFilePath.Parse(fileName)) : Optional.None()); })); }) .Replay(1).RefCount(); _userInfo = action.Select(x => x.Message); _createCommand = Command.Create(action.Select(x => x.Action)); }