mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Rework nexus logins to use windows
This commit is contained in:
parent
87f8d8ff24
commit
1032e2554b
@ -48,7 +48,7 @@ namespace Wabbajack
|
||||
services.AddOSIntegrated();
|
||||
|
||||
services.AddSingleton<CefService>();
|
||||
services.AddSingleton<IUserInterventionHandler, InteventionHandler>();
|
||||
services.AddSingleton<IUserInterventionHandler, UserInteventionHandler>();
|
||||
|
||||
services.AddTransient<MainWindow>();
|
||||
services.AddTransient<MainWindowVM>();
|
||||
|
@ -1,282 +0,0 @@
|
||||
// TabContent.cs, version 1.2
|
||||
// The code in this file is Copyright (c) Ivan Krivyakov
|
||||
// See http://www.ikriv.com/legal.php for more information
|
||||
//
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace IKriv.Windows.Controls.Behaviors
|
||||
{
|
||||
/// <summary>
|
||||
/// Attached properties for persistent tab control
|
||||
/// </summary>
|
||||
/// <remarks>By default WPF TabControl bound to an ItemsSource destroys visual state of invisible tabs.
|
||||
/// Set ikriv:TabContent.IsCached="True" to preserve visual state of each tab.
|
||||
/// </remarks>
|
||||
public static class TabContent
|
||||
{
|
||||
public static bool GetIsCached(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(IsCachedProperty);
|
||||
}
|
||||
|
||||
public static void SetIsCached(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(IsCachedProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether tab content is cached or not
|
||||
/// </summary>
|
||||
/// <remarks>When TabContent.IsCached is true, visual state of each tab is preserved (cached), even when the tab is hidden</remarks>
|
||||
public static readonly DependencyProperty IsCachedProperty =
|
||||
DependencyProperty.RegisterAttached("IsCached", typeof(bool), typeof(TabContent), new UIPropertyMetadata(false, OnIsCachedChanged));
|
||||
|
||||
|
||||
public static DataTemplate GetTemplate(DependencyObject obj)
|
||||
{
|
||||
return (DataTemplate)obj.GetValue(TemplateProperty);
|
||||
}
|
||||
|
||||
public static void SetTemplate(DependencyObject obj, DataTemplate value)
|
||||
{
|
||||
obj.SetValue(TemplateProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used instead of TabControl.ContentTemplate for cached tabs
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TemplateProperty =
|
||||
DependencyProperty.RegisterAttached("Template", typeof(DataTemplate), typeof(TabContent), new UIPropertyMetadata(null));
|
||||
|
||||
|
||||
public static DataTemplateSelector GetTemplateSelector(DependencyObject obj)
|
||||
{
|
||||
return (DataTemplateSelector)obj.GetValue(TemplateSelectorProperty);
|
||||
}
|
||||
|
||||
public static void SetTemplateSelector(DependencyObject obj, DataTemplateSelector value)
|
||||
{
|
||||
obj.SetValue(TemplateSelectorProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used instead of TabControl.ContentTemplateSelector for cached tabs
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TemplateSelectorProperty =
|
||||
DependencyProperty.RegisterAttached("TemplateSelector", typeof(DataTemplateSelector), typeof(TabContent), new UIPropertyMetadata(null));
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static TabControl GetInternalTabControl(DependencyObject obj)
|
||||
{
|
||||
return (TabControl)obj.GetValue(InternalTabControlProperty);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void SetInternalTabControl(DependencyObject obj, TabControl value)
|
||||
{
|
||||
obj.SetValue(InternalTabControlProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for InternalTabControl. This enables animation, styling, binding, etc...
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static readonly DependencyProperty InternalTabControlProperty =
|
||||
DependencyProperty.RegisterAttached("InternalTabControl", typeof(TabControl), typeof(TabContent), new UIPropertyMetadata(null, OnInternalTabControlChanged));
|
||||
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static ContentControl GetInternalCachedContent(DependencyObject obj)
|
||||
{
|
||||
return (ContentControl)obj.GetValue(InternalCachedContentProperty);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void SetInternalCachedContent(DependencyObject obj, ContentControl value)
|
||||
{
|
||||
obj.SetValue(InternalCachedContentProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for InternalCachedContent. This enables animation, styling, binding, etc...
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static readonly DependencyProperty InternalCachedContentProperty =
|
||||
DependencyProperty.RegisterAttached("InternalCachedContent", typeof(ContentControl), typeof(TabContent), new UIPropertyMetadata(null));
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static object GetInternalContentManager(DependencyObject obj)
|
||||
{
|
||||
return (object)obj.GetValue(InternalContentManagerProperty);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void SetInternalContentManager(DependencyObject obj, object value)
|
||||
{
|
||||
obj.SetValue(InternalContentManagerProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for InternalContentManager. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty InternalContentManagerProperty =
|
||||
DependencyProperty.RegisterAttached("InternalContentManager", typeof(object), typeof(TabContent), new UIPropertyMetadata(null));
|
||||
|
||||
private static void OnIsCachedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
var tabControl = obj as TabControl;
|
||||
if (tabControl == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot set TabContent.IsCached on object of type " + args.NewValue.GetType().Name +
|
||||
". Only objects of type TabControl can have TabContent.IsCached property.");
|
||||
}
|
||||
|
||||
bool newValue = (bool)args.NewValue;
|
||||
|
||||
if (!newValue)
|
||||
{
|
||||
if (args.OldValue != null && ((bool)args.OldValue))
|
||||
{
|
||||
throw new NotImplementedException("Cannot change TabContent.IsCached from True to False. Turning tab caching off is not implemented");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureContentTemplateIsNull(tabControl);
|
||||
tabControl.ContentTemplate = CreateContentTemplate();
|
||||
EnsureContentTemplateIsNotModified(tabControl);
|
||||
}
|
||||
|
||||
private static DataTemplate CreateContentTemplate()
|
||||
{
|
||||
const string xaml =
|
||||
"<DataTemplate><Border b:TabContent.InternalTabControl=\"{Binding RelativeSource={RelativeSource AncestorType=TabControl}}\" /></DataTemplate>";
|
||||
|
||||
var context = new ParserContext();
|
||||
|
||||
context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
|
||||
context.XamlTypeMapper.AddMappingProcessingInstruction("b", typeof(TabContent).Namespace, typeof(TabContent).Assembly.FullName);
|
||||
|
||||
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
|
||||
context.XmlnsDictionary.Add("b", "b");
|
||||
|
||||
var template = (DataTemplate)XamlReader.Parse(xaml, context);
|
||||
return template;
|
||||
}
|
||||
|
||||
private static void OnInternalTabControlChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
if (obj == null) return;
|
||||
var container = obj as Decorator;
|
||||
|
||||
if (container == null)
|
||||
{
|
||||
var message = "Cannot set TabContent.InternalTabControl on object of type " + obj.GetType().Name +
|
||||
". Only controls that derive from Decorator, such as Border can have a TabContent.InternalTabControl.";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
if (args.NewValue == null) return;
|
||||
if (!(args.NewValue is TabControl))
|
||||
{
|
||||
throw new InvalidOperationException("Value of TabContent.InternalTabControl cannot be of type " + args.NewValue.GetType().Name +", it must be of type TabControl");
|
||||
}
|
||||
|
||||
var tabControl = (TabControl)args.NewValue;
|
||||
var contentManager = GetContentManager(tabControl, container);
|
||||
contentManager.UpdateSelectedTab();
|
||||
}
|
||||
|
||||
private static ContentManager GetContentManager(TabControl tabControl, Decorator container)
|
||||
{
|
||||
var contentManager = (ContentManager)GetInternalContentManager(tabControl);
|
||||
if (contentManager != null)
|
||||
{
|
||||
/*
|
||||
* Content manager already exists for the tab control. This means that tab content template is applied
|
||||
* again, and new instance of the Border control (container) has been created. The old container
|
||||
* referenced by the content manager is no longer visible and needs to be replaced
|
||||
*/
|
||||
contentManager.ReplaceContainer(container);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create content manager for the first time
|
||||
contentManager = new ContentManager(tabControl, container);
|
||||
SetInternalContentManager(tabControl, contentManager);
|
||||
}
|
||||
|
||||
return contentManager;
|
||||
}
|
||||
|
||||
private static void EnsureContentTemplateIsNull(TabControl tabControl)
|
||||
{
|
||||
if (tabControl.ContentTemplate != null)
|
||||
{
|
||||
throw new InvalidOperationException("TabControl.ContentTemplate value is not null. If TabContent.IsCached is True, use TabContent.Template instead of ContentTemplate");
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureContentTemplateIsNotModified(TabControl tabControl)
|
||||
{
|
||||
var descriptor = DependencyPropertyDescriptor.FromProperty(TabControl.ContentTemplateProperty, typeof(TabControl));
|
||||
descriptor.AddValueChanged(tabControl, (sender, args) =>
|
||||
{
|
||||
throw new InvalidOperationException("Cannot assign to TabControl.ContentTemplate when TabContent.IsCached is True. Use TabContent.Template instead");
|
||||
});
|
||||
}
|
||||
|
||||
public class ContentManager
|
||||
{
|
||||
TabControl _tabControl;
|
||||
Decorator _border;
|
||||
|
||||
public ContentManager(TabControl tabControl, Decorator border)
|
||||
{
|
||||
_tabControl = tabControl;
|
||||
_border = border;
|
||||
_tabControl.SelectionChanged += (sender, args) => { UpdateSelectedTab(); };
|
||||
}
|
||||
|
||||
public void ReplaceContainer(Decorator newBorder)
|
||||
{
|
||||
if (Object.ReferenceEquals(_border, newBorder)) return;
|
||||
|
||||
_border.Child = null; // detach any tab content that old border may hold
|
||||
_border = newBorder;
|
||||
}
|
||||
|
||||
public void UpdateSelectedTab()
|
||||
{
|
||||
_border.Child = GetCurrentContent();
|
||||
}
|
||||
|
||||
private ContentControl GetCurrentContent()
|
||||
{
|
||||
var item = _tabControl.SelectedItem;
|
||||
if (item == null) return null;
|
||||
|
||||
var tabItem = _tabControl.ItemContainerGenerator.ContainerFromItem(item);
|
||||
if (tabItem == null) return null;
|
||||
|
||||
var cachedContent = TabContent.GetInternalCachedContent(tabItem);
|
||||
if (cachedContent == null)
|
||||
{
|
||||
cachedContent = new ContentControl
|
||||
{
|
||||
DataContext = item,
|
||||
ContentTemplate = TabContent.GetTemplate(_tabControl),
|
||||
ContentTemplateSelector = TabContent.GetTemplateSelector(_tabControl)
|
||||
};
|
||||
|
||||
cachedContent.SetBinding(ContentControl.ContentProperty, new Binding());
|
||||
TabContent.SetInternalCachedContent(tabItem, cachedContent);
|
||||
}
|
||||
|
||||
return cachedContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,21 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.DTOs.Interventions;
|
||||
using Wabbajack.UserIntervention;
|
||||
|
||||
namespace Wabbajack.Interventions;
|
||||
|
||||
public class InteventionHandler : IUserInterventionHandler
|
||||
public class UserInteventionHandler : IUserInterventionHandler
|
||||
{
|
||||
private readonly ILogger<InteventionHandler> _logger;
|
||||
private readonly ILogger<UserInteventionHandler> _logger;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public InteventionHandler(ILogger<InteventionHandler> logger)
|
||||
public UserInteventionHandler(ILogger<UserInteventionHandler> logger, IServiceProvider serviceProvider)
|
||||
{
|
||||
_logger = logger;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
public void Raise(IUserIntervention intervention)
|
||||
{
|
||||
@ -18,7 +23,11 @@ public class InteventionHandler : IUserInterventionHandler
|
||||
{
|
||||
// Recast these or they won't be properly handled by the message bus
|
||||
case ManualDownload md:
|
||||
MessageBus.Current.SendMessage(md);
|
||||
var view = new BrowserWindow();
|
||||
var provider = _serviceProvider.GetRequiredService<ManualDownloadHandler>();
|
||||
view.DataContext = provider;
|
||||
provider.Intervention = md;
|
||||
view.Show();
|
||||
break;
|
||||
case ManualBlobDownload bd:
|
||||
MessageBus.Current.SendMessage(bd);
|
||||
|
@ -56,10 +56,18 @@ public class LoversLabLoginManager : ViewModel, INeedsLogin
|
||||
TriggerLogin = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
_logger.LogInformation("Logging into {SiteName}", SiteName);
|
||||
|
||||
MessageBus.Current.SendMessage(new OpenBrowserTab(_serviceProvider.GetRequiredService<LoversLabLoginHandler>()));
|
||||
StartLogin();
|
||||
}, this.WhenAnyValue(v => v.HaveLogin).Select(v => !v));
|
||||
}
|
||||
|
||||
private void StartLogin()
|
||||
{
|
||||
var view = new BrowserWindow();
|
||||
view.Closed += (sender, args) => { RefreshTokenState(); };
|
||||
var provider = _serviceProvider.GetRequiredService<LoversLabLoginHandler>();
|
||||
view.DataContext = provider;
|
||||
view.Show();
|
||||
}
|
||||
|
||||
private void RefreshTokenState()
|
||||
{
|
||||
|
@ -52,7 +52,8 @@ public class NexusLoginManager : ViewModel, INeedsLogin
|
||||
TriggerLogin = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
_logger.LogInformation("Logging into {SiteName}", SiteName);
|
||||
MessageBus.Current.SendMessage(new OpenBrowserTab(_serviceProvider.GetRequiredService<NexusLoginHandler>()));
|
||||
//MessageBus.Current.SendMessage(new OpenBrowserTab(_serviceProvider.GetRequiredService<NexusLoginHandler>()));
|
||||
StartLogin();
|
||||
}, this.WhenAnyValue(v => v.HaveLogin).Select(v => !v));
|
||||
|
||||
MessageBus.Current.Listen<CloseBrowserTab>()
|
||||
@ -60,6 +61,15 @@ public class NexusLoginManager : ViewModel, INeedsLogin
|
||||
.DisposeWith(CompositeDisposable);
|
||||
}
|
||||
|
||||
private void StartLogin()
|
||||
{
|
||||
var view = new BrowserWindow();
|
||||
view.Closed += (sender, args) => { RefreshTokenState(); };
|
||||
var provider = _serviceProvider.GetRequiredService<NexusLoginHandler>();
|
||||
view.DataContext = provider;
|
||||
view.Show();
|
||||
}
|
||||
|
||||
private void RefreshTokenState()
|
||||
{
|
||||
HaveLogin = _token.HaveToken();
|
||||
|
@ -56,9 +56,20 @@ public class VectorPlexusLoginManager : ViewModel, INeedsLogin
|
||||
TriggerLogin = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
_logger.LogInformation("Logging into {SiteName}", SiteName);
|
||||
MessageBus.Current.SendMessage(new OpenBrowserTab(_serviceProvider.GetRequiredService<VectorPlexusLoginHandler>()));
|
||||
StartLogin();
|
||||
}, this.WhenAnyValue(v => v.HaveLogin).Select(v => !v));
|
||||
}
|
||||
|
||||
|
||||
private void StartLogin()
|
||||
{
|
||||
var view = new BrowserWindow();
|
||||
view.Closed += (sender, args) => { RefreshTokenState(); };
|
||||
var provider = _serviceProvider.GetRequiredService<VectorPlexusLoginManager>();
|
||||
view.DataContext = provider;
|
||||
view.Show();
|
||||
}
|
||||
|
||||
|
||||
private void RefreshTokenState()
|
||||
{
|
||||
|
@ -2,9 +2,9 @@ namespace Wabbajack.Messages;
|
||||
|
||||
public class CloseBrowserTab
|
||||
{
|
||||
public BrowserTabViewModel ViewModel { get; init; }
|
||||
public BrowserWindowViewModel ViewModel { get; init; }
|
||||
|
||||
public CloseBrowserTab(BrowserTabViewModel viewModel)
|
||||
public CloseBrowserTab(BrowserWindowViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ namespace Wabbajack.Messages;
|
||||
|
||||
public class OpenBrowserTab
|
||||
{
|
||||
public BrowserTabViewModel ViewModel { get; set; }
|
||||
public BrowserWindowViewModel ViewModel { get; set; }
|
||||
|
||||
public OpenBrowserTab(BrowserTabViewModel viewModel)
|
||||
public OpenBrowserTab(BrowserWindowViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using Wabbajack.DTOs.Interventions;
|
||||
|
||||
namespace Wabbajack.UserIntervention;
|
||||
|
||||
public class ManualBlobDownloadHandler : BrowserTabViewModel
|
||||
public class ManualBlobDownloadHandler : BrowserWindowViewModel
|
||||
{
|
||||
public ManualBlobDownload Intervention { get; set; }
|
||||
|
||||
|
@ -8,7 +8,7 @@ using Wabbajack.Paths;
|
||||
|
||||
namespace Wabbajack.UserIntervention;
|
||||
|
||||
public class ManualDownloadHandler : BrowserTabViewModel
|
||||
public class ManualDownloadHandler : BrowserWindowViewModel
|
||||
{
|
||||
public ManualDownload Intervention { get; set; }
|
||||
|
||||
|
@ -12,7 +12,7 @@ using Wabbajack.Services.OSIntegrated;
|
||||
|
||||
namespace Wabbajack.UserIntervention;
|
||||
|
||||
public class NexusLoginHandler : BrowserTabViewModel
|
||||
public class NexusLoginHandler : BrowserWindowViewModel
|
||||
{
|
||||
private readonly EncryptedJsonTokenProvider<NexusApiState> _tokenProvider;
|
||||
|
||||
|
@ -17,7 +17,7 @@ using Wabbajack.Services.OSIntegrated;
|
||||
|
||||
namespace Wabbajack.UserIntervention;
|
||||
|
||||
public abstract class OAuth2LoginHandler<TIntervention, TLoginType> : BrowserTabViewModel
|
||||
public abstract class OAuth2LoginHandler<TIntervention, TLoginType> : BrowserWindowViewModel
|
||||
where TIntervention : IUserIntervention
|
||||
where TLoginType : OAuth2LoginState, new()
|
||||
{
|
||||
|
@ -18,20 +18,20 @@ using Wabbajack.Views;
|
||||
|
||||
namespace Wabbajack;
|
||||
|
||||
public abstract class BrowserTabViewModel : ViewModel
|
||||
public abstract class BrowserWindowViewModel : ViewModel
|
||||
{
|
||||
[Reactive] public string HeaderText { get; set; }
|
||||
|
||||
[Reactive] public string Instructions { get; set; }
|
||||
|
||||
public BrowserView? Browser { get; set; }
|
||||
public BrowserWindow? Browser { get; set; }
|
||||
|
||||
private WebView2 _browser => Browser!.Browser;
|
||||
|
||||
public async Task RunWrapper(CancellationToken token)
|
||||
{
|
||||
await Run(token);
|
||||
MessageBus.Current.SendMessage(new CloseBrowserTab(this));
|
||||
//MessageBus.Current.SendMessage(new CloseBrowserTab(this));
|
||||
}
|
||||
|
||||
protected abstract Task Run(CancellationToken token);
|
@ -181,13 +181,13 @@ namespace Wabbajack
|
||||
private void HandleLogin(LoversLabLogin loversLabLogin)
|
||||
{
|
||||
var handler = _serviceProvider.GetRequiredService<LoversLabLoginHandler>();
|
||||
handler.RunWrapper(CancellationToken.None).FireAndForget();
|
||||
//handler.RunWrapper(CancellationToken.None).FireAndForget();
|
||||
}
|
||||
|
||||
private void HandleLogin(VectorPlexusLogin vectorPlexusLogin)
|
||||
{
|
||||
var handler = _serviceProvider.GetRequiredService<VectorPlexusLoginHandler>();
|
||||
handler.RunWrapper(CancellationToken.None).FireAndForget();
|
||||
//handler.RunWrapper(CancellationToken.None).FireAndForget();
|
||||
}
|
||||
|
||||
private void HandleNavigateBack(NavigateBack navigateBack)
|
||||
@ -200,14 +200,14 @@ namespace Wabbajack
|
||||
{
|
||||
var handler = _serviceProvider.GetRequiredService<ManualDownloadHandler>();
|
||||
handler.Intervention = manualDownload;
|
||||
MessageBus.Current.SendMessage(new OpenBrowserTab(handler));
|
||||
//MessageBus.Current.SendMessage(new OpenBrowserTab(handler));
|
||||
}
|
||||
|
||||
private void HandleManualBlobDownload(ManualBlobDownload manualDownload)
|
||||
{
|
||||
var handler = _serviceProvider.GetRequiredService<ManualBlobDownloadHandler>();
|
||||
handler.Intervention = manualDownload;
|
||||
MessageBus.Current.SendMessage(new OpenBrowserTab(handler));
|
||||
//MessageBus.Current.SendMessage(new OpenBrowserTab(handler));
|
||||
}
|
||||
|
||||
private void HandleNavigateTo(NavigateToGlobal.ScreenType s)
|
||||
|
@ -1,16 +0,0 @@
|
||||
<UserControl x:Class="Wabbajack.Views.BrowserTabView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
|
||||
xmlns:views="clr-namespace:Wabbajack.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
|
||||
<Grid>
|
||||
<views:BrowserView x:Name="Browser">
|
||||
</views:BrowserView>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.Views;
|
||||
|
||||
public partial class BrowserTabView : IDisposable
|
||||
{
|
||||
private readonly CompositeDisposable _compositeDisposable;
|
||||
|
||||
public BrowserTabView()
|
||||
{
|
||||
_compositeDisposable = new CompositeDisposable();
|
||||
InitializeComponent();
|
||||
Browser.Browser.Source = new Uri("http://www.google.com");
|
||||
|
||||
/*
|
||||
vm.Browser = Browser;
|
||||
|
||||
vm.WhenAnyValue(vm => vm.HeaderText)
|
||||
.BindTo(this, view => view.HeaderText.Text)
|
||||
.DisposeWith(_compositeDisposable);
|
||||
*/
|
||||
|
||||
//Start().FireAndForget();
|
||||
}
|
||||
|
||||
private async Task Start()
|
||||
{
|
||||
await ((BrowserTabViewModel) DataContext).RunWrapper(CancellationToken.None);
|
||||
ClickClose(this, new RoutedEventArgs());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_compositeDisposable.Dispose();
|
||||
var vm = (BrowserTabViewModel) DataContext;
|
||||
vm.Browser = null;
|
||||
}
|
||||
|
||||
private void ClickClose(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var tc = (TabControl) this.Parent;
|
||||
if (tc != null)
|
||||
{
|
||||
if (tc.Items.Contains(this))
|
||||
tc.Items.Remove(this);
|
||||
}
|
||||
|
||||
this.Dispose();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<reactiveUi:ReactiveUserControl x:TypeArguments="wabbajack:BrowserTabViewModel"
|
||||
<reactiveUi:ReactiveUserControl x:TypeArguments="wabbajack:BrowserWindowViewModel"
|
||||
x:Class="Wabbajack.Views.BrowserView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
|
49
Wabbajack.App.Wpf/Views/BrowserWindow.xaml
Normal file
49
Wabbajack.App.Wpf/Views/BrowserWindow.xaml
Normal file
@ -0,0 +1,49 @@
|
||||
<mahapps:MetroWindow x:Class="Wabbajack.BrowserWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
|
||||
xmlns:local="clr-namespace:Wabbajack"
|
||||
xmlns:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Wabbajack.View_Models"
|
||||
xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
||||
ShowTitleBar="False"
|
||||
Title="Browser Window"
|
||||
Width="1280"
|
||||
Height="960"
|
||||
MinWidth="850"
|
||||
MinHeight="650"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
ResizeMode="CanResize"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
TitleBarHeight="25"
|
||||
UseLayoutRounding="True"
|
||||
WindowTitleBrush="{StaticResource MahApps.Brushes.Accent}"
|
||||
Activated="BrowserWindow_OnActivated"
|
||||
mc:Ignorable="d">
|
||||
<Grid Background="#121212" MouseDown="UIElement_OnMouseDown">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="20"></RowDefinition>
|
||||
<RowDefinition Height="20"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="20"></ColumnDefinition>
|
||||
<ColumnDefinition Width="20"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Grid.ColumnSpan="3" FontSize="16">Browser Window</TextBlock>
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0">
|
||||
<icon:PackIconModern Kind="NavigatePrevious"></icon:PackIconModern>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="1">
|
||||
<icon:PackIconModern Kind="Home"></icon:PackIconModern>
|
||||
</Button>
|
||||
<TextBox Grid.Row="1" Grid.Column="3" VerticalContentAlignment="Center"></TextBox>
|
||||
|
||||
<wpf:WebView2 Grid.Row="2" Grid.ColumnSpan="3" Name="Browser" Source="https://www.wabbajack.org"></wpf:WebView2>
|
||||
|
||||
</Grid>
|
||||
</mahapps:MetroWindow>
|
29
Wabbajack.App.Wpf/Views/BrowserWindow.xaml.cs
Normal file
29
Wabbajack.App.Wpf/Views/BrowserWindow.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using MahApps.Metro.Controls;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack;
|
||||
|
||||
public partial class BrowserWindow : MetroWindow
|
||||
{
|
||||
public BrowserWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
base.DragMove();
|
||||
}
|
||||
|
||||
private void BrowserWindow_OnActivated(object sender, EventArgs e)
|
||||
{
|
||||
var vm = ((BrowserWindowViewModel) DataContext);
|
||||
vm.Browser = this;
|
||||
vm.RunWrapper(CancellationToken.None)
|
||||
.ContinueWith(_ => Dispatcher.Invoke(Close));
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
xmlns:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Wabbajack.View_Models"
|
||||
xmlns:behaviors="clr-namespace:IKriv.Windows.Controls.Behaviors"
|
||||
xmlns:views="clr-namespace:Wabbajack.Views"
|
||||
ShowTitleBar="False"
|
||||
Title="WABBAJACK"
|
||||
@ -25,63 +24,46 @@
|
||||
WindowTitleBrush="{StaticResource MahApps.Brushes.Accent}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Window.Resources>
|
||||
<DataTemplate x:Key="HeaderTemplate">
|
||||
<ContentPresenter Grid.Row="0" Content="{Binding}">
|
||||
<ContentPresenter.Resources>
|
||||
<DataTemplate DataType="{x:Type local:MainWindowVM}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock FontSize="16" Margin="0, 0, 8, 0">WABBAJACK 3.0.0</TextBlock>
|
||||
<Button Name="SettingsButton">
|
||||
<icon:Material Kind="Cog"></icon:Material>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type local:BrowserTabViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock FontSize="16" Margin="0, 0, 8, 0" Text="{Binding HeaderText}"></TextBlock>
|
||||
<Button Name="SettingsButton">
|
||||
<icon:Material Kind="Close"></icon:Material>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ContentPresenter.Resources>
|
||||
</ContentPresenter>
|
||||
</DataTemplate>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Background="#121212" MouseDown="UIElement_OnMouseDown">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Rectangle Grid.Row="0">
|
||||
<Rectangle.Fill>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#16BB86FC" />
|
||||
<GradientStop Offset="0.4" Color="#00000000" />
|
||||
</LinearGradientBrush>
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<TabControl Grid.Row="0" x:Name="Tabs" behaviors:TabContent.IsCached="True"
|
||||
ItemTemplate="{DynamicResource HeaderTemplate}">
|
||||
<behaviors:TabContent.Template>
|
||||
<DataTemplate>
|
||||
<ContentPresenter Content="{Binding}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="Auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<TextBlock FontSize="16" Margin="0, 0, 8, 0">WABBAJACK 3.0.0</TextBlock>
|
||||
<Button Name="SettingsButton">
|
||||
<icon:Material Kind="Cog"></icon:Material>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Row="1" Content="{Binding ActivePane}">
|
||||
<ContentPresenter.Resources>
|
||||
<DataTemplate DataType="{x:Type local:MainWindowVM}">
|
||||
<local:MainWindowContent></local:MainWindowContent>
|
||||
<DataTemplate DataType="{x:Type local:CompilerVM}">
|
||||
<local:CompilerView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type local:BrowserTabViewModel}">
|
||||
<views:BrowserTabView></views:BrowserTabView>
|
||||
<DataTemplate DataType="{x:Type local:InstallerVM}">
|
||||
<local:InstallationView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:ModeSelectionVM}">
|
||||
<local:ModeSelectionView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:ModListGalleryVM}">
|
||||
<local:ModListGalleryView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:WebBrowserVM}">
|
||||
<local:WebBrowserView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:SettingsVM}">
|
||||
<local:SettingsView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type viewModels:ModListContentsVM}">
|
||||
<local:ModListContentsView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
</ContentPresenter.Resources>
|
||||
</ContentPresenter>
|
||||
</DataTemplate>
|
||||
</behaviors:TabContent.Template>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="1" Margin="5, 0" Name="ResourceUsage" HorizontalAlignment="Right"></TextBlock>
|
||||
</Grid>
|
||||
|
||||
<mahapps:MetroWindow.RightWindowCommands>
|
||||
<mahapps:WindowCommands>
|
||||
|
@ -40,12 +40,7 @@ namespace Wabbajack
|
||||
{
|
||||
InitializeComponent();
|
||||
_mwvm = vm;
|
||||
Tabs.ItemsSource = TabVMs;
|
||||
TabVMs.Add(vm);
|
||||
|
||||
TabVMs.Add(new ManualDownloadHandler() {Intervention = new ManualDownload(new Archive() {State = new Manual(){Url = new Uri("https://www.wabbajack.org")}})});
|
||||
Tabs.SelectedItem = TabVMs.Last();
|
||||
|
||||
DataContext = vm;
|
||||
_logger = logger;
|
||||
_systemParams = systemParams;
|
||||
try
|
||||
@ -121,10 +116,10 @@ namespace Wabbajack
|
||||
{
|
||||
this.Topmost = false;
|
||||
};
|
||||
/*
|
||||
|
||||
((MainWindowVM) DataContext).WhenAnyValue(vm => vm.OpenSettingsCommand)
|
||||
.BindTo(this, view => view.SettingsButton.Command);
|
||||
*/
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -227,12 +222,13 @@ namespace Wabbajack
|
||||
|
||||
private void OnCloseBrowserTab(CloseBrowserTab msg)
|
||||
{
|
||||
/*
|
||||
foreach (var tab in Tabs.Items.OfType<BrowserTabView>())
|
||||
{
|
||||
if (tab.DataContext != msg.ViewModel) continue;
|
||||
Tabs.Items.Remove(tab);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,38 +8,7 @@
|
||||
xmlns:viewModels="clr-namespace:Wabbajack.View_Models"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="Auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<ContentPresenter Grid.Row="0" Content="{Binding ActivePane}">
|
||||
<ContentPresenter.Resources>
|
||||
<DataTemplate DataType="{x:Type local:CompilerVM}">
|
||||
<local:CompilerView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:InstallerVM}">
|
||||
<local:InstallationView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:ModeSelectionVM}">
|
||||
<local:ModeSelectionView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:ModListGalleryVM}">
|
||||
<local:ModListGalleryView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:WebBrowserVM}">
|
||||
<local:WebBrowserView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type local:SettingsVM}">
|
||||
<local:SettingsView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type viewModels:ModListContentsVM}">
|
||||
<local:ModListContentsView ViewModel="{Binding}" />
|
||||
</DataTemplate>
|
||||
</ContentPresenter.Resources>
|
||||
</ContentPresenter>
|
||||
<TextBlock Grid.Row="1" Margin="5, 0" Name="ResourceUsage" HorizontalAlignment="Right"></TextBlock>
|
||||
</Grid>
|
||||
|
||||
|
||||
<!--
|
||||
<TabItem>
|
||||
|
Loading…
Reference in New Issue
Block a user