Skip to content

Commit 5650d63

Browse files
committed
Cleanup layout code and rename nodes
GridLikeNode is a base class for containers like SplitPanelNode. LayoutFunctionNode uses a function to compute base layout.
1 parent 0498d8c commit 5650d63

9 files changed

Lines changed: 121 additions & 51 deletions

File tree

FancyWM.Layouts/GridLayout.cs

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
54
using WinMan;
65

76
namespace FancyWM.Layouts
@@ -12,29 +11,67 @@ public class GridLayout(int spacing) : ILayoutFunction
1211

1312
public IReadOnlyList<Rectangle> Execute(Rectangle availableArea, IEnumerable<Constraints> constraints)
1413
{
15-
bool isHorizontal = availableArea.Width >= availableArea.Height;
14+
var (rows, columns) = CalculateGridDimensions(constraints.Count(), availableArea.Width, availableArea.Height);
15+
16+
var constraintList = constraints.ToList();
17+
var result = new List<Rectangle>();
1618

17-
var count = constraints.Count();
18-
var root = (int)Math.Round(Math.Sqrt(count));
19+
if (constraintList.Count == 0)
20+
{
21+
return result;
22+
}
1923

20-
var w = (availableArea.Width - Spacing * (root + 1)) / root;
21-
var h = (availableArea.Height - Spacing * (root + 1)) / root;
24+
double cellWidth = (double)availableArea.Width / columns;
25+
double cellHeight = (double)availableArea.Height / rows;
2226

23-
List<Rectangle> rects = [];
24-
for (int i = 0; i < w; i++)
27+
for (int i = 0; i < constraintList.Count; i++)
2528
{
26-
for (int j = 0; j < h; j++)
29+
if (i >= rows * columns)
2730
{
28-
31+
break;
2932
}
33+
34+
int row = i / columns;
35+
int col = i % columns;
36+
37+
int slotLeft = availableArea.Left + (int)(col * cellWidth);
38+
int slotRight = (col == columns - 1)
39+
? availableArea.Right
40+
: availableArea.Left + (int)((col + 1) * cellWidth);
41+
42+
int slotTop = availableArea.Top + (int)(row * cellHeight);
43+
int slotBottom = (row == rows - 1)
44+
? availableArea.Bottom
45+
: availableArea.Top + (int)((row + 1) * cellHeight);
46+
47+
int left = slotLeft + (col == 0 ? Spacing : Spacing / 2);
48+
int right = slotRight - (col == columns - 1 ? Spacing : Spacing / 2);
49+
int top = slotTop + (row == 0 ? Spacing : Spacing / 2);
50+
int bottom = slotBottom - (row == rows - 1 ? Spacing : Spacing / 2);
51+
52+
result.Add(new Rectangle(
53+
left: Math.Min(left, right),
54+
top: Math.Min(top, bottom),
55+
bottom: Math.Max(top, bottom),
56+
right: Math.Max(left, right)
57+
));
58+
}
59+
60+
return result;
61+
}
62+
63+
private (int rows, int columns) CalculateGridDimensions(int count, int width, int height)
64+
{
65+
int a = 1;
66+
while (a * a < count) a++;
67+
int b = (count + a - 1) / a;
68+
69+
if (width > height && a >= b)
70+
{
71+
(b, a) = (a, b);
3072
}
3173

32-
return constraints.Select((rect, index) => Rectangle.OffsetAndSize(
33-
left: availableArea.Left + (w * index) + Spacing * (index + 1),
34-
top: availableArea.Top + Spacing,
35-
width: w,
36-
height: h - 2 * Spacing
37-
)).ToArray();
74+
return (a, b);
3875
}
3976
}
4077
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace FancyWM.Layouts.Tiling
2+
{
3+
public abstract class GridLikeNode : PanelNode
4+
{
5+
public abstract bool CanResizeInOrientation(PanelOrientation orientation);
6+
7+
public abstract bool ResizeTo(TilingNode node, double newLength, GrowDirection direction);
8+
9+
public abstract bool ResizeBy(TilingNode node, double delta, GrowDirection direction);
10+
}
11+
}

FancyWM.Layouts/Tiling/StaticPanelNode.cs renamed to FancyWM.Layouts/Tiling/LayoutFunctionNode.cs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace FancyWM.Layouts.Tiling
88
{
9-
public class StaticPanelNode(ILayoutFunction layoutFunction) : PanelNode
9+
public class LayoutFunctionNode(ILayoutFunction layoutFunction) : GridLikeNode
1010
{
1111
public override TilingNodeType Type => TilingNodeType.Static;
1212

@@ -47,7 +47,7 @@ internal override void ArrangeCore(RectangleF rectangle)
4747

4848
public override object Clone()
4949
{
50-
var copy = (StaticPanelNode)base.Clone();
50+
var copy = (LayoutFunctionNode)base.Clone();
5151
copy.m_children = m_children.Select(x => (TilingNode)x.Clone()).ToList();
5252
foreach (var child in copy.m_children)
5353
{
@@ -58,22 +58,42 @@ public override object Clone()
5858

5959
internal override void MeasureCore()
6060
{
61-
throw new NotImplementedException();
61+
foreach (var node in m_children)
62+
{
63+
node.Measure();
64+
}
6265
}
6366

6467
public override void Move(int fromIndex, int toIndex)
6568
{
66-
throw new NotImplementedException();
69+
var n = m_children[fromIndex];
70+
m_children.RemoveAt(fromIndex);
71+
m_children.Insert(toIndex, n);
6772
}
6873

6974
public override Point GetMaxChildSize(TilingNode node)
7075
{
71-
throw new NotImplementedException();
76+
return ComputedContentRectangle.Size;
7277
}
7378

7479
public override Point GetMaxSizeForInsert(TilingNode node)
7580
{
76-
throw new NotImplementedException();
81+
return ComputedContentRectangle.Size;
82+
}
83+
84+
public override bool CanResizeInOrientation(PanelOrientation orientation)
85+
{
86+
return false;
87+
}
88+
89+
public override bool ResizeTo(TilingNode node, double newLength, GrowDirection direction)
90+
{
91+
return false;
92+
}
93+
94+
public override bool ResizeBy(TilingNode node, double delta, GrowDirection direction)
95+
{
96+
return false;
7797
}
7898
}
7999
}

FancyWM.Layouts/Tiling/PanelNode.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,4 @@ public void RemovePlaceholders()
151151
}
152152
}
153153
}
154-
155-
//class StackPanel : Panel
156-
//{
157-
// public override NodeType Type => NodeType.Stack;
158-
//}
159154
}

FancyWM.Layouts/Tiling/SplitPanelNode.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace FancyWM.Layouts.Tiling
1111
{
12-
public class SplitPanelNode : PanelNode
12+
public class SplitPanelNode : GridLikeNode
1313
{
1414
public override TilingNodeType Type => TilingNodeType.Split;
1515

@@ -152,7 +152,12 @@ internal override void ArrangeCore(RectangleF rect)
152152
}
153153
}
154154

155-
public bool ResizeTo(TilingNode node, double newLength, GrowDirection direction)
155+
public override bool CanResizeInOrientation(PanelOrientation orientation)
156+
{
157+
return Orientation == orientation;
158+
}
159+
160+
public override bool ResizeTo(TilingNode node, double newLength, GrowDirection direction)
156161
{
157162
if (Children.Count == 1)
158163
{
@@ -163,7 +168,7 @@ public bool ResizeTo(TilingNode node, double newLength, GrowDirection direction)
163168
return ResizeBy(node, newLength - m_constraints[index].Width, direction);
164169
}
165170

166-
public bool ResizeBy(TilingNode node, double delta, GrowDirection direction)
171+
public override bool ResizeBy(TilingNode node, double delta, GrowDirection direction)
167172
{
168173
if (Children.Count == 1)
169174
{

FancyWM.Layouts/Tiling/WindowNode.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,4 @@ internal override void MeasureCore()
4141
}
4242

4343
}
44-
45-
//class StackPanel : Panel
46-
//{
47-
// public override NodeType Type => NodeType.Stack;
48-
//}
4944
}

FancyWM/TilingService.Private.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ void RegisterInSavedPanel()
13291329
savedLocation.Parent.Attach(index, window);
13301330

13311331
// Restore size
1332-
if (window.Parent is SplitPanelNode splitPanel)
1332+
if (window.Parent is GridLikeNode gridNode)
13331333
{
13341334
if (m_backend.GetTree(m_workspace.VirtualDesktopManager.CurrentDesktop) is DesktopTree tree)
13351335
{
@@ -1342,13 +1342,13 @@ void RegisterInSavedPanel()
13421342
catch (UnsatisfiableFlexConstraintsException)
13431343
{
13441344
}
1345-
if (splitPanel.Orientation == PanelOrientation.Horizontal)
1345+
if (gridNode.CanResizeInOrientation(PanelOrientation.Horizontal))
13461346
{
1347-
splitPanel.ResizeTo(window, savedLocation.ComputedRectangle.Width, GrowDirection.Both);
1347+
gridNode.ResizeTo(window, savedLocation.ComputedRectangle.Width, GrowDirection.Both);
13481348
}
13491349
else
13501350
{
1351-
splitPanel.ResizeTo(window, savedLocation.ComputedRectangle.Height, GrowDirection.Both);
1351+
gridNode.ResizeTo(window, savedLocation.ComputedRectangle.Height, GrowDirection.Both);
13521352
}
13531353
}
13541354
}

FancyWM/TilingService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,10 +596,10 @@ public bool CanResize(PanelOrientation orientation, double displayPercentage)
596596
var horizontalDelta = (int)(display.WorkArea.Width * displayPercentage);
597597

598598
var grandparent = focusedNode.Ancestors
599-
.Select(x => x as SplitPanelNode)
599+
.Select(x => x as GridLikeNode)
600600
.Where(x => x != null)
601-
.FirstOrDefault(x => x!.Orientation == orientation);
602-
if (grandparent is SplitPanelNode s && s.Orientation == orientation)
601+
.FirstOrDefault(x => x!.CanResizeInOrientation(orientation));
602+
if (grandparent != null)
603603
{
604604
double newSize;
605605
switch (orientation)

FancyWM/TilingWorkspace.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,18 @@ public TilingWorkspace()
120120
{
121121
}
122122

123+
public PanelNode CreateRoot(PanelOrientation orientation)
124+
{
125+
// return new LayoutFunctionNode(new GridLayout(8));
126+
// return new LayoutFunctionNode(new RatioLayout(0.5, 8));
127+
return new SplitPanelNode { Orientation = orientation };
128+
}
129+
123130
public void RegisterDesktop(IVirtualDesktop virtualDesktop, PanelOrientation orientation)
124131
{
125132
var tree = new DesktopTree
126133
{
127-
Root = new SplitPanelNode { Orientation = orientation }
134+
Root = CreateRoot(orientation)
128135
};
129136
m_states.AddState(virtualDesktop, new DesktopState
130137
{
@@ -378,9 +385,9 @@ private static int FindInsertionIndex(TilingNode nodeAtPoint, Point pt)
378385
{
379386
Debug.Assert(nodeAtPoint.Parent != null);
380387
var insertionIndex = nodeAtPoint.Parent!.IndexOf(nodeAtPoint);
381-
if (nodeAtPoint.Parent is SplitPanelNode split)
388+
if (nodeAtPoint.Parent is GridLikeNode grid)
382389
{
383-
if (split.Orientation == PanelOrientation.Horizontal)
390+
if (grid.CanResizeInOrientation(PanelOrientation.Horizontal))
384391
{
385392
if (nodeAtPoint.ComputedRectangle.Left + nodeAtPoint.ComputedRectangle.Width / 2 < pt.X)
386393
{
@@ -612,10 +619,10 @@ public void ResizeNode(TilingNode node, Rectangle newPosition, Rectangle oldPosi
612619
{
613620
if (newPosition.Width != oldPosition.Width)
614621
{
615-
SplitPanelNode? p = node.Ancestors
616-
.Select(x => x as SplitPanelNode)
622+
GridLikeNode? p = node.Ancestors
623+
.Select(x => x as GridLikeNode)
617624
.Where(x => x != null)
618-
.FirstOrDefault(x => x!.Orientation == PanelOrientation.Horizontal);
625+
.FirstOrDefault(x => x!.CanResizeInOrientation(PanelOrientation.Horizontal));
619626

620627
if (p != null)
621628
{
@@ -647,10 +654,10 @@ public void ResizeNode(TilingNode node, Rectangle newPosition, Rectangle oldPosi
647654

648655
if (newPosition.Height != oldPosition.Height)
649656
{
650-
SplitPanelNode? p = node.Ancestors
651-
.Select(x => x as SplitPanelNode)
657+
GridLikeNode? p = node.Ancestors
658+
.Select(x => x as GridLikeNode)
652659
.Where(x => x != null)
653-
.FirstOrDefault(x => x!.Orientation == PanelOrientation.Vertical);
660+
.FirstOrDefault(x => x!.CanResizeInOrientation(PanelOrientation.Vertical));
654661

655662
if (p != null)
656663
{

0 commit comments

Comments
 (0)