Files
FileTime2/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs

437 lines
16 KiB
C#

using System.Globalization;
using FileTime.App.Core.Models.Enums;
using FileTime.App.Core.ViewModels;
using FileTime.ConsoleUI.App.Controls;
using FileTime.ConsoleUI.App.Styling;
using FileTime.Core.Enums;
using FileTime.Core.Models;
using Humanizer.Bytes;
using TerminalUI;
using TerminalUI.Color;
using TerminalUI.Controls;
using TerminalUI.Extensions;
using TerminalUI.Models;
using TerminalUI.ViewExtensions;
namespace FileTime.ConsoleUI.App;
public class MainWindow
{
private readonly struct ItemViewRenderOptions
{
public readonly bool ShowAttributes;
public ItemViewRenderOptions(bool showAttributes = false)
{
ShowAttributes = showAttributes;
}
}
private readonly IRootViewModel _rootViewModel;
private readonly IApplicationContext _applicationContext;
private readonly ITheme _theme;
private readonly CommandPalette _commandPalette;
private readonly Dialogs _dialogs;
private readonly Timeline _timeline;
private readonly Lazy<IView> _root;
public MainWindow(
IRootViewModel rootViewModel,
IApplicationContext applicationContext,
ITheme theme,
CommandPalette commandPalette,
Dialogs dialogs,
Timeline timeline)
{
_rootViewModel = rootViewModel;
_applicationContext = applicationContext;
_theme = theme;
_commandPalette = commandPalette;
_dialogs = dialogs;
_timeline = timeline;
_root = new Lazy<IView>(Initialize);
}
public IEnumerable<IView> RootViews() => new[]
{
_root.Value
};
public Grid<IRootViewModel> Initialize()
{
var root = new Grid<IRootViewModel>
{
Name = "root",
DataContext = _rootViewModel,
ApplicationContext = _applicationContext,
Foreground = _theme.DefaultForegroundColor,
ChildInitializer =
{
MainContent(),
_commandPalette.View(),
_dialogs.View(),
}
};
return root;
}
private Grid<IRootViewModel> MainContent() =>
new()
{
RowDefinitionsObject = "Auto * Auto Auto Auto",
ChildInitializer =
{
new Grid<IRootViewModel>
{
ColumnDefinitionsObject = "Auto * Auto",
ChildInitializer =
{
new StackPanel<IRootViewModel>
{
Name = "username_panel",
Orientation = Orientation.Horizontal,
Margin = "0 0 1 0",
ChildInitializer =
{
new TextBlock<IRootViewModel>()
.Setup(t => t.Bind(
t,
root => root.UserName,
tb => tb.Text
)),
new TextBlock<IRootViewModel>()
.Setup(t => t.Bind(
t,
root => root.MachineName,
tb => tb.Text,
t => $"@{t}"
))
}
},
new TextBlock<IRootViewModel>
{
Foreground = _theme.ContainerColor,
Extensions =
{
new GridPositionExtension(1, 0)
}
}
.Setup(t => t.Bind(
t,
root => root.AppState.SelectedTab.Value.CurrentLocation.Value.FullName.Path,
tb => tb.Text
)),
TabControl()
.WithExtension(new GridPositionExtension(2, 0))
}
},
new Grid<IRootViewModel>
{
ColumnDefinitionsObject = "* 4* 4*",
Extensions =
{
new GridPositionExtension(0, 1)
},
ChildInitializer =
{
ParentsItemsView().WithExtension(new GridPositionExtension(0, 0)),
SelectedItemsView().WithExtension(new GridPositionExtension(1, 0)),
SelectedsItemsView().WithExtension(new GridPositionExtension(2, 0)),
}
},
new ItemsControl<IRootViewModel, string>
{
MaxHeight = 5,
Extensions =
{
new GridPositionExtension(0, 2)
},
ItemTemplate = () =>
{
return new TextBlock<string>
{
Foreground = _theme.WarningForegroundColor
}
.Setup(t => t.Bind(
t,
dc => dc,
t => t.Text));
}
}
.Setup(i => i.Bind(
i,
root => root.AppState.PopupTexts,
c => c.ItemsSource
)),
new Grid<IRootViewModel>
{
Extensions =
{
new GridPositionExtension(0, 3)
},
ChildInitializer =
{
PossibleCommands()
}
},
_timeline.View().WithExtension(new GridPositionExtension(0, 4)),
}
};
private IView<IRootViewModel> PossibleCommands()
{
//TODO: Create and use DataGrid
var commandBindings = new ListView<IRootViewModel, IPossibleCommandEntryViewModel>
{
ItemTemplate = _ =>
{
var grid = new Grid<IPossibleCommandEntryViewModel>
{
ColumnDefinitionsObject = "10 *",
ChildInitializer =
{
new TextBlock<IPossibleCommandEntryViewModel>()
.Setup(t =>
t.Bind(
t,
dc => dc.KeysText,
tb => tb.Text)
),
new TextBlock<IPossibleCommandEntryViewModel>
{
Extensions =
{
new GridPositionExtension(1, 0)
}
}.Setup(t =>
t.Bind(
t,
dc => dc.Title,
tb => tb.Text)
)
}
};
return grid;
}
};
commandBindings.Bind(
commandBindings,
root => root.PossibleCommands.PossibleCommands,
v => v.ItemsSource,
d => d);
return commandBindings;
}
private IView<IRootViewModel> TabControl()
{
var tabList = new ListView<IRootViewModel, ITabViewModel>
{
Orientation = Orientation.Horizontal,
ItemTemplate = item =>
{
var textBlock = item.CreateChild<TextBlock<ITabViewModel>>();
textBlock.Bind(
textBlock,
dc => dc.TabNumber.ToString(),
tb => tb.Text,
value => $" {value}",
fallbackValue: "?");
textBlock.Bind(
textBlock,
dc => dc.IsSelected.Value ? _theme.SelectedTabBackgroundColor : null,
tb => tb.Background,
fallbackValue: null
);
return textBlock;
}
};
tabList.Bind(
tabList,
root => root.AppState.Tabs,
v => v.ItemsSource);
return tabList;
}
private ListView<IRootViewModel, IItemViewModel> SelectedItemsView()
{
var list = new ListView<IRootViewModel, IItemViewModel>
{
ListPadding = 8,
Margin = "1 0 1 0"
};
list.ItemTemplate = item => ItemItemTemplate(item, new ItemViewRenderOptions(true));
list.Bind(
list,
root => root.AppState.SelectedTab.Value.CurrentItems.Value,
v => v.ItemsSource);
list.Bind(
list,
root => root.AppState.SelectedTab.Value.CurrentSelectedItem.Value,
v => v.SelectedItem);
return list;
}
private ListView<IRootViewModel, IItemViewModel> SelectedsItemsView()
{
var list = new ListView<IRootViewModel, IItemViewModel>
{
ListPadding = 8
};
list.ItemTemplate = item => ItemItemTemplate(item, new ItemViewRenderOptions());
list.Bind(
list,
root => root.AppState.SelectedTab.Value.SelectedsChildren.Value,
v => v.ItemsSource);
return list;
}
private ListView<IRootViewModel, IItemViewModel> ParentsItemsView()
{
var list = new ListView<IRootViewModel, IItemViewModel>
{
ListPadding = 8
};
list.ItemTemplate = item => ItemItemTemplate(item, new ItemViewRenderOptions());
list.Bind(
list,
root => root.AppState.SelectedTab.Value.ParentsChildren.Value,
v => v.ItemsSource);
return list;
}
private IView<IItemViewModel> ItemItemTemplate(
ListViewItem<IItemViewModel, IRootViewModel> item,
ItemViewRenderOptions options
)
{
var root = new Grid<IItemViewModel>
{
ChildInitializer =
{
new Rectangle<IItemViewModel>(),
new Grid<IItemViewModel>
{
Margin = "1 0 1 0",
ColumnDefinitionsObject = "* Auto",
ChildInitializer =
{
new TextBlock<IItemViewModel>()
.Setup(t =>
{
t.Bind(
t,
dc => dc == null ? string.Empty : dc.DisplayNameText,
tb => tb.Text
);
}),
new StackPanel<IItemViewModel>
{
Extensions = {new GridPositionExtension(1, 0)},
ChildInitializer =
{
new TextBlock<IItemViewModel>()
.Setup(t =>
{
if (!options.ShowAttributes) return;
t.Bind(
t,
dc => ((IContainer) dc.BaseItem).Items.Count,
tb => tb.Text,
t => $" {t}");
})
}
}
.Setup(s => s.Bind(
s,
dc => dc.BaseItem.Type == AbsolutePathType.Container,
s => s.IsVisible)),
new StackPanel<IItemViewModel>
{
Extensions = {new GridPositionExtension(1, 0)},
ChildInitializer =
{
new TextBlock<IItemViewModel>()
.Setup(t =>
{
if (!options.ShowAttributes) return;
t.Bind(
t,
dc => ((IElementViewModel) dc).Size.Value,
tb => tb.Text,
v =>
{
var b = ByteSize.FromBytes(v);
return $"{b.LargestWholeNumberValue:0.#} " + b.GetLargestWholeNumberSymbol(NumberFormatInfo.CurrentInfo).First();
});
})
}
}
.Setup(s => s.Bind(
s,
dc => dc.BaseItem.Type == AbsolutePathType.Element,
s => s.IsVisible))
}
}
}
};
root.Bind(
root,
dc => dc == null ? _theme.DefaultForegroundColor : ToForegroundColor(dc.ViewMode.Value, dc.BaseItem.Type),
tb => tb.Foreground
);
root.Bind(
root,
dc => dc == null ? _theme.DefaultBackgroundColor : ToBackgroundColor(dc.ViewMode.Value, dc.BaseItem.Type),
tb => tb.Background
);
return root;
}
private IColor? ToForegroundColor(ItemViewMode viewMode, AbsolutePathType absolutePathType) =>
(viewMode, absolutePathType) switch
{
(ItemViewMode.Default, AbsolutePathType.Container) => _theme.ContainerColor,
(ItemViewMode.Alternative, AbsolutePathType.Container) => _theme.ContainerColor,
(ItemViewMode.Default, _) => _theme.ElementColor,
(ItemViewMode.Alternative, _) => _theme.ElementColor,
(ItemViewMode.Selected, _) => _theme.SelectedItemColor,
(ItemViewMode.Marked, _) => _theme.MarkedItemForegroundColor,
(ItemViewMode.MarkedSelected, _) => _theme.SelectedItemColor,
(ItemViewMode.MarkedAlternative, _) => _theme.MarkedItemForegroundColor,
_ => throw new NotImplementedException()
};
private IColor? ToBackgroundColor(ItemViewMode viewMode, AbsolutePathType absolutePathType)
=> (viewMode, absolutePathType) switch
{
(ItemViewMode.Default, _) => _theme.DefaultBackgroundColor,
(ItemViewMode.Alternative, _) => _theme.DefaultBackgroundColor,
(ItemViewMode.Selected, _) => ToForegroundColor(ItemViewMode.Default, absolutePathType)?.AsBackground(),
(ItemViewMode.Marked, _) => _theme.MarkedItemBackgroundColor,
(ItemViewMode.MarkedSelected, _) => ToForegroundColor(ItemViewMode.Marked, absolutePathType)?.AsBackground(),
(ItemViewMode.MarkedAlternative, _) => _theme.MarkedItemBackgroundColor,
_ => throw new NotImplementedException()
};
}