private void CreateNode(Task task) { var node = MorphList.CreateItem(MorphList.GetRoot()); node.SetCellMode(0, TreeItem.TreeCellMode.String); node.SetText(0, task.Key); node.SetCellMode(1, TreeItem.TreeCellMode.String); node.SetText(1, task.Surface); node.SetCellMode(2, TreeItem.TreeCellMode.String); node.SetText(2, Translate($"ui.BlendMapGenerator.status.{task.State}")); node.SetCellMode(3, TreeItem.TreeCellMode.String); node.SetText(3, task.File.Name); }
protected override void PostConstruct() { base.PostConstruct(); SourceList.CreateItem(); SourceList.SetColumnTitle(0, Translate("ui.BlendMapGenerator.name")); SourceList.SetColumnTitle(1, Translate("ui.BlendMapGenerator.path")); SourceList.SetColumnTitlesVisible(true); MorphList.CreateItem(); MorphList.SetColumnTitle(0, Translate("ui.BlendMapGenerator.name")); MorphList.SetColumnTitle(1, Translate("ui.BlendMapGenerator.surface")); MorphList.SetColumnTitle(2, Translate("ui.BlendMapGenerator.status")); MorphList.SetColumnTitle(3, Translate("ui.BlendMapGenerator.path")); MorphList.SetColumnTitlesVisible(true); FileDialog.CurrentDir = "res://"; var disposed = Disposed.Where(identity); IObservable <Option <DirectoryInfo> > ObserveDirectoryChange( Button button, LineEdit edit, // This is a horrible workaround for a problem that Popup.popup_hide never gets fired. IObservable <Unit> anotherButtonPressed) { Option <DirectoryInfo> Validate(string path) { var dir = new DirectoryInfo(path); return(dir.IsDirectory && dir.Exists ? Some(dir) : None); } var fromChooser = button.OnPress() .Do(_ => { FileDialog.Mode = ModeEnum.OpenDir; FileDialog.ShowModal(true); }) .Select(_ => FileDialog.OnSelectDirectory().Select(Some).TakeUntil(anotherButtonPressed)) .Switch() .Do(dir => edit.Text = dir.Map(v => v.Path).IfNone("")); var fromEdit = edit.OnTextChanged() .Select(Validate) .Do(dir => dir.Iter(v => FileDialog.CurrentDir = v.Path)); return(fromChooser.Merge(fromEdit)); } var onInputChange = ObserveDirectoryChange(InputButton, InputEdit, OutputButton.OnPress()); var onOutputChange = ObserveDirectoryChange(OutputButton, OutputEdit, InputButton.OnPress()); IObservable <Option <string> > ToErrorMessage(IObservable <Option <DirectoryInfo> > value, string msg) => value.StartWith(None).Select(v => v.IsSome ? None : Some(msg)); var message = Observable.CombineLatest( ToErrorMessage(onInputChange, Translate("error.invalid.directory.input")), ToErrorMessage(onOutputChange, Translate("error.invalid.directory.output")), (m1, m2) => m1.Concat(m2).HeadOrNone().IfNone("") ).Skip(1); message .TakeUntil(disposed) .Subscribe(m => InfoLabel.Text = m, this); var onDirectoryChange = Observable.CombineLatest( onInputChange.Select(v => v.ToObservable()).Switch(), onOutputChange.Select(v => v.ToObservable()).Switch(), (input, output) => new Paths(input, output)); var meshes = onDirectoryChange .Select(v => v.Input.Contents) .Select(FindMeshes) .Select(v => v.Cast <FileInfo>().Freeze()); var meshSets = meshes.CombineLatest(onDirectoryChange, (files, paths) => (files, paths)) .Do(v => Logger.LogDebug("Searching for base meshes in '{}'.", v.paths.Input.Path)) .Select(v => v.files.Bind(f => MeshSet.TryCreate(f, v.paths, v.files, Logger))) .Select(v => v.Freeze()); var shownTasks = SourceList.OnItemSelect() .Select(v => v.Map(i => i.GetText(0))) .WithLatestFrom(meshSets, (key, s) => s.Find(v => v.Key == key).Bind(v => v.Tasks)); var valid = meshSets.Select(set => set.Bind(v => v.Tasks).Any(t => t.State != TaskState.UpToDate)); meshSets .Throttle(TimeSpan.FromSeconds(1)) .TakeUntil(disposed) .Do(_ => SourceList.RemoveAllNodes()) .Do(v => v.Iter(CreateNode)) .Do(_ => SourceList.GetRoot().Children().HeadOrNone().Iter(c => c.Select(0))) .Subscribe(this); shownTasks .TakeUntil(disposed) .Do(_ => MorphList.RemoveAllNodes()) .Subscribe(v => v.Iter(CreateNode), this); valid .TakeUntil(disposed) .Subscribe(v => StartButton.Disabled = !v, this); StartButton.OnPress() .WithLatestFrom(meshSets, (_, v) => v) .TakeUntil(disposed) .Subscribe(Start, this); CloseButton.OnPress() .TakeUntil(disposed) .Subscribe(_ => Quit(), this); }