Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/FrameView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public override void Redraw (Rect bounds)
foreach (var p in lc.GenerateImage (bounds)) {
this.AddRune (p.Key.X, p.Key.Y, p.Value);
}

// Redraw the lines so that focus/drag symbol renders
foreach (var subview in contentView.Subviews) {
// line.DrawSplitterSymbol ();
Expand Down
50 changes: 33 additions & 17 deletions Terminal.Gui/Views/TileView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ namespace Terminal.Gui {
public class TileView : View {
TileView parentTileView;

/// <summary>
/// The keyboard key that the user can press to toggle resizing
/// of splitter lines. Mouse drag splitting is always enabled.
/// </summary>
public Key ToggleResizable { get; set; } = Key.CtrlMask | Key.F10;

/// <summary>
/// A single <see cref="ContentView"/> presented in a <see cref="TileView"/>. To create
/// new instances use <see cref="TileView.RebuildForTileCount(int)"/>
Expand Down Expand Up @@ -167,7 +173,6 @@ public TileView () : this (2)
/// <param name="tiles"></param>
public TileView (int tiles)
{
CanFocus = true;
RebuildForTileCount (tiles);
IgnoreBorderPropertyOnRedraw = true;
Border = new Border () {
Expand Down Expand Up @@ -403,15 +408,6 @@ public bool SetSplitterPos (int idx, Pos value)
return true;
}

/// <inheritdoc/>
public override bool OnEnter (View view)
{
Driver.SetCursorVisibility (CursorVisibility.Invisible);
if (!Tiles.Where (t => t.ContentView.HasFocus).Any ()) {
Tiles.FirstOrDefault ()?.ContentView.SetFocus ();
}
return base.OnEnter (view);
}

/// <inheritdoc/>
public override void Redraw (Rect bounds)
Expand Down Expand Up @@ -550,6 +546,30 @@ public bool TrySplitTile (int idx, int numberOfPanels, out TileView result)
return true;
}

/// <inheritdoc/>
public override bool ProcessHotKey (KeyEvent keyEvent)
{
bool focusMoved = false;

if(keyEvent.Key == ToggleResizable) {
foreach(var l in splitterLines) {

var iniBefore = l.IsInitialized;
l.IsInitialized = false;
l.CanFocus = !l.CanFocus;
l.IsInitialized = iniBefore;

if (l.CanFocus && !focusMoved) {
l.SetFocus ();
focusMoved = true;
}
}
return true;
}

return base.ProcessHotKey (keyEvent);
}

private bool IsValidNewSplitterPos (int idx, Pos value, int fullSpace)
{
int newSize = value.Anchor (fullSpace);
Expand Down Expand Up @@ -750,7 +770,7 @@ private void Setup (Rect bounds)
tile.ContentView.Width = GetTileWidthOrHeight (i, Bounds.Width, visibleTiles, visibleSplitterLines);
} else {
tile.ContentView.X = bounds.X;
tile.ContentView.Y = i == 0 ? 0 : Pos.Bottom (visibleSplitterLines [i - 1]);
tile.ContentView.Y = i == 0 ? bounds.Y : Pos.Bottom (visibleSplitterLines [i - 1]);
tile.ContentView.Width = bounds.Width;
tile.ContentView.Height = GetTileWidthOrHeight (i, Bounds.Height, visibleTiles, visibleSplitterLines);
}
Expand Down Expand Up @@ -864,7 +884,7 @@ private class TileViewLineView : LineView {

public TileViewLineView (TileView parent, int idx)
{
CanFocus = true;
CanFocus = false;
TabStop = true;

this.Parent = parent;
Expand Down Expand Up @@ -929,7 +949,7 @@ public override void Redraw (Rect bounds)

public void DrawSplitterSymbol ()
{
if (CanFocus && HasFocus) {
if (dragPosition != null || CanFocus) {
var location = moveRuneRenderLocation ??
new Point (Bounds.Width / 2, Bounds.Height / 2);

Expand All @@ -939,10 +959,6 @@ public void DrawSplitterSymbol ()

public override bool MouseEvent (MouseEvent mouseEvent)
{
if (!CanFocus) {
return true;
}

if (!dragPosition.HasValue && (mouseEvent.Flags == MouseFlags.Button1Pressed)) {

// Start a Drag
Expand Down
8 changes: 4 additions & 4 deletions UICatalog/Scenarios/TileViewExperiment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override void Setup ()
Y = 1,
Width = 15, //Dim.Fill (),
Height = 15, //Dim.Fill (),
//IgnoreBorderPropertyOnRedraw = true
//IgnoreBorderPropertyOnRedraw = true

};
frame1.Border.BorderStyle = BorderStyle.Double;
Expand Down Expand Up @@ -60,11 +60,11 @@ public override void Setup ()
Width = 14, //Dim.Percent (30) - 5,
Height = 14, //Dim.Percent (50) - 5,
ColorScheme = Colors.ColorSchemes ["Dialog"],
Border = new Border () {
BorderStyle = BorderStyle.Single,
Border = new Border () {
BorderStyle = BorderStyle.Single,
//BorderThickness = new Thickness (1),
DrawMarginFrame = true,
Padding = new Thickness(1),
Padding = new Thickness (1),
BorderBrush = Color.BrightMagenta,
Title = "Border Title"
}
Expand Down
3 changes: 3 additions & 0 deletions UICatalog/Scenarios/TileViewNesting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ private void SetupTileView ()
bool? border = cbBorder.Checked;
bool? startHorizontal = cbHorizontal.Checked;

foreach(var sub in workArea.Subviews) {
sub.Dispose ();
}
workArea.RemoveAll ();

if (numberOfViews <= 0) {
Expand Down
101 changes: 61 additions & 40 deletions UnitTests/Views/TileViewTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.ComponentModel;
using System.Linq;
using Terminal.Gui;
using Terminal.Gui.Graphs;
using Xunit;
using Xunit.Abstractions;
Expand Down Expand Up @@ -60,7 +60,7 @@ public void TestTileView_Vertical_WithBorder ()
public void TestTileView_Vertical_Focused ()
{
var tileView = Get11By3TileView (out var line);
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));

tileView.Redraw (tileView.Bounds);

Expand Down Expand Up @@ -100,7 +100,7 @@ public void TestTileView_Vertical_Focused ()
public void TestTileView_Vertical_Focused_WithBorder ()
{
var tileView = Get11By3TileView (out var line, true);
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));

tileView.Redraw (tileView.Bounds);

Expand Down Expand Up @@ -141,9 +141,10 @@ public void TestTileView_Vertical_Focused_WithBorder ()
public void TestTileView_Vertical_Focused_50PercentSplit ()
{
var tileView = Get11By3TileView (out var line);
SetInputFocusLine (tileView);
tileView.SetSplitterPos (0, Pos.Percent (50));
Assert.IsType<Pos.PosFactor> (tileView.SplitterDistances.ElementAt (0));
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));

tileView.Redraw (tileView.Bounds);

string looksLike =
Expand Down Expand Up @@ -209,7 +210,7 @@ public void TestTileView_Horizontal ()
public void TestTileView_Vertical_View1MinSize_Absolute ()
{
var tileView = Get11By3TileView (out var line);
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));
tileView.Tiles.ElementAt (0).MinSize = 6;

// distance is too small (below 6)
Expand Down Expand Up @@ -254,7 +255,7 @@ public void TestTileView_Vertical_View1MinSize_Absolute ()
public void TestTileView_Vertical_View1MinSize_Absolute_WithBorder ()
{
var tileView = Get11By3TileView (out var line, true);
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));
tileView.Tiles.ElementAt (0).MinSize = 5;

// distance is too small (below 5)
Expand Down Expand Up @@ -298,7 +299,7 @@ public void TestTileView_Vertical_View1MinSize_Absolute_WithBorder ()
public void TestTileView_Vertical_View2MinSize_Absolute ()
{
var tileView = Get11By3TileView (out var line);
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));
tileView.Tiles.ElementAt (1).MinSize = 6;

// distance leaves too little space for view2 (less than 6 would remain)
Expand Down Expand Up @@ -342,7 +343,7 @@ public void TestTileView_Vertical_View2MinSize_Absolute ()
public void TestTileView_Vertical_View2MinSize_Absolute_WithBorder ()
{
var tileView = Get11By3TileView (out var line, true);
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));
tileView.Tiles.ElementAt (1).MinSize = 5;

// distance leaves too little space for view2 (less than 5 would remain)
Expand Down Expand Up @@ -386,8 +387,6 @@ public void TestTileView_Vertical_View2MinSize_Absolute_WithBorder ()
public void TestTileView_InsertPanelAtStart ()
{
var tileView = Get11By3TileView (out var line, true);
SetInputFocusLine (tileView);

tileView.InsertTile (0);

tileView.Redraw (tileView.Bounds);
Expand All @@ -405,8 +404,6 @@ public void TestTileView_InsertPanelAtStart ()
public void TestTileView_InsertPanelMiddle ()
{
var tileView = Get11By3TileView (out var line, true);
SetInputFocusLine (tileView);

tileView.InsertTile (1);

tileView.Redraw (tileView.Bounds);
Expand All @@ -424,8 +421,6 @@ public void TestTileView_InsertPanelMiddle ()
public void TestTileView_InsertPanelAtEnd ()
{
var tileView = Get11By3TileView (out var line, true);
SetInputFocusLine (tileView);

tileView.InsertTile (2);

tileView.Redraw (tileView.Bounds);
Expand All @@ -445,7 +440,9 @@ public void TestTileView_Horizontal_Focused ()
var tileView = Get11By3TileView (out var line);

tileView.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
SetInputFocusLine (tileView);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));

Assert.True (line.HasFocus);

tileView.Redraw (tileView.Bounds);

Expand Down Expand Up @@ -485,9 +482,9 @@ public void TestTileView_Horizontal_Focused ()
public void TestTileView_Horizontal_View1MinSize_Absolute ()
{
var tileView = Get11By3TileView (out var line);
tileView.ProcessHotKey (new KeyEvent (tileView.ToggleResizable, new KeyModifiers ()));

tileView.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
SetInputFocusLine (tileView);
tileView.Tiles.ElementAt (0).MinSize = 1;

// 0 should not be allowed because it brings us below minimum size of View1
Expand Down Expand Up @@ -2045,6 +2042,45 @@ public void TestNestedContainer3RightAnd1Down_TileVisibility_WithoutBorder ()

}

[Fact, AutoInitShutdown]
public void Test_SplitTop_WholeBottom()
{
var tileView = new TileView (2) {
Width = 20,
Height = 10,
Orientation = Orientation.Horizontal,
};
tileView.Border.BorderStyle = BorderStyle.Single;

Assert.True (tileView.TrySplitTile (0,2,out TileView top));

top.Tiles.ElementAt (0).ContentView.Add (new Label ("bleh"));
top.Tiles.ElementAt (1).ContentView.Add (new Label ("blah"));

tileView.Tiles.ElementAt (1).ContentView.Add (new Label ("Hello"));
tileView.ColorScheme = new ColorScheme ();
top.ColorScheme = new ColorScheme ();
tileView.LayoutSubviews ();

tileView.Redraw (tileView.Bounds);

string looksLike =
@"
┌─────────┬────────┐
│bleh │blah │
│ │ │
│ │ │
│ │ │
├─────────┴────────┤
│Hello │
│ │
│ │
└──────────────────┘";

TestHelpers.AssertDriverContentsAre (looksLike, output);

}

[Fact, AutoInitShutdown]
public void TestNestedContainer3RightAnd1Down_TitleDoesNotOverspill()
{
Expand Down Expand Up @@ -2094,12 +2130,10 @@ public void TestNestedContainer3RightAnd1Down_TitleTriesToOverspill ()

TestHelpers.AssertDriverContentsAre (looksLike, output);
}


[Fact,AutoInitShutdown]
[Fact, AutoInitShutdown]
public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRebuildForTileCount ()
{
var tv = GetTileView (20,10);
var tv = GetTileView (20, 10);

var myReusableView = new DisposeCounter ();

Expand All @@ -2113,10 +2147,10 @@ public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRebuildForTileCount
// but I still want my view in the first tile
tv.Tiles.ElementAt (0).ContentView.Add (myReusableView);
Assert.Multiple (
()=>Assert.Equal (0, myReusableView.DisposalCount)
,()=> {
() => Assert.Equal (0, myReusableView.DisposalCount)
, () => {
tv.Dispose ();
Assert.Equal (1, myReusableView.DisposalCount);
Assert.Equal (1, myReusableView.DisposalCount);
});
}
[Fact, AutoInitShutdown]
Expand All @@ -2140,15 +2174,13 @@ public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringInsertTile ()
() => Assert.Equal (0, myReusableView.DisposalCount)
, () => {
tv.Dispose ();

// TODO seems to be double disposed ?!
Assert.True (myReusableView.DisposalCount >= 1);
Assert.True (myReusableView.DisposalCount>=1);
});
}
[Theory, AutoInitShutdown]
[InlineData(0)]
[InlineData (0)]
[InlineData (1)]
public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRemoveTile(int idx)
public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRemoveTile (int idx)
{
var tv = GetTileView (20, 10);

Expand All @@ -2166,14 +2198,10 @@ public void TestDisposal_NoEarlyDisposalsOfUsersViews_DuringRemoveTile(int idx)
() => Assert.Equal (0, myReusableView.DisposalCount)
, () => {
tv.Dispose ();

// TODO seems to be double disposed ?!
Assert.True (myReusableView.DisposalCount >= 1);
});
}

private class DisposeCounter : View
{
private class DisposeCounter : View {
public int DisposalCount;
protected override void Dispose (bool disposing)
{
Expand Down Expand Up @@ -2255,13 +2283,6 @@ private LineView GetLine (TileView tileView)
return tileView.Subviews.OfType<LineView> ().Single ();
}

private void SetInputFocusLine (TileView tileView)
{
var line = GetLine (tileView);
line.SetFocus ();
Assert.True (line.HasFocus);
}


private TileView Get5x1TilesView (bool border = true)
{
Expand Down