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

Generalized slice layout engine #737

Merged
merged 67 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
98fe244
Project structure
dalyIsaac Dec 20, 2023
9b73f6d
Rename to `SliceLayout`, and implement in-order traversal
dalyIsaac Dec 20, 2023
d26d758
Iterate over the order
dalyIsaac Dec 20, 2023
b6f8db4
Added two sample layouts
dalyIsaac Dec 20, 2023
7a54ef7
Respect the ordering
dalyIsaac Dec 20, 2023
c4c8c81
Add insertion and swapping
dalyIsaac Dec 20, 2023
7a279ac
Prune the tree of empty areas before doing a layout
dalyIsaac Dec 20, 2023
9e46121
Implement an easy `GetWindowAtPoint`
dalyIsaac Dec 20, 2023
9682f30
Set `OverflowArea.IsHorizontal`
dalyIsaac Dec 20, 2023
55043d0
Working PrimaryStackLayout
dalyIsaac Dec 21, 2023
5ac8309
Fix indexing issue on MultiColumnLayout
dalyIsaac Dec 21, 2023
ff340b2
Cache layouts for a fake scale
dalyIsaac Dec 21, 2023
7dab8e2
FocusWindowInDirection
dalyIsaac Dec 21, 2023
67bb7c2
SwapWindowInDirection
dalyIsaac Dec 21, 2023
9b7ca57
Move private methods to partial class
dalyIsaac Dec 21, 2023
8ba0b1a
Switch from eager to lazy
dalyIsaac Dec 21, 2023
9874a9c
Add commands
dalyIsaac Dec 21, 2023
b1c148c
Add PerformCustomAction
dalyIsaac Dec 22, 2023
0c8e2fc
Add PerformCustomAction for SliceLayoutEngine
dalyIsaac Dec 22, 2023
3c966f0
Promote and demote commands
dalyIsaac Dec 22, 2023
de13abd
Fix promotion/demotion
dalyIsaac Dec 22, 2023
21187f4
Added empty test project
dalyIsaac Dec 22, 2023
cc96f65
Merge remote-tracking branch 'origin/main' into 634-generalized-maste…
dalyIsaac Dec 22, 2023
65c3d68
Move AreaHelpers to its own file
dalyIsaac Dec 22, 2023
42a671e
SetStartIndexes tests
dalyIsaac Dec 23, 2023
4507885
Formatting
dalyIsaac Dec 23, 2023
66a1006
Refactor a bit and fix build
dalyIsaac Dec 23, 2023
5d9bc56
Try turn off parallel build
dalyIsaac Dec 23, 2023
57d7a43
Remove SliceLayout from Whim.Runner.csproj
dalyIsaac Dec 23, 2023
4089bbb
Add SliceLayout build back in
dalyIsaac Dec 23, 2023
2629260
Maybe fix build?
dalyIsaac Dec 23, 2023
a0fef0a
Prune tests
dalyIsaac Dec 23, 2023
16bddd4
Handle empty parents
dalyIsaac Dec 23, 2023
7707295
Most DoLayout tests
dalyIsaac Dec 23, 2023
bb4531f
DoLayout tests
dalyIsaac Dec 23, 2023
8dc9123
Overflow row
dalyIsaac Dec 24, 2023
be93f00
Commands tests
dalyIsaac Dec 24, 2023
d9b8e73
FocusWindowInDirection
dalyIsaac Dec 24, 2023
7bc6cae
Handle lazy
dalyIsaac Dec 24, 2023
8a84c3d
SwapWindowInDirection
dalyIsaac Dec 24, 2023
ae67363
Plugin coverage
dalyIsaac Dec 24, 2023
822898e
More tests
dalyIsaac Dec 24, 2023
e9002d7
MoveWindowToPoint tests
dalyIsaac Dec 24, 2023
490618a
PerformCustomAction tests
dalyIsaac Dec 24, 2023
e3f6601
More tests
dalyIsaac Dec 24, 2023
f04cc2d
Tests for remaining functionality
dalyIsaac Dec 24, 2023
8cb9979
Switch from `uint` to `int`
dalyIsaac Dec 25, 2023
be4f6d6
Semi-tested promote/demote focus
dalyIsaac Dec 25, 2023
a229463
Fix promote/demote tests
dalyIsaac Dec 25, 2023
9f40ca9
Found some commented tests
dalyIsaac Dec 25, 2023
d91e47b
TODOs
dalyIsaac Dec 25, 2023
18a8332
Add to release.yml
dalyIsaac Dec 25, 2023
071dd50
Overflow replacement in CreateMultiColumnLayout
dalyIsaac Dec 25, 2023
aed3b22
Expose OverflowArea
dalyIsaac Dec 25, 2023
50fab82
Name layouts
dalyIsaac Dec 25, 2023
e4ae1f1
Respect the names
dalyIsaac Dec 25, 2023
4561b64
Fix `ArgumentOutOfRangeException`
dalyIsaac Dec 25, 2023
a9c3451
Take the first overflow area
dalyIsaac Dec 25, 2023
69321ff
Replace TODO with issue reference
dalyIsaac Dec 25, 2023
63a9edc
Remove unused method
dalyIsaac Dec 25, 2023
9797408
Documentation
dalyIsaac Dec 25, 2023
8957c37
Merge remote-tracking branch 'origin/main' into 634-generalized-maste…
dalyIsaac Dec 25, 2023
1f58436
Coverage
dalyIsaac Dec 25, 2023
c5e28ad
Docs and update csx
dalyIsaac Dec 25, 2023
aafaf1e
Handle multiple overflow areas when there is only a single window
dalyIsaac Dec 25, 2023
e9bf22d
Docs
dalyIsaac Dec 25, 2023
cc14563
Merge remote-tracking branch 'origin/main' into 634-generalized-maste…
dalyIsaac Dec 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ changelog:
labels:
- "layout preview"

- title: Slice Layout 🍰
labels:
- "slice layout"

- title: Tree Layout 🌳
labels:
- "tree layout"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
# dotnet format analyzers Whim.sln --verify-no-changes --no-restore

- name: Add msbuild to PATH
uses: microsoft/[email protected]
uses: microsoft/setup-msbuild@v1.3.1

- name: Build
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
Configuration: ${{ matrix.configuration }}

- name: Add msbuild to PATH
uses: microsoft/[email protected]
uses: microsoft/setup-msbuild@v1.3.1

- name: Build
run: |
Expand Down
86 changes: 86 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ context.WorkspaceManager.Add("Alt");
// Set up layout engines.
context.WorkspaceManager.CreateLayoutEngines = () => new CreateLeafLayoutEngine[]
{
(id) => SliceLayouts.CreateMultiColumnLayout(context, sliceLayoutPlugin, id, 1, 2, 0),
(id) => SliceLayouts.CreatePrimaryStackLayout(context, sliceLayoutPlugin, id),
(id) => SliceLayouts.CreateSecondaryPrimaryLayout(context, sliceLayoutPlugin, id),
(id) => new TreeLayoutEngine(context, treeLayoutPlugin, id),
(id) => new ColumnLayoutEngine(id)
};
Expand Down Expand Up @@ -65,6 +68,76 @@ context.PluginManager.AddPlugin(barPlugin);

Each plugin needs to be added to the `context` object.

### Layout Engines

#### `SliceLayoutEngine`

`SliceLayoutEngine` is a layout engine that internally stores an ordered list of `IWindow`s. The monitor is divided into a number of `IArea`s. Each `IArea` corresponds to a "slice" of the `IWindow` list.

There are three types of `IArea`s:

- `ParentArea`: An area that can have any `IArea` implementation as a child
- `SliceArea`: An ordered area that can have any `IWindow` as a child. There can be multiple `SliceArea`s in a `SliceLayoutEngine`, and they are ordered by the `Order` property/parameter.
- `OverflowArea`: An area that can have any infinite number of `IWindow`s as a child. There can be only one `OverflowArea` in a `SliceLayoutEngine` - any additional `OverflowArea`s will be ignored. If no `OverflowArea` is specified, the `SliceLayoutEngine` will replace the last `SliceArea` with an `OverflowArea`.

`OverflowArea`s are implicitly the last ordered area in the layout engine, in comparison to all `SliceArea`s.

The `SliceLayouts` contains methods to create a few common layouts:

- primary/stack (master/stack)
- multi-column layout
- three-column layout, with the middle column being the primary

Arbitrary layouts can be created by nesting areas.

```csharp
context.WorkspaceManager.CreateLayoutEngines = () => new CreateLeafLayoutEngine[]
{
(id) => new SliceLayoutEngine(
context,
sliceLayoutPlugin,
id,
new ParentArea(
isRow: true,
(0.5, new OverflowArea()),
(0.5, new SliceArea(order: 0, maxChildren: 2))
)
) { Name = "Overflow on left" },

(id) => new SliceLayoutEngine(
context,
sliceLayoutPlugin,
id,
new ParentArea(
isRow: true,
(0.5, new SliceArea(order: 0, maxChildren: 1)),
(0.25, new OverflowArea()), (0.25, new OverflowArea())
)
) { Name = "Multiple overflows"},

(id) => SliceLayouts.CreateMultiColumnLayout(context, sliceLayoutPlugin, id, 1, 2, 0),
(id) => SliceLayouts.CreatePrimaryStackLayout(context, sliceLayoutPlugin, id)
};
```

`SliceLayoutEngine` requires the `SliceLayoutPlugin` to be added to the `context` object:

```csharp
SliceLayoutPlugin sliceLayoutPlugin = new(context);
context.PluginManager.AddPlugin(sliceLayoutPlugin);
```

#### `TreeLayoutEngine`

`TreeLayoutEngine` is a layout that allows users to create arbitrary grid layouts. Unlike `SliceLayoutEngine`, windows can can be added in any location.

`TreeLayoutEngine` requires the `TreeLayoutPlugin` to be added to the `context` object:

```csharp
TreeLayoutPlugin treeLayoutPlugin = new(context);
context.PluginManager.AddPlugin(treeLayoutPlugin);
```

### Commands

Whim stores commands ([`ICommand`](src/Whim/Commands/ICommand.cs)), which are objects with a unique identifier, title, and executable action. Commands expose easy access to functionality from Whim's core, and loaded plugins.
Expand Down Expand Up @@ -216,6 +289,19 @@ See [`GapsCommands.cs`](src/Whim.Gaps/GapsCommands.cs).
| `whim.gaps.inner.increase` | Increase inner gap | <kbd>Win</kbd> + <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd> |
| `whim.gaps.inner.decrease` | Decrease inner gap | <kbd>Win</kbd> + <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>J</kbd> |

##### Slice Layout Plugin Commands

See [`SliceLayoutCommands.cs`](src/Whim.SliceLayout/SliceLayoutCommands.cs).

| Identifier | Title | Keybind |
| --------------------------------------------- | ---------------------------------- | ------------------ |
| `whim.slice_layout.set_insertion_type.swap` | Set slice insertion type to swap | No default keybind |
| `whim.slice_layout.set_insertion_type.rotate` | Set slice insertion type to rotate | No default keybind |
| `whim.slice_layout.window.promote` | Promote window in stack | No default keybind |
| `whim.slice_layout.window.demote` | Demote window in stack | No default keybind |
| `whim.slice_layout.focus.promote` | Promote focus in stack | No default keybind |
| `whim.slice_layout.focus.demote` | Demote focus in stack | No default keybind |

##### Tree Layout Plugin Commands

See [`TreeLayoutCommands.cs`](src/Whim.TreeLayout/TreeLayoutCommands.cs).
Expand Down
53 changes: 44 additions & 9 deletions Whim.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.FloatingLayout", "src\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.Runner", "src\Whim.Runner\Whim.Runner.csproj", "{D74F1389-F4D1-4A1C-ACE3-D91D70472DBB}"
ProjectSection(ProjectDependencies) = postProject
{4F66FB22-C4B3-494F-BEE0-9F878349621E} = {4F66FB22-C4B3-494F-BEE0-9F878349621E}
{636EA561-2625-4D2A-9A8A-890E5AEF18B9} = {636EA561-2625-4D2A-9A8A-890E5AEF18B9}
{81F6ADB0-5053-46E7-81C6-1F04E243FB1D} = {81F6ADB0-5053-46E7-81C6-1F04E243FB1D}
{6B13ECFB-0754-4721-819A-9F4712B75E18} = {6B13ECFB-0754-4721-819A-9F4712B75E18}
{C16D9C8A-A36E-430C-AB84-700919BC7259} = {C16D9C8A-A36E-430C-AB84-700919BC7259}
{636EA561-2625-4D2A-9A8A-890E5AEF18B9} = {636EA561-2625-4D2A-9A8A-890E5AEF18B9}
{D1CD9632-7BF6-40D3-BEE5-E6FA9BCE79CB} = {D1CD9632-7BF6-40D3-BEE5-E6FA9BCE79CB}
{C16D9C8A-A36E-430C-AB84-700919BC7259} = {C16D9C8A-A36E-430C-AB84-700919BC7259}
{05AB1322-761E-4C82-BF41-9613CA563C5A} = {05AB1322-761E-4C82-BF41-9613CA563C5A}
{4F66FB22-C4B3-494F-BEE0-9F878349621E} = {4F66FB22-C4B3-494F-BEE0-9F878349621E}
{8CD01B7A-78BD-48BD-B274-B2FEE48CC8F4} = {8CD01B7A-78BD-48BD-B274-B2FEE48CC8F4}
{38946E3C-F336-450F-8159-164AD14C025B} = {38946E3C-F336-450F-8159-164AD14C025B}
{3F7A2C45-EC4E-4CF5-8D62-4BA3A52F6CAC} = {3F7A2C45-EC4E-4CF5-8D62-4BA3A52F6CAC}
{1E722ACD-6DC6-4D2E-AD30-642483643B7C} = {1E722ACD-6DC6-4D2E-AD30-642483643B7C}
{E91865D5-66D9-448B-9EEC-E0EEF6EC5EBE} = {E91865D5-66D9-448B-9EEC-E0EEF6EC5EBE}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.Bar", "src\Whim.Bar\Whim.Bar.csproj", "{D1CD9632-7BF6-40D3-BEE5-E6FA9BCE79CB}"
Expand Down Expand Up @@ -50,6 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.TestUtils", "src\Whim.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.Bar.Tests", "src\Whim.Bar.Tests\Whim.Bar.Tests.csproj", "{6339FE1D-E9CF-4C71-868A-931CB51D6486}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.SliceLayout", "src\Whim.SliceLayout\Whim.SliceLayout.csproj", "{38946E3C-F336-450F-8159-164AD14C025B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.SliceLayout.Tests", "src\Whim.SliceLayout.Tests\Whim.SliceLayout.Tests.csproj", "{0C32EB78-44C7-4397-8643-2E1C1F3442E9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.TreeLayout", "src\Whim.TreeLayout\Whim.TreeLayout.csproj", "{3F7A2C45-EC4E-4CF5-8D62-4BA3A52F6CAC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Whim.TreeLayout.Tests", "src\Whim.TreeLayout.Tests\Whim.TreeLayout.Tests.csproj", "{804053FC-ABCF-4A54-9B24-CF623CEA990F}"
Expand Down Expand Up @@ -280,6 +291,30 @@ Global
{6339FE1D-E9CF-4C71-868A-931CB51D6486}.Release|arm64.Build.0 = Release|arm64
{6339FE1D-E9CF-4C71-868A-931CB51D6486}.Release|x64.ActiveCfg = Release|x64
{6339FE1D-E9CF-4C71-868A-931CB51D6486}.Release|x64.Build.0 = Release|x64
{38946E3C-F336-450F-8159-164AD14C025B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38946E3C-F336-450F-8159-164AD14C025B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38946E3C-F336-450F-8159-164AD14C025B}.Debug|arm64.ActiveCfg = Debug|arm64
{38946E3C-F336-450F-8159-164AD14C025B}.Debug|arm64.Build.0 = Debug|arm64
{38946E3C-F336-450F-8159-164AD14C025B}.Debug|x64.ActiveCfg = Debug|x64
{38946E3C-F336-450F-8159-164AD14C025B}.Debug|x64.Build.0 = Debug|x64
{38946E3C-F336-450F-8159-164AD14C025B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38946E3C-F336-450F-8159-164AD14C025B}.Release|Any CPU.Build.0 = Release|Any CPU
{38946E3C-F336-450F-8159-164AD14C025B}.Release|arm64.ActiveCfg = Release|arm64
{38946E3C-F336-450F-8159-164AD14C025B}.Release|arm64.Build.0 = Release|arm64
{38946E3C-F336-450F-8159-164AD14C025B}.Release|x64.ActiveCfg = Release|x64
{38946E3C-F336-450F-8159-164AD14C025B}.Release|x64.Build.0 = Release|x64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Debug|arm64.ActiveCfg = Debug|arm64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Debug|arm64.Build.0 = Debug|arm64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Debug|x64.ActiveCfg = Debug|x64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Debug|x64.Build.0 = Debug|x64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Release|Any CPU.Build.0 = Release|Any CPU
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Release|arm64.ActiveCfg = Release|arm64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Release|arm64.Build.0 = Release|arm64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Release|x64.ActiveCfg = Release|x64
{0C32EB78-44C7-4397-8643-2E1C1F3442E9}.Release|x64.Build.0 = Release|x64
{3F7A2C45-EC4E-4CF5-8D62-4BA3A52F6CAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F7A2C45-EC4E-4CF5-8D62-4BA3A52F6CAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F7A2C45-EC4E-4CF5-8D62-4BA3A52F6CAC}.Debug|arm64.ActiveCfg = Debug|arm64
Expand Down Expand Up @@ -342,16 +377,16 @@ Global
{E91865D5-66D9-448B-9EEC-E0EEF6EC5EBE}.Release|x64.Build.0 = Release|x64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|arm64.ActiveCfg = Debug|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|arm64.Build.0 = Debug|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|arm64.ActiveCfg = Debug|arm64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|arm64.Build.0 = Debug|arm64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|x64.ActiveCfg = Debug|x64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Debug|x64.Build.0 = Debug|x64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|Any CPU.Build.0 = Release|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|arm64.ActiveCfg = Release|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|arm64.Build.0 = Release|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|x64.ActiveCfg = Release|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|x64.Build.0 = Release|Any CPU
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|arm64.ActiveCfg = Release|arm64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|arm64.Build.0 = Release|arm64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|x64.ActiveCfg = Release|x64
{741677F5-5C83-474E-83B7-08F7A84DE11D}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading