Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IWorkspace.Create #111

Merged
merged 12 commits into from
Jul 3, 2022
5 changes: 5 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
</Project>
11 changes: 10 additions & 1 deletion src/Whim.Bar/ActiveLayout/ActiveLayoutWidget.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@ namespace Whim.Bar;
/// <summary>
/// Interaction logic for ActiveLayoutWidget.xaml
/// </summary>
public partial class ActiveLayoutWidget : UserControl
internal partial class ActiveLayoutWidget : UserControl
{
/// <summary>
/// The view model for the active layout widget.
/// </summary>
public ActiveLayoutWidgetViewModel ViewModel { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="ActiveLayoutWidget"/> class.
/// </summary>
public ActiveLayoutWidget(IConfigContext config, IMonitor monitor)
{
ViewModel = new ActiveLayoutWidgetViewModel(config, monitor);
UIElementExtensions.InitializeComponent(this, "Whim.Bar", "ActiveLayout/ActiveLayoutWidget");
}

/// <summary>
/// Creates a new bar component which contains the active layout widget.
/// </summary>
public static BarComponent CreateComponent()
{
return new BarComponent((configContext, monitor, window) => new ActiveLayoutWidget(configContext, monitor));
Expand Down
24 changes: 24 additions & 0 deletions src/Whim.Bar/ActiveLayout/ActiveLayoutWidgetViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,37 @@

namespace Whim.Bar;

/// <summary>
/// View model containing the active layout.
/// </summary>
public class ActiveLayoutWidgetViewModel : INotifyPropertyChanged, IDisposable
{
private readonly IConfigContext _configContext;

/// <summary>
/// The monitor that the widget is displayed on.
/// </summary>
public IMonitor Monitor { get; }

private bool disposedValue;

private readonly HashSet<IWorkspace> _workspaces = new();

/// <summary>
/// The name of the active layout engine.
/// </summary>
public string ActiveLayoutEngine => _configContext.WorkspaceManager.GetWorkspaceForMonitor(Monitor)?.ActiveLayoutEngine.Name ?? "";

/// <summary>
/// Command to switch to the next layout engine.
/// </summary>
public System.Windows.Input.ICommand NextLayoutEngineCommand { get; }

/// <summary>
///
/// </summary>
/// <param name="configContext"></param>
/// <param name="monitor"></param>
public ActiveLayoutWidgetViewModel(IConfigContext configContext, IMonitor monitor)
{
_configContext = configContext;
Expand All @@ -33,10 +53,13 @@ public ActiveLayoutWidgetViewModel(IConfigContext configContext, IMonitor monito

private void WorkspaceManager_ActiveWorkspaceChanged(object? sender, EventArgs e) => OnPropertyChanged(nameof(ActiveLayoutEngine));

/// <inheritdoc/>
public event PropertyChangedEventHandler? PropertyChanged;

/// <inheritdoc/>
protected virtual void OnPropertyChanged(string? propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

/// <inheritdoc/>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
Expand All @@ -55,6 +78,7 @@ protected virtual void Dispose(bool disposing)
}
}

/// <inheritdoc/>
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Expand Down
11 changes: 11 additions & 0 deletions src/Whim.Bar/ActiveLayout/NextLayoutEngineCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@

namespace Whim.Bar;

/// <summary>
/// Command to switch to the next layout engine.
/// </summary>
public class NextLayoutEngineCommand : System.Windows.Input.ICommand
{
private readonly IConfigContext _configContext;
private readonly ActiveLayoutWidgetViewModel _viewModel;

#pragma warning disable CS0067 // The event 'NextLayoutEngineCommand.CanExecuteChanged' is never used
/// <inheritdoc/>
public event EventHandler? CanExecuteChanged;
#pragma warning restore CS0067 // The event 'NextLayoutEngineCommand.CanExecuteChanged' is never used

/// <summary>
/// Creates a new instance of <see cref="NextLayoutEngineCommand"/>.
/// </summary>
/// <param name="configContext"></param>
/// <param name="viewModel"></param>
public NextLayoutEngineCommand(IConfigContext configContext, ActiveLayoutWidgetViewModel viewModel)
{
_configContext = configContext;
_viewModel = viewModel;
}

/// <inheritdoc/>
public bool CanExecute(object? parameter) => true;

/// <inheritdoc/>
public void Execute(object? parameter)
{
Logger.Debug("Switching to next layout engine");
Expand Down
43 changes: 37 additions & 6 deletions src/Whim.Bar/BarConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,23 @@ namespace Whim.Bar;

/// <summary>
/// Delegate for creating a component.
/// A component will subscribe to <see cref="Window.Closed"/> if it has resources to dispose.
/// A component will subscribe to <see cref="Microsoft.UI.Xaml.Window.Closed"/> if it has resources to dispose.
/// </summary>
public delegate UserControl BarComponent(IConfigContext configContext, IMonitor monitor, Microsoft.UI.Xaml.Window window);

/// <summary>
/// Configuration for the bar plugin.
/// </summary>
public class BarConfig : INotifyPropertyChanged
{
/// <inheritdoc/>
public event PropertyChangedEventHandler? PropertyChanged;

private List<BarComponent> _leftComponents;

/// <summary>
/// The components to display on the left side of the bar.
/// </summary>
public IEnumerable<BarComponent> LeftComponents
{
get => _leftComponents;
Expand All @@ -27,18 +35,26 @@ public IEnumerable<BarComponent> LeftComponents
}
}

private List<BarComponent> _middleComponents;
private List<BarComponent> _centerComponents;

/// <summary>
/// The components to display in the center of the bar.
/// </summary>
public IEnumerable<BarComponent> CenterComponents
{
get => _middleComponents;
get => _centerComponents;
set
{
_middleComponents = value.ToList();
_centerComponents = value.ToList();
OnPropertyChanged(nameof(CenterComponents));
}
}

private List<BarComponent> _rightComponents;

/// <summary>
/// The components to display on the right side of the bar.
/// </summary>
public IEnumerable<BarComponent> RightComponents
{
get => _rightComponents;
Expand All @@ -50,6 +66,10 @@ public IEnumerable<BarComponent> RightComponents
}

private int _height = 48;

/// <summary>
/// The height of the bar.
/// </summary>
public int Height
{
get => _height;
Expand All @@ -61,6 +81,10 @@ public int Height
}

private Thickness _margin = new(10.0);

/// <summary>
/// The margin of the bar.
/// </summary>
public Thickness Margin
{
get => _margin;
Expand All @@ -71,15 +95,22 @@ public Thickness Margin
}
}

/// <inheritdoc/>
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public BarConfig(IEnumerable<BarComponent>? leftComponents = null, IEnumerable<BarComponent>? middleComponents = null, IEnumerable<BarComponent>? rightComponents = null)
/// <summary>
/// Creates a new bar configuration.
/// </summary>
/// <param name="leftComponents">The components to display on the left side of the bar.</param>
/// <param name="centerComponents">The components to display in the center of the bar.</param>
/// <param name="rightComponents">The components to display on the right side of the bar.</param>
public BarConfig(IEnumerable<BarComponent>? leftComponents = null, IEnumerable<BarComponent>? centerComponents = null, IEnumerable<BarComponent>? rightComponents = null)
{
_leftComponents = (leftComponents ?? Enumerable.Empty<BarComponent>()).ToList();
_middleComponents = (middleComponents ?? Enumerable.Empty<BarComponent>()).ToList();
_centerComponents = (centerComponents ?? Enumerable.Empty<BarComponent>()).ToList();
_rightComponents = (rightComponents ?? Enumerable.Empty<BarComponent>()).ToList();
}
}
27 changes: 25 additions & 2 deletions src/Whim.Bar/BarException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,35 @@

namespace Whim.Bar;

/// <summary>
/// Exception thrown by Whim.Bar.
/// </summary>
[Serializable]
public class BarException : Exception
public class BarException : System.Exception
{
/// <summary>
/// Constructs a new BarException.
/// </summary>
public BarException() { }

/// <summary>
/// Constructs a new BarException.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public BarException(string message) : base(message) { }
public BarException(string message, Exception inner) : base(message, inner) { }

/// <summary>
/// Constructs a new BarException.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="inner">The exception that is the cause of the current exception.</param>
public BarException(string message, System.Exception inner) : base(message, inner) { }

/// <summary>
/// Constructs a new BarException.
/// </summary>
/// <param name="info">The <see cref="System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
protected BarException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
Expand Down
11 changes: 10 additions & 1 deletion src/Whim.Bar/BarLayoutEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@

namespace Whim.Bar;

/// <summary>
/// A proxy layout engine to reserve space for the bar in each monitor.
/// </summary>
public class BarLayoutEngine : BaseProxyLayoutEngine
{
private readonly BarConfig _barConfig;

/// <summary>
/// Creates a new instance of the proxy layout engine <see cref="BarLayoutEngine"/>.
/// </summary>
/// <param name="barConfig"></param>
/// <param name="innerLayoutEngine"></param>
public BarLayoutEngine(BarConfig barConfig, ILayoutEngine innerLayoutEngine) : base(innerLayoutEngine)
{
_barConfig = barConfig;
}

public override IEnumerable<IWindowLocation> DoLayout(ILocation<int> location)
/// <inheritdoc />
public override IEnumerable<IWindowState> DoLayout(ILocation<int> location)
{
int height = _barConfig.Height + (int)(_barConfig.Margin.Bottom + _barConfig.Margin.Top);
Location proxiedLocation = new(
Expand Down
14 changes: 14 additions & 0 deletions src/Whim.Bar/BarPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

namespace Whim.Bar;

/// <summary>
/// BarPlugin displays an interactive bar at the top of the screen for Whim. It can be configured
/// with various <see cref="BarComponent"/>s to display on the left, center, and right sides of the bar.
/// </summary>
public class BarPlugin : IPlugin, IDisposable
{
private readonly IConfigContext _configContext;
Expand All @@ -11,19 +15,26 @@ public class BarPlugin : IPlugin, IDisposable
private readonly Dictionary<IMonitor, BarWindow> _monitorBarMap = new();
private bool disposedValue;

/// <summary>
/// Create the bar plugin.
/// </summary>
/// <param name="configContext"></param>
/// <param name="barConfig"></param>
public BarPlugin(IConfigContext configContext, BarConfig barConfig)
{
_configContext = configContext;
_barConfig = barConfig;
}

/// <inheritdoc />
public void PreInitialize()
{
_configContext.MonitorManager.MonitorsChanged += MonitorManager_MonitorsChanged;
_configContext.FilterManager.IgnoreTitleMatch("Whim Bar");
_configContext.WorkspaceManager.AddProxyLayoutEngine(layout => new BarLayoutEngine(_barConfig, layout));
}

/// <inheritdoc />
public void PostInitialize()
{
foreach (IMonitor monitor in _configContext.MonitorManager)
Expand Down Expand Up @@ -57,6 +68,7 @@ private void MonitorManager_MonitorsChanged(object? sender, MonitorsChangedEvent
}
}

/// <inheritdoc />
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
Expand All @@ -76,6 +88,8 @@ protected virtual void Dispose(bool disposing)
disposedValue = true;
}
}

/// <inheritdoc />
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Expand Down
11 changes: 9 additions & 2 deletions src/Whim.Bar/BarWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ public sealed partial class BarWindow : Microsoft.UI.Xaml.Window
private readonly IConfigContext _configContext;
private readonly BarConfig _barConfig;
private readonly IMonitor _monitor;
private readonly IWindowLocation _windowLocation;
private readonly IWindowState _windowLocation;

/// <summary>
/// Creates a new bar window.
/// </summary>
/// <param name="configContext"></param>
/// <param name="barConfig"></param>
/// <param name="monitor"></param>
/// <exception cref="BarException"></exception>
public BarWindow(IConfigContext configContext, BarConfig barConfig, IMonitor monitor)
{
_configContext = configContext;
Expand All @@ -31,7 +38,7 @@ public BarWindow(IConfigContext configContext, BarConfig barConfig, IMonitor mon
int topMargin = (int)_barConfig.Margin.Top;
int bottomMargin = (int)_barConfig.Margin.Bottom;

_windowLocation = new WindowLocation(window, new Location(
_windowLocation = new WindowState(window, new Location(
x: _monitor.X + leftMargin,
y: _monitor.Y + rightMargin,
width: _monitor.Width - (leftMargin + rightMargin),
Expand Down
2 changes: 1 addition & 1 deletion src/Whim.Bar/DateTime/DateTimeWidget.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Whim.Bar;
/// <summary>
/// Interaction logic for DateTimeWidget.xaml
/// </summary>
public partial class DateTimeWidget : UserControl
internal partial class DateTimeWidget : UserControl
{
public DateTimeWidgetViewModel ViewModel { get; private set; }

Expand Down
Loading