Skip to content

Commit

Permalink
Rudimentary Bar (#16)
Browse files Browse the repository at this point in the history
Resolves #6

- Added a rudimentary Bar plugin.
- Added the following widgets:
  - `TextWidget`
  - `WorkspaceWidget`
  - `DateTimeWidget`
- `ProxyLayoutEngine` is now a delegate.
- Added a `BaseProxyLayoutEngine` to inherit from.
- Renamed `WorkspaceMonitorChangedEvent` to `MonitorWorkspaceChangedEvent`, as the event is responsible for notifying subscribers of the monitor's change of workspaces.
  • Loading branch information
dalyIsaac authored Jan 1, 2022
1 parent 36218cd commit ef48ea8
Show file tree
Hide file tree
Showing 43 changed files with 1,120 additions and 69 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.insertSpaces": false
}
8 changes: 7 additions & 1 deletion Whim.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim", "src\Whim\Whim.cspro
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.Dashboard", "src\Whim.Dashboard\Whim.Dashboard.csproj", "{36F8A72C-8FD4-49C5-B547-74DCFAB9587D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Whim.App", "src\Whim.App\Whim.App.csproj", "{42B300E2-06B3-4671-A11F-25875BAB658C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.App", "src\Whim.App\Whim.App.csproj", "{42B300E2-06B3-4671-A11F-25875BAB658C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Whim.Bar", "src\Whim.Bar\Whim.Bar.csproj", "{E95331E9-FE75-44FF-ABDD-519550814DB6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -27,6 +29,10 @@ Global
{42B300E2-06B3-4671-A11F-25875BAB658C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42B300E2-06B3-4671-A11F-25875BAB658C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42B300E2-06B3-4671-A11F-25875BAB658C}.Release|Any CPU.Build.0 = Release|Any CPU
{E95331E9-FE75-44FF-ABDD-519550814DB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E95331E9-FE75-44FF-ABDD-519550814DB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E95331E9-FE75-44FF-ABDD-519550814DB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E95331E9-FE75-44FF-ABDD-519550814DB6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
16 changes: 14 additions & 2 deletions src/Whim.App/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using Windows.Win32.UI.Input.KeyboardAndMouse;
using Whim.Bar;
using Whim.Dashboard;

namespace Whim.App;
Expand All @@ -19,16 +21,26 @@ private static ConfigContext CreateConfigContext()
// Add workspaces
for (int i = 0; i < 4; i++)
{
Workspace workspace = new(configContext, i.ToString(), new ColumnLayoutEngine());
Workspace workspace = new(configContext, i.ToString(), new ColumnLayoutEngine(), new ColumnLayoutEngine("Right to left", false));
configContext.WorkspaceManager.Add(workspace);
}

// Add plugins
// Add dashboard
DashboardPlugin dashboardPlugin = new(configContext);

configContext.PluginManager.RegisterPlugin(dashboardPlugin);
configContext.KeybindManager.Add(new Keybind(KeyModifiers.LWin, VIRTUAL_KEY.VK_F12), (args) => dashboardPlugin.Toggle());

// Add bar
List<BarComponent> leftComponents = new() { WorkspaceWidget.CreateComponent(), ActiveLayoutWidget.CreateComponent() };
List<BarComponent> centerComponents = new() { TextWidget.CreateComponent("Hello World!") };
List<BarComponent> rightComponents = new() { DateTimeWidget.CreateComponent() };

BarConfig barConfig = new(leftComponents, centerComponents, rightComponents);
BarPlugin barPlugin = new(configContext, barConfig);

configContext.PluginManager.RegisterPlugin(barPlugin);

return configContext;
}
}
1 change: 1 addition & 0 deletions src/Whim.App/Whim.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Whim.Bar\Whim.Bar.csproj" />
<ProjectReference Include="..\Whim.Dashboard\Whim.Dashboard.csproj" />
<ProjectReference Include="..\Whim\Whim.csproj" />
</ItemGroup>
Expand Down
11 changes: 11 additions & 0 deletions src/Whim.Bar/ActiveLayout/ActiveLayoutWidget.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<UserControl x:Class="Whim.Bar.ActiveLayoutWidget"
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:local="clr-namespace:Whim.Bar"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:ActiveLayoutViewModel}"
d:DesignHeight="450" d:DesignWidth="800">
<Button Content="{Binding Path=ActiveLayoutEngine}" Command="{Binding Path=NextLayoutEngineCommand}" CommandParameter="{Binding}" />
</UserControl>
36 changes: 36 additions & 0 deletions src/Whim.Bar/ActiveLayout/ActiveLayoutWidget.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Whim.Bar;

/// <summary>
/// Interaction logic for ActiveLayoutWidget.xaml
/// </summary>
public partial class ActiveLayoutWidget : UserControl
{
public ActiveLayoutWidgetViewModel ViewModel { get; private set; }

public ActiveLayoutWidget(IConfigContext config, IMonitor monitor)
{
ViewModel = new ActiveLayoutWidgetViewModel(config, monitor);
InitializeComponent();
DataContext = ViewModel;
}

public static BarComponent CreateComponent()
{
return new BarComponent((configContext, monitor, window) => new ActiveLayoutWidget(configContext, monitor));
}
}
89 changes: 89 additions & 0 deletions src/Whim.Bar/ActiveLayout/ActiveLayoutWidgetViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace Whim.Bar;

public class ActiveLayoutWidgetViewModel : INotifyPropertyChanged, IDisposable
{
private readonly IConfigContext _configContext;
public IMonitor Monitor { get; }
private bool disposedValue;

private readonly HashSet<IWorkspace> _workspaces = new();
public string ActiveLayoutEngine { get => _configContext.WorkspaceManager.GetWorkspaceForMonitor(Monitor)?.ActiveLayoutEngine.Name ?? ""; }

public System.Windows.Input.ICommand NextLayoutEngineCommand { get; }

public ActiveLayoutWidgetViewModel(IConfigContext configContext, IMonitor monitor)
{
_configContext = configContext;
Monitor = monitor;
NextLayoutEngineCommand = new NextLayoutEngineCommand(configContext, this);

_configContext.WorkspaceManager.WorkspaceAdded += WorkspaceAdded;
_configContext.WorkspaceManager.WorkspaceRemoved += WorkspaceRemoved;

foreach (IWorkspace workspace in _configContext.WorkspaceManager)
{
workspace.ActiveLayoutEngineChanged += Workspace_ActiveLayoutEngineChanged;
_workspaces.Add(workspace);
}
}

private void WorkspaceManager_ActiveWorkspaceChanged(object? sender, EventArgs e)
{
OnPropertyChanged(nameof(ActiveLayoutEngine));
}

public event PropertyChangedEventHandler? PropertyChanged;

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

protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// dispose managed state (managed objects)
_configContext.WorkspaceManager.WorkspaceAdded -= WorkspaceAdded;
_configContext.WorkspaceManager.WorkspaceRemoved -= WorkspaceRemoved;

foreach (IWorkspace workspace in _configContext.WorkspaceManager)
{
workspace.ActiveLayoutEngineChanged -= Workspace_ActiveLayoutEngineChanged;
}
}

// free unmanaged resources (unmanaged objects) and override finalizer
// set large fields to null
disposedValue = true;
}
}

public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}

private void WorkspaceAdded(object? sender, WorkspaceEventArgs e)
{
_workspaces.Add(e.Workspace);
}

private void WorkspaceRemoved(object? sender, WorkspaceEventArgs e)
{
_workspaces.Remove(e.Workspace);
}

private void Workspace_ActiveLayoutEngineChanged(object? sender, EventArgs e)
{
OnPropertyChanged(nameof(ActiveLayoutEngine));
}
}
30 changes: 30 additions & 0 deletions src/Whim.Bar/ActiveLayout/NextLayoutEngineCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Windows.Input;

namespace Whim.Bar;

public class NextLayoutEngineCommand : System.Windows.Input.ICommand
{
private readonly IConfigContext _configContext;
private readonly ActiveLayoutWidgetViewModel _viewModel;

public NextLayoutEngineCommand(IConfigContext configContext, ActiveLayoutWidgetViewModel viewModel)
{
_configContext = configContext;
_viewModel = viewModel;
}

public event EventHandler? CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}

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

public void Execute(object? parameter)
{
Logger.Debug("Switching to next layout engine");
_configContext.WorkspaceManager.GetWorkspaceForMonitor(_viewModel.Monitor)?.NextLayoutEngine();
}
}
74 changes: 74 additions & 0 deletions src/Whim.Bar/BarConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Controls;

namespace Whim.Bar;

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

public class BarConfig : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;

private List<BarComponent> _leftComponents;
public IEnumerable<BarComponent> LeftComponents
{
get => _leftComponents;
set
{
_leftComponents = value.ToList();
OnPropertyChanged(nameof(LeftComponents));
}
}

private List<BarComponent> _middleComponents;
public IEnumerable<BarComponent> CenterComponents
{
get => _middleComponents;
set
{
_middleComponents = value.ToList();
OnPropertyChanged(nameof(CenterComponents));
}
}

private List<BarComponent> _rightComponents;
public IEnumerable<BarComponent> RightComponents
{
get => _rightComponents;
set
{
_rightComponents = value.ToList();
OnPropertyChanged(nameof(RightComponents));
}
}

private int _height = 48;
public int Height
{
get => _height;
set
{
_height = value;
OnPropertyChanged(nameof(Height));
}
}

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)
{
_leftComponents = (leftComponents ?? Enumerable.Empty<BarComponent>()).ToList();
_middleComponents = (middleComponents ?? Enumerable.Empty<BarComponent>()).ToList();
_rightComponents = (rightComponents ?? Enumerable.Empty<BarComponent>()).ToList();
}
}
29 changes: 29 additions & 0 deletions src/Whim.Bar/BarLayoutEngine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;

namespace Whim.Bar;

public class BarLayoutEngine : BaseProxyLayoutEngine
{
private readonly BarConfig _barConfig;

public BarLayoutEngine(BarConfig barConfig, ILayoutEngine innerLayoutEngine) : base(innerLayoutEngine)
{
_barConfig = barConfig;
}

public override void AddWindow(IWindow window)
{
_innerLayoutEngine.AddWindow(window);
}

public override IEnumerable<IWindowLocation> DoLayout(ILocation location)
{
Location proxiedLocation = new(location.X, location.Y + _barConfig.Height, location.Width, location.Height - _barConfig.Height);
return _innerLayoutEngine.DoLayout(proxiedLocation);
}

public override bool RemoveWindow(IWindow window)
{
return _innerLayoutEngine.RemoveWindow(window);
}
}
Loading

0 comments on commit ef48ea8

Please sign in to comment.