private static void OnPlaceHolderControlChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var comboBox = sender as ComboBox;

            if (comboBox != null)
            {
                var control = e.NewValue as FrameworkElement;

                var disposables = new CompositeDisposable();

                var selectionChanged = Observable.FromEvent <SelectionChangedEventHandler, SelectionChangedEventArgs>
                                           (h => (s, ea) => h(ea),
                                           h => comboBox.SelectionChanged += h,
                                           h => comboBox.SelectionChanged -= h);

                selectionChanged
                .Select(x => x.AddedItems.Count <= 0 || string.IsNullOrWhiteSpace(x.AddedItems[0].ToString()))
                .Subscribe(x =>
                {
                    control.Visibility = VisibilityHelper.Set(x);
                })
                .AddTo(disposables);

                comboBox.UnloadedAsObservable()
                .Subscribe(_ => disposables?.Dispose())
                .AddTo(disposables);

                control.Visibility = VisibilityHelper.Set(string.IsNullOrWhiteSpace(comboBox.SelectionBoxItem.ToString()));
            }
        }
        private void RefreshVisibility()
        {
            var isGroup = this.Source?.IsGroup ?? false;
            var isOpen  = !this.IsMainClosed;

            this.FileCommonVisibility = VisibilityHelper.Set(!isGroup);
            this.FileMainVisibility   = VisibilityHelper.Set(!isGroup && isOpen);
            this.GroupVisibility      = VisibilityHelper.Set(isGroup);
            this.CommonMainVisibility = VisibilityHelper.Set(isGroup || isOpen);
        }
Beispiel #3
0
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var num = value as int?;

            if (num == null)
            {
                return(Visibility.Collapsed);
            }
            return(VisibilityHelper.Set(num.Value == 0));
        }
Beispiel #4
0
        private async void mikanImportButton_Loaded(object sender, RoutedEventArgs e)
        {
            if (!conpatButtonLoaded)
            {
                conpatButtonLoaded = true;
                var convertable = await this.Core.IsOldConvertableAsync();

                this.mikanImportButton.Visibility = VisibilityHelper.Set(convertable);
            }
        }
        private static void OnIsExifEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var thisInstance = d as FileInformationPage;
            var value        = e.NewValue as bool?;

            if (thisInstance != null && value.HasValue)
            {
                thisInstance.expandButtonGrid.Visibility = VisibilityHelper.Set(value.Value);
                if (!value.Value)
                {
                    thisInstance.IsMainClosed = false;
                }
            }
        }
Beispiel #6
0
        public KeyBindPageViewModel()
        {
            var core = ((App)Application.Current).Core;

            this.CursorKeyBind = core
                                 .ToReactivePropertyAsSynchronized(x => x.CursorKeyBind).AddTo(this.Disposables);

            this.CursorKeyToFlipVisibility = this.CursorKeyBind
                                             .Select(x => VisibilityHelper.Set(x != 1))
                                             .ToReactiveProperty().AddTo(this.Disposables);

            this.CursorKeyToMoveVisibility = this.CursorKeyBind
                                             .Select(x => VisibilityHelper.Set(x == 1))
                                             .ToReactiveProperty().AddTo(this.Disposables);
        }
        private static void OnPlaceHolderControlChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var textBox = sender as TextBox;

            if (textBox != null)
            {
                var control = e.NewValue as FrameworkElement;

                SubscribeEvents(textBox, x =>
                {
                    control.Visibility = VisibilityHelper.Set(x);
                });

                control.Visibility = VisibilityHelper.Set(string.IsNullOrEmpty(textBox.Text));
            }
        }
        private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var thisInstance = d as PopupDialog;
            var value        = e.NewValue as bool?;

            if (thisInstance != null && value.HasValue)
            {
                thisInstance.rootGrid.Visibility = VisibilityHelper.Set(value.Value);
                if (!value.Value)
                {
                    var content = thisInstance.mainContent.Content as FrameworkElement;

                    thisInstance.DialogContent = null;
                    //thisInstance.mainContent.Content = null;

                    if (content != null)
                    {
                        content.IsEnabled = false;
                    }

                    thisInstance.ClosedCommand?.Execute(thisInstance);
                }
            }
        }
        public ClientWindowViewModel()
        {
            var core    = ((App)Application.Current).Core;
            var library = core.Library;

            var client = new Client(new LibraryFront(library), core).AddTo(this.Disposables);

            this.Client = client;
            this.Core   = core;

            this.KeyReceiver = new KeyReceiver <object>().AddTo(this.Disposables);

            this.WindowTitle = client.SelectedPage
                               .CombineLatest(client.ViewerDisplaying, (Page, Item) => new { Page, Item })
                               .Select(x =>
            {
                var file = (x.Page == PageType.Viewer) ? x.Item?.FileName : null;
                return((file == null) ? core.AppName : (file + " - " + core.AppName));
            })
                               .ToReadOnlyReactiveProperty()
                               .AddTo(this.Disposables);

            this.SelectedInformationPage = new ReactiveProperty <OptionPaneType>
                                               (core.IsViewerPageLeftBarFixed ? OptionPaneType.ItemInfo : OptionPaneType.None)
                                           .AddTo(this.Disposables);

            this.IsPaneOpen = new ReactiveProperty <bool>(core.IsViewerPageLeftBarFixed)
                              .AddTo(this.Disposables);


            this.IsPaneFixed = core
                               .ToReactivePropertyAsSynchronized(x => x.IsViewerPageLeftBarFixed)
                               .AddTo(this.Disposables);

            this.SelectedTab = client.SelectedPage
                               .Select(x =>
            {
                switch (x)
                {
                case PageType.Search:
                    return(0);

                case PageType.Catalog:
                    return(1);

                case PageType.Viewer:
                    return(2);

                default:
                    return(0);
                }
            })
                               .ToReactiveProperty(0)
                               .AddTo(this.Disposables);


            this.SelectedTab.Subscribe(x =>
            {
                if (this.IsPaneOpen.Value)
                {
                    if (this.IsPaneFixed.Value)
                    {
                        this.ShowInformationPane();
                    }
                    else
                    {
                        this.IsPaneOpen.Value = false;
                    }
                }
            })
            .AddTo(this.Disposables);

            this.Client.FeaturedGroupChanged.Subscribe(x =>
            {
                if (client.SelectedPage.Value == PageType.Catalog && this.IsPaneOpen.Value)
                {
                    this.ShowInformationPane();
                }
            })
            .AddTo(this.Disposables);


            this.PaneSelectedPath = new ReactiveProperty <string>((string)null)
                                    .AddTo(this.Disposables);
            this.PaneSelectedPath.Where(x => !string.IsNullOrWhiteSpace(x))
            .Subscribe(x => this.StartPathOrTagSearch(FileProperty.DirectoryPathStartsWith, x))
            .AddTo(this.Disposables);

            this.PaneSelectedTag = new ReactiveProperty <TagInformation>((TagInformation)null)
                                   .AddTo(this.Disposables);
            this.PaneSelectedTag.Where(x => x != null)
            .Subscribe(x => this.StartPathOrTagSearch(FileProperty.ContainsTag, x.Id))
            .AddTo(this.Disposables);

            this.DefaultPaneMode = client.SelectedPage
                                   .Select(x => (x == PageType.Viewer) ? PaneMode.HideInClosing
                    : PaneMode.AlwaysVisible)
                                   .ToReactiveProperty(PaneMode.AlwaysVisible)
                                   .AddTo(this.Disposables);



            this.IsOptionPageOpen = this.SelectedInformationPage
                                    .Select(x => x > 0)
                                    .ToReactiveProperty()
                                    .AddTo(this.Disposables);


            //情報
            this.IsInformationPaneOpen = this.SelectedInformationPage
                                         .Select(x => this.IsInformationPane(x))
                                         .ToReactiveProperty(false)
                                         .AddTo(this.Disposables);

            this.OpenInformationPaneCommand = new ReactiveCommand()
                                              .WithSubscribe(_ =>
            {
                if (this.IsInformationPaneOpen.Value)
                {
                    if (this.prevPaneSelected == OptionPaneType.None)
                    {
                        this.prevPaneSelected = OptionPaneType.NoInformation;
                    }
                    this.ShowInformationPane(true);
                }
                else
                {
                    if (this.SelectedInformationPage.Value != OptionPaneType.Setting)
                    {
                        this.SelectedInformationPage.Value = OptionPaneType.None;
                    }
                }
            }, this.Disposables);



            //設定
            this.IsSettingPaneOpen = this.SelectedInformationPage
                                     .Select(x => x == OptionPaneType.Setting)
                                     .ToReactiveProperty(false)
                                     .AddTo(this.Disposables);

            this.OpenSettingPaneCommand = new ReactiveCommand()
                                          .WithSubscribe(_ =>
            {
                if (this.IsSettingPaneOpen.Value)
                {
                    this.SelectedInformationPage.Value = OptionPaneType.Setting;
                    this.IsPaneOpen.Value = true;
                }
                else
                {
                    if (this.SelectedInformationPage.Value == OptionPaneType.Setting)
                    {
                        this.SelectedInformationPage.Value = OptionPaneType.None;
                    }
                }
            }, this.Disposables);



            //ヘルプ
            this.IsHelpPaneOpen = this.SelectedInformationPage
                                  .Select(x => x == OptionPaneType.Help)
                                  .ToReactiveProperty(false)
                                  .AddTo(this.Disposables);

            this.OpenHelpPaneCommand = new ReactiveCommand()
                                       .WithSubscribe(_ =>
            {
                if (this.IsHelpPaneOpen.Value)
                {
                    this.SelectedInformationPage.Value = OptionPaneType.Help;
                    this.IsPaneOpen.Value = true;
                }
                else
                {
                    if (this.SelectedInformationPage.Value == OptionPaneType.Help)
                    {
                        this.SelectedInformationPage.Value = OptionPaneType.None;
                    }
                }
            }, this.Disposables);



            this.OptionPaneVisibility = this.SelectedInformationPage
                                        .Select(x => VisibilityHelper.Set(x > 0))
                                        .ToReactiveProperty()
                                        .AddTo(this.Disposables);

            this.FrameWidth = new ReactiveProperty <double>(300).AddTo(this.Disposables);

            this.IsFullScreen = client.SelectedPage.Select(_ => false).ToReactiveProperty().AddTo(this.Disposables);

            this.PageChangedSubject = new Subject <SplitViewDisplayMode>().AddTo(this.Disposables);

            this.PaneDisplayMode = this.IsPaneFixed
                                   .CombineLatest(this.DefaultPaneMode,
                                                  (paneFixed, defaultMode) =>
                                                  (defaultMode == PaneMode.Disabled) ? SplitViewDisplayMode.Overlay
                    : (paneFixed) ? SplitViewDisplayMode.CompactInline
                    : (defaultMode == PaneMode.HideInClosing) ? SplitViewDisplayMode.Overlay
                    : SplitViewDisplayMode.CompactOverlay)
                                   .ToReactiveProperty()
                                   .AddTo(this.Disposables);

            this.IsPaneOpen
            .Subscribe(x =>
            {
                if (!x)
                {
                    this.IsPaneFixed.Value             = false;
                    this.SelectedInformationPage.Value = OptionPaneType.None;
                    if (this.PaneDisplayMode.Value == SplitViewDisplayMode.CompactInline)
                    {
                        this.PaneDisplayMode.Value = SplitViewDisplayMode.CompactOverlay;
                    }
                }
            })
            .AddTo(this.Disposables);


            this.PaneOpenButtonVisibility = new ReactiveProperty <Visibility>(Visibility.Collapsed)
                                            .ToReactiveProperty()
                                            .AddTo(this.Disposables);

            var isWide = this.FrameWidth.Select(y => y > middleWindowWidth).Publish().RefCount();

            this.PaneFixButtonVisibility = isWide.Select(y => VisibilityHelper.Set(y))
                                           .ToReactiveProperty().AddTo(this.Disposables);
            isWide.Where(y => !y).Skip(2).Subscribe(y => this.IsPaneFixed.Value = false).AddTo(this.Disposables);

            this.JumpListWidth = this.IsOptionPageOpen.Select(x => x ? compactPaneWidth : openPaneWidth)
                                 .ToReactiveProperty().AddTo(this.Disposables);

            this.IsOptionPageOpen.Subscribe(x =>
            {
                if (x && this.SelectedInformationPage.Value != OptionPaneType.NoInformation &&
                    !core.IsAutoInformationPaneDisabled)
                {
                    this.IsPaneOpen.Value = true;
                }
            }).AddTo(this.Disposables);



            this.OpenSettingWindowCommand = new ReactiveCommand()
                                            .WithSubscribe(_ => ((App)Application.Current).ShowSettingWindow(-1), this.Disposables);

            this.OptionPageCommand = new ReactiveCommand <string>().AddTo(this.Disposables);



            this.IsPopupOpen = new ReactiveProperty <bool>(false).AddTo(this.Disposables);

            this.IsPopupOpen
            .Subscribe(x => this.KeyReceiver.Mode
                           = (int)(x ? KeyReceiverMode.PopupIsOpened : KeyReceiverMode.Normal))
            .AddTo(this.Disposables);



            this.prevPaneMode     = this.PaneDisplayMode.Value;
            this.prevPaneOpen     = this.IsPaneOpen.Value;
            this.prevPaneSelected = (OptionPaneType)this.SelectedInformationPage.Value;

            this.SelectedItems.ObserveProperty(x => x.Count).Pairwise().Subscribe(x =>
            {
                var autoOpen = !core.IsAutoInformationPaneDisabled;

                if (x.OldItem <= 0 && x.NewItem > 0)
                {
                    this.prevPaneMode     = this.PaneDisplayMode.Value;
                    this.prevPaneOpen     = this.IsPaneOpen.Value;
                    this.prevPaneSelected = (OptionPaneType)this.SelectedInformationPage.Value;

                    if (autoOpen && this.FrameWidth.Value > wideWindowWidth)
                    {
                        this.PaneDisplayMode.Value = SplitViewDisplayMode.CompactInline;
                        this.IsPaneOpen.Value      = true;
                    }

                    this.ShowInformationPane();
                }
                else if (x.OldItem > 0 && x.NewItem > 0 &&
                         (this.FrameWidth.Value > wideWindowWidth || this.IsPaneOpen.Value))
                {
                    this.ShowInformationPane();
                }
                else if (x.OldItem > 0 && x.NewItem <= 0)
                {
                    if (autoOpen)
                    {
                        this.PaneDisplayMode.Value = this.prevPaneMode;
                    }

                    this.ShowInformationPane();

                    if (autoOpen)
                    {
                        this.IsPaneOpen.Value = this.prevPaneOpen;
                    }
                }
            })
            .AddTo(this.Disposables);


            this.IsPaneFixed
            .Subscribe(x =>
            {
                if (x)
                {
                    this.prevPaneMode = SplitViewDisplayMode.CompactInline;
                    this.prevPaneOpen = true;
                }
                else
                {
                    this.prevPaneMode = SplitViewDisplayMode.CompactOverlay;
                    this.prevPaneOpen = false;
                }
            })
            .AddTo(this.Disposables);

            this.TagSelectorSortMode = core
                                       .ToReactivePropertyAsSynchronized(x => x.TagSelectorSortMode)
                                       .AddTo(this.Disposables);

            this.ExifVisibilityCheck = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.ExifVisibilityCheck
            .Skip(1)
            .Subscribe(x => core.Library.ExifManager.EnableAll(x)).AddTo(this.Disposables);

            this.IsExifEnabled = core.Library.ExifManager.HasVisibleItem
                                 .ToReadOnlyReactiveProperty().AddTo(this.Disposables);


            this.BackCommand = client.BackHistoryCount
                               .Select(x => x > 0)
                               .ToReactiveCommand()
                               .WithSubscribe(_ => client.Back(), this.Disposables);

            this.MoveToSearchPageCommand = new ReactiveCommand()
                                           .WithSubscribe(x => client.MoveToSearch(), this.Disposables);

            this.OpenPaneCommand = new ReactiveCommand()
                                   .WithSubscribe(_ => this.TogglePane(OptionPaneType.None), this.Disposables);

            // ウインドウへのファイルのドラッグ&ドロップ
            this.FileDropCommand = new ReactiveCommand()
                                   .WithSubscribe(obj =>
            {
                var files = obj as string[];
                if (files != null)
                {
                    this.Client.ActivateFiles(files);
                }
            }, this.Disposables);

            this.MouseExButtonSubject = new Subject <bool>().AddTo(this.Disposables);

            this.MouseExButtonLeftCommand = new ReactiveCommand()
                                            .WithSubscribe(_ =>
            {
                if (core.UseExtendedMouseButtonsToSwitchImage &&
                    client.SelectedPage.Value == PageType.Viewer)
                {
                    this.MouseExButtonSubject.OnNext(false);
                }
                else
                {
                    client.Back();
                }
            }, this.Disposables);

            this.MouseExButtonRightCommand = new ReactiveCommand()
                                             .WithSubscribe(_ =>
            {
                if (core.UseExtendedMouseButtonsToSwitchImage &&
                    client.SelectedPage.Value == PageType.Viewer)
                {
                    this.MouseExButtonSubject.OnNext(true);
                }
                else
                {
                    client.Forward();
                }
            }, this.Disposables);


            //Keyboard
            this.RegisterKeyReceiver(client);

            this.Catalog = new CatalogPageViewModel(this).AddTo(this.Disposables);
            this.Viewer  = new ViewerPageViewModel(this).AddTo(this.Disposables);
            this.Search  = new SearchPageViewModel(this).AddTo(this.Disposables);
        }
        public EditSearchViewModel(ISqlSearch source)
        {
            var core = ((App)Application.Current).Core;

            this.library  = core.Library;
            this.settings = core;

            this.unsubscribers = new CompositeDisposable();


            this.PropertyList = FilePropertyManager.GetPropertyListToSearch()
                                .Select(x => new KeyValuePair <string, PropertyContainer>(x.Key, new PropertyContainer(x.Value)))
                                .ToList();

            if (!source.IsUnit)
            {
                this.PropertyList.Add
                    (new KeyValuePair <string, PropertyContainer>
                        (settings.GetResourceString("MatchAll"), new PropertyContainer(ComplexMode.And)));
                this.PropertyList.Add
                    (new KeyValuePair <string, PropertyContainer>
                        (settings.GetResourceString("MatchAny"), new PropertyContainer(ComplexMode.Or)));
            }

            this.PropertyComboBoxDefault = settings.GetResourceString("Property");
            this.TagComboBoxDefault      = settings.GetResourceString("Tag");


            this.CompareOperator = new List <KeyValuePair <string, CompareMode> >();
            this.AddCompareSymbol(CompareMode.Great);
            this.AddCompareSymbol(CompareMode.GreatEqual);
            this.AddCompareSymbol(CompareMode.Equal);
            this.AddCompareSymbol(CompareMode.LessEqual);
            this.AddCompareSymbol(CompareMode.Less);
            this.AddCompareSymbol(CompareMode.NotEqual);

            this.EqualitySelector = new ObservableCollection <string>()
            {
                "", ""
            };


            this.isSVO          = settings.IsSVOLanguage;
            this.BelowRefString = settings.GetResourceString("BelowRef");
            this.IsVString      = settings.GetResourceString("IsV");

            this.SourceItem = source;

            var unit = source.IsUnit ? (UnitSearch)source : null;

            this.Init(unit);


            this.IsEditing = new ReactiveProperty <bool>(true).AddTo(this.unsubscribers);

            this.OkCommand = this.PropertyListSelectedIndex
                             .Select(x => x >= 0)
                             .ToReactiveCommand()
                             .WithSubscribe(_ =>
            {
                this.Commit();
                this.IsEditing.Value = false;
            }, this.unsubscribers);
            this.CancelCommand = new ReactiveCommand()
                                 .WithSubscribe(_ => this.IsEditing.Value = false, this.unsubscribers);


            var propertyObserver = this.PropertyListSelectedIndex
                                   .Select(x =>
            {
                var container = this.GetProperty(x);
                return(new
                {
                    Property = container.Property,
                    Enable = (container.Complex == ComplexMode.None &&
                              container.IsValid)
                });
            })
                                   .Publish().RefCount();

            this.CompareListVisibility = propertyObserver
                                         .Select(x => VisibilityHelper.Set(x.Enable && x.Property.IsComperable()))
                                         .ToReactiveProperty().AddTo(this.unsubscribers);

            this.EqualityListVisibility = propertyObserver
                                          .Select(x => VisibilityHelper.Set(x.Enable && !x.Property.IsComperable()))
                                          .ToReactiveProperty().AddTo(this.unsubscribers);

            this.NumericTextVisibility = propertyObserver
                                         .Select(x => VisibilityHelper.Set(x.Enable && x.Property.IsInteger()))
                                         .ToReactiveProperty().AddTo(this.unsubscribers);

            this.FloatTextVisibility = propertyObserver
                                       .Select(x => VisibilityHelper.Set(x.Enable && x.Property.IsFloat()))
                                       .ToReactiveProperty().AddTo(this.unsubscribers);

            this.DirectoryListVisibility = propertyObserver
                                           .Select(x => VisibilityHelper.Set(x.Enable && x.Property == FileProperty.DirectoryPathStartsWith))
                                           .ToReactiveProperty().AddTo(this.unsubscribers);

            this.TagListVisibility = propertyObserver
                                     .Select(x => VisibilityHelper.Set(x.Enable && x.Property == FileProperty.ContainsTag))
                                     .ToReactiveProperty().AddTo(this.unsubscribers);

            this.TextBoxVisibility = propertyObserver
                                     .Select(x => VisibilityHelper.Set(x.Enable && x.Property.IsText()))
                                     .ToReactiveProperty().AddTo(this.unsubscribers);

            this.DateVisibility = propertyObserver
                                  .Select(x => VisibilityHelper.Set(x.Enable && x.Property.IsDate()))
                                  .ToReactiveProperty().AddTo(this.unsubscribers);

            this.IsVStringVisibility = propertyObserver
                                       .Select(x => VisibilityHelper.Set(x.Enable && !this.isSVO))
                                       .ToReactiveProperty().AddTo(this.unsubscribers);

            this.PropertyComboBoxDefaultVisibility = this.PropertyListSelectedIndex
                                                     .Select(x => VisibilityHelper.Set(x < 0))
                                                     .ToReactiveProperty()
                                                     .AddTo(this.unsubscribers);

            this.TagComboBoxDefaultVisibility
                = new[]
                {
                this.TagListSelectedIndex.Select(x => x < 0),
                propertyObserver.Select(x => x.Enable && x.Property == FileProperty.ContainsTag)
                }
            .CombineLatestValuesAreAllTrue()
            .Select(x => VisibilityHelper.Set(x))
            .ToReactiveProperty()
            .AddTo(this.unsubscribers);


            propertyObserver.Subscribe(x =>
            {
                if (x.Enable)
                {
                    var currentIndex = this.EqualitySelectedIndex.Value;
                    this.EqualitySelector[this.GetEqualitySelectorIndex(true)]
                        = x.Property.GetEqualityLabel(true);
                    this.EqualitySelector[this.GetEqualitySelectorIndex(false)]
                        = x.Property.GetEqualityLabel(false);
                    this.EqualitySelectedIndex.Value = currentIndex;
                }
            }).AddTo(this.unsubscribers);


            this.PropertyListSelectedIndex.Value =
                unit == null
                ? -1
                : this.PropertyList.FindIndex(x => x.Value.Property == unit.Property);
        }
        public CatalogPageViewModel(ClientWindowViewModel parent)
        {
            this.parent  = parent;
            this.client  = parent.Client;
            this.library = parent.Library;
            var core = parent.Core;

            this.Length = client.Length.ToReadOnlyReactiveProperty().AddTo(this.Disposables);

            this.IsInSelecting = this.client.SelectedItemsCount
                                 .Select(x => x > 0)
                                 .ToReadOnlyReactiveProperty()
                                 .AddTo(this.Disposables);

            //表示中のインデックス
            this.StartIndex = this.client
                              .CatalogIndex
                              .Select(x => (x < int.MaxValue) ? (int)x : int.MaxValue)
                              .ToReactiveProperty()
                              .AddTo(this.Disposables);

            this.StartIndex
            .Subscribe(x => this.client.CatalogIndex.Value = x)
            .AddTo(this.Disposables);

            this.DisplayIndex = this.StartIndex.Select(x => x + 1).ToReactiveProperty().AddTo(this.Disposables);
            this.DisplayIndex.Subscribe(x => this.StartIndex.Value = x - 1).AddTo(this.Disposables);

            this.ThumbnailSize = core.ObserveProperty(x => x.ThumbNailSize)
                                 .Select(x => (double)x)
                                 .ToReactiveProperty().AddTo(this.Disposables);

            this.ThumbnailViewSize = this.ThumbnailSize
                                     .Select(x => new Size(x, x))
                                     .ToReadOnlyReactiveProperty()
                                     .AddTo(this.Disposables);

            this.ImagePropertiesVisibility = this.ThumbnailSize
                                             .Select(x => VisibilityHelper.Set(x > 128)).ToReactiveProperty().AddTo(this.Disposables);

            this.ThumbnailMargin = this.ThumbnailSize
                                   .Select(x => new Thickness((x < 128) ? 1 : (x < 256) ? 2 : 4))
                                   .ToReactiveProperty().AddTo(this.Disposables);

            this.IsRefreshEnabled = this.client.IsStateChanging
                                    .Select(x => !x)
                                    .ToReadOnlyReactiveProperty()
                                    .AddTo(this.Disposables);

            this.IsRenderingEnabled = this.client.IsCatalogRenderingEnabled
                                      .CombineLatest(this.client.SelectedPage, (e, p) => e && p == PageType.Catalog)
                                      .ToReadOnlyReactiveProperty(true)
                                      .AddTo(this.Disposables);


            //戻ってきたときにサムネイル再読み込み
            client.BackHistoryCount
            .Pairwise()
            .CombineLatest(client.SelectedPage,
                           (history, page) => history.OldItem > history.NewItem && page == PageType.Catalog)
            .Where(x => x)
            .Subscribe(_ => this.RefreshTrigger = !this.RefreshTrigger)
            .AddTo(this.Disposables);

            client.CacheUpdated
            .SkipUntil(client.StateChanged)
            .Take(1)
            .Repeat()
            .Subscribe(_ => this.RefreshTrigger = !this.RefreshTrigger)
            .AddTo(this.Disposables);


            //スクロールが落ち着いたら再読み込み
            this.StartIndex
            .Throttle(TimeSpan.FromMilliseconds(3000))
            .ObserveOnUIDispatcher()
            .Subscribe(_ => this.RefreshTrigger = !this.RefreshTrigger)
            .AddTo(this.Disposables);

            //スクロール位置復元
            this.client.CatalogScrollIndex
            .Subscribe(x => this.ScrollToIndexAction?.Invoke((int)x))
            .AddTo(this.Disposables);

            //サムネイルクリック
            this.ItemClickCommand = new ReactiveCommand()
                                    .WithSubscribe(context => this.SelectOrShow(context, true), this.Disposables);

            //選択
            this.ItemSelectCommand = new ReactiveCommand()
                                     .WithSubscribe(context => this.SelectOrShow(context, false), this.Disposables);

            //ソート条件編集
            this.EditSortCommand = new ReactiveCommand()
                                   .WithSubscribe(x =>
            {
                var control = x as FrameworkElement;

                var content = new SortEditor()
                {
                    ItemsSource = this.client.GetSort(),
                };

                content.IsEnabledChanged += (o, e) =>
                {
                    var value = e.NewValue as bool?;
                    if (value.HasValue && !value.Value)
                    {
                        this.client.SetSort(content.SortSettings);
                    }
                };

                this.parent.PopupOwner.PopupDialog.Show(content,
                                                        new Thickness(double.NaN, 10.0, 0.0, double.NaN),
                                                        HorizontalAlignment.Right, VerticalAlignment.Bottom, control);
            }, this.Disposables);

            //すべて選択
            this.SelectAllCommand = new ReactiveCommand()
                                    .WithSubscribe(async _ => await this.client.SelectAllAsync(), this.Disposables);

            //選択をクリア
            this.SelectionClearCommand = this.IsInSelecting
                                         .ToReactiveCommand()
                                         .WithSubscribe(_ => this.SelectedItems.Clear(), this.Disposables);

            //グループ化
            this.GroupingCommand = this.client.SelectedItemsCount
                                   .CombineLatest(this.client.IsGroupMode, (c, g) => c > 1 && !g)
                                   .ToReactiveCommand()
                                   .WithSubscribe(_ => this.client.Grouping(), this.Disposables);

            //グループから退去
            this.RemoveFromGroupCommand = this.client.SelectedItemsCount
                                          .CombineLatest(this.client.IsGroupMode, (c, g) => c >= 1 && g)
                                          .ToReactiveCommand()
                                          .WithSubscribe(_ => this.client.RemoveFromGroup(), this.Disposables);

            this.SetToLeaderCommand = this.client.SelectedItemsCount
                                      .CombineLatest(this.client.IsGroupMode, (c, g) => c == 1 && g)
                                      .ToReactiveCommand()
                                      .WithSubscribe(_ => this.client.SetGroupLeader(), this.Disposables);

            this.RefreshCommand = new ReactiveCommand()
                                  .WithSubscribe(_ => this.client.Refresh(), this.Disposables);

            this.RegisterKeyReceiver(parent);
        }
Beispiel #12
0
        public ViewerPageViewModel(ClientWindowViewModel parent)
        {
            this.parent = parent;
            this.client = parent.Client;

            this.library = parent.Library;

            this.DisplayIndex = client.ViewerIndex
                                .Select(x => x + 1)
                                .ToReactiveProperty()
                                .AddTo(this.Disposables);

            this.DisplayIndex.Subscribe(x =>
            {
                client.ViewerIndex.Value = x - 1;
            })
            .AddTo(this.Disposables);

            this.Length = client.Length.ToReadOnlyReactiveProperty().AddTo(this.Disposables);

            this.randomNumber = new RandomNumber();
            this.IsRandom     = parent.Core
                                .ToReactivePropertyAsSynchronized(x => x.IsSlideshowRandom).AddTo(this.Disposables);

            this.IsRandom.Select(_ => Unit.Default)
            .Merge(this.Length.Select(_ => Unit.Default))
            .Subscribe(x =>
            {
                if (this.IsRandom.Value && this.Length.Value > 0)
                {
                    this.randomNumber.Length = (int)this.Length.Value;
                    this.randomNumber.Clear();
                    this.client.PrepareNext(this.randomNumber.GetNext());
                }
            })
            .AddTo(this.Disposables);

            this.client.ViewerCacheClearedTrigger
            .Subscribe(x =>
            {
                if (this.IsRandom.Value && this.Length.Value > 0)
                {
                    this.client.PrepareNext(this.randomNumber.GetNext());
                }
            })
            .AddTo(this.Disposables);



            this.ZoomFactor        = new ReactiveProperty <double>().AddTo(this.Disposables);
            this.DesiredZoomFactor = new ReactiveProperty <double>(0.0).AddTo(this.Disposables);

            this.CurrentZoomFactorPercent = this.ZoomFactor
                                            .Select(x => x * 100.0)
                                            .ToReactiveProperty()
                                            .AddTo(this.Disposables);

            this.DisplayZoomFactor = this.CurrentZoomFactorPercent.ToReactiveProperty().AddTo(this.Disposables);

            this.DisplayZoomFactor.Where(x => x != this.CurrentZoomFactorPercent.Value)
            .Subscribe(x => this.ChangeZoomFactor(x / 100.0))
            .AddTo(this.Disposables);

            this.UsePhysicalPixel = parent.Core
                                    .ObserveProperty(x => x.UseLogicalPixel)
                                    .Select(x => !x)
                                    .ToReadOnlyReactiveProperty()
                                    .AddTo(this.Disposables);

            this.ScalingMode = parent.Core
                               .ObserveProperty(x => x.ScalingMode)
                               .ToReadOnlyReactiveProperty()
                               .AddTo(this.Disposables);

            this.IsImageChanging = new ReactiveProperty <bool>().AddTo(this.Disposables);

            //拡大率表示ポップアップ
            this.ZoomFactorVisibility = this.ZoomFactor.Select(x => true)
                                        .Merge(this.ZoomFactor.Throttle(TimeSpan.FromMilliseconds(zoomFactorDisplayTime)).Select(x => false))
                                        .Where(x => !this.IsImageChanging.Value)
                                        .Merge(this.IsImageChanging.Where(x => x).Select(x => !x))
                                        .Select(x => VisibilityHelper.Set(x))
                                        .ToReactiveProperty(Visibility.Collapsed)
                                        .AddTo(this.Disposables);

            this.IsGifAnimationEnabled = parent.Core
                                         .ToReactivePropertyAsSynchronized(x => x.IsAnimatedGifEnabled)
                                         .AddTo(this.Disposables);


            this.IsFill = parent.Core
                          .ObserveProperty(x => x.IsSlideshowResizeToFill)
                          .ToReadOnlyReactiveProperty()
                          .AddTo(this.Disposables);

            this.IsZoomoutOnly = parent.Core
                                 .ObserveProperty(x => x.IsSlideshowResizingAlways)
                                 .Select(x => !x)
                                 .ToReadOnlyReactiveProperty()
                                 .AddTo(this.Disposables);

            parent.MouseExButtonPressed
            .Subscribe(x =>
            {
                if (parent.Core.UseExtendedMouseButtonsToSwitchImage &&
                    client.SelectedPage.Value == PageType.Viewer)
                {
                    if (x)
                    {
                        this.MoveRight();
                    }
                    else
                    {
                        this.MoveLeft();
                    }
                }
            })
            .AddTo(this.Disposables);



            this.ViewWidth = new ReactiveProperty <double>().AddTo(this.Disposables);
            this.ViewWidth.Subscribe(x => client.ViewWidth = x).AddTo(this.Disposables);
            this.ViewHeight = new ReactiveProperty <double>().AddTo(this.Disposables);
            this.ViewHeight.Subscribe(x => client.ViewHeight = x).AddTo(this.Disposables);

            this.IsInHorizontalMirror = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.IsInVerticalMirror   = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.IsAutoScalingEnabled = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.Orientation          = new ReactiveProperty <int>().AddTo(this.Disposables);

            this.IsScrollRequested = new ReactiveProperty <bool>().AddTo(this.Disposables);

            this.IsTopBarOpen  = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.IsTopBarFixed = parent.Core
                                 .ToReactivePropertyAsSynchronized(x => x.IsViewerPageTopBarFixed)
                                 .AddTo(this.Disposables);
            if (this.IsTopBarFixed.Value)
            {
                this.IsTopBarOpen.Value = true;
            }

            this.OpenPaneCommand = new ReactiveCommand()
                                   .WithSubscribe(_ => parent.TogglePane(OptionPaneType.ItemInfo), this.Disposables);

            this.TogglePaneCommand = new ReactiveCommand()
                                     .WithSubscribe(_ => this.TogglePane(), this.Disposables);

            this.TapCommand = new ReactiveCommand().AddTo(this.Disposables);

            var tapped = this.TapCommand.OfType <ViewerTapEventArgs>().Publish().RefCount();

            tapped
            .Subscribe(e =>
            {
                if (e.HolizontalRate < edgeTapThreshold)
                {
                    this.MoveLeft();
                }
                else if (e.HolizontalRate > (1.0 - edgeTapThreshold))
                {
                    this.MoveRight();
                }
            })
            .AddTo(this.Disposables);

            tapped
            .Where(_ => parent.Core.IsOpenNavigationWithSingleTapEnabled)
            .Throttle(TimeSpan.FromMilliseconds(500))
            .Subscribe(e =>
            {
                if (e.Count == 1 &&
                    parent.Core.IsOpenNavigationWithSingleTapEnabled &&
                    e.HolizontalRate >= edgeTapThreshold &&
                    e.HolizontalRate <= (1.0 - edgeTapThreshold) &&
                    (!this.IsTopBarFixed.Value || !this.IsTopBarOpen.Value))
                {
                    this.IsTopBarOpen.Toggle();
                }
            })
            .AddTo(this.Disposables);


            this.PointerMoveCommand = new ReactiveCommand()
                                      .WithSubscribe(x =>
            {
                var y = ((Point)x).Y;

                if (y < 100)
                {
                    this.IsTopBarOpen.Value    = true;
                    this.topBarOpenedByPointer = true;
                }
                else if (y > 150)
                {
                    if (this.topBarOpenedByPointer && !this.IsTopBarFixed.Value)
                    {
                        this.IsTopBarOpen.Value = false;
                    }
                    this.topBarOpenedByPointer = false;
                }
            }, this.Disposables);


            this.BackCommand = client.BackHistoryCount
                               .Select(x => x > 0)
                               .ToReactiveCommand()
                               .WithSubscribe(_ => client.Back(), this.Disposables);

            this.SplitViewButtonVisibility = parent.IsPaneFixed
                                             .Select(x => VisibilityHelper.Set(!x))
                                             .ToReactiveProperty()
                                             .AddTo(this.Disposables);

            this.IsSlideshowPlaying = this.client.SelectedPage
                                      .Select(_ => false)
                                      .ToReactiveProperty(false)
                                      .AddTo(this.Disposables);

            this.IsSlideshowPlaying.Subscribe(x =>
            {
                if (x)
                {
                    this.StartSlideShow();
                }
                else
                {
                    this.parent.IsFullScreen.Value = false;
                }
            })
            .AddTo(this.Disposables);

            this.SlideshowSubject = new Subject <Unit>().AddTo(this.Disposables);

            var slideshowSubscription = new SerialDisposable().AddTo(this.Disposables);

            this.parent.Core.ObserveProperty(x => x.SlideshowFlipTimeMillisec)
            .Subscribe(x =>
            {
                slideshowSubscription.Disposable = this.SlideshowSubject
                                                   .Throttle(TimeSpan.FromMilliseconds(x))
                                                   .Where(_ => this.IsSlideshowPlaying.Value)
                                                   .ObserveOnUIDispatcher()
                                                   .Subscribe(y =>
                {
                    if (this.IsSlideshowPlaying.Value)
                    {
                        this.MoveNext();
                    }
                });

                if (this.IsSlideshowPlaying.Value)
                {
                    this.SlideshowSubject.OnNext(Unit.Default);
                }
            })
            .AddTo(this.Disposables);



            // Transform Dialog

            this.IsTransformDialogEnabled = new ReactiveProperty <bool>(true).AddTo(this.Disposables);

            this.VerticalMirrorCommand = new ReactiveCommand()
                                         .WithSubscribe(_ => { this.VerticalMirror(); this.HidePopup(); }, this.Disposables);
            this.HorizontalMirrorCommand = new ReactiveCommand()
                                           .WithSubscribe(_ => { this.HorizontalMirror(); this.HidePopup(); }, this.Disposables);
            this.RotateCwCommand = new ReactiveCommand()
                                   .WithSubscribe(_ => { this.Rotate(1); this.HidePopup(); }, this.Disposables);
            this.RotateCcwCommand = new ReactiveCommand()
                                    .WithSubscribe(_ => { this.Rotate(-1); this.HidePopup(); }, this.Disposables);

            this.MoveToGroupCommand = this.Record.Select(x => x?.IsGroup ?? false).ToReactiveCommand()
                                      .WithSubscribe(_ => this.client.DisplayGroup(0), this.Disposables);

            this.CheckHorizontalScrollRequestFunction = () =>
            {
                var k = this.CheckKeyboardScrollModifier();

                return((Keyboard.IsKeyDown(Key.Right)) ? k
                    : (Keyboard.IsKeyDown(Key.Left)) ? -k
                    : 0);
            };

            this.CheckVerticalScrollRequestFunction = () =>
            {
                var k = this.CheckKeyboardScrollModifier();

                return((Keyboard.IsKeyDown(Key.Down)) ? k
                    : (Keyboard.IsKeyDown(Key.Up)) ? -k
                    : 0);
            };

            this.TopBarWheelAction = (o, e) =>
            {
                if (e.Delta > 0)
                {
                    this.MovePrev();
                }
                else if (e.Delta < 0)
                {
                    this.MoveNext();
                }
            };


            //画像変更ボタン
            this.MoveButtonVisibility = parent.Core
                                        .ObserveProperty(x => x.IsViewerMoveButtonDisabled)
                                        .Select(x => VisibilityHelper.Set(!x))
                                        .ToReadOnlyReactiveProperty()
                                        .AddTo(this.Disposables);


            this.IsLeftButtonEnter    = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.IsRightButtonEnter   = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.IsLeftButtonPressed  = new ReactiveProperty <bool>(false).AddTo(this.Disposables);
            this.IsRightButtonPressed = new ReactiveProperty <bool>(false).AddTo(this.Disposables);

            this.PointerMoveAction = (o, e) =>
            {
                if (this.IsDisposed)
                {
                    return;
                }
                var element = o as FrameworkElement;
                if (element == null)
                {
                    return;
                }
                var point = (Vector)e.GetPosition(element) / element.ActualWidth;

                if (point.X < edgeTapThreshold)
                {
                    this.IsLeftButtonEnter.Value = true;
                }
                else
                {
                    this.IsLeftButtonEnter.Value   = false;
                    this.IsLeftButtonPressed.Value = false;
                }
                if (point.X > (1.0 - edgeTapThreshold))
                {
                    this.IsRightButtonEnter.Value = true;
                }
                else
                {
                    this.IsRightButtonEnter.Value   = false;
                    this.IsRightButtonPressed.Value = false;
                }
            };
            this.PointerLeaveAction = (o, e) =>
            {
                if (this.IsDisposed)
                {
                    return;
                }
                this.IsLeftButtonEnter.Value    = false;
                this.IsRightButtonEnter.Value   = false;
                this.IsLeftButtonPressed.Value  = false;
                this.IsRightButtonPressed.Value = false;
            };
            this.PointerDownAction = (o, e) =>
            {
                if (this.IsDisposed)
                {
                    return;
                }
                var element = o as FrameworkElement;
                if (element == null)
                {
                    return;
                }
                var point = (Vector)e.GetPosition(element) / element.ActualWidth;

                this.IsLeftButtonPressed.Value  = point.X < edgeTapThreshold;
                this.IsRightButtonPressed.Value = point.X > (1.0 - edgeTapThreshold);
            };
            this.PointerUpAction = (o, e) =>
            {
                if (this.IsDisposed)
                {
                    return;
                }
                this.IsLeftButtonPressed.Value  = false;
                this.IsRightButtonPressed.Value = false;
            };

            //キーボード操作
            this.RegisterKeyReceiver(parent);
        }