Добавлен Studio
This commit is contained in:
64
Lattice.Studio/Controls/LatticeStudioShell.xaml
Normal file
64
Lattice.Studio/Controls/LatticeStudioShell.xaml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<UserControl
|
||||
x:Class="Lattice.Studio.Controls.LatticeStudioShell"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Lattice.Studio.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:lui="using:Lattice.UI.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<!-- TitleBar с MenuBar -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- Тулбар -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- СЛОТ ДЛЯ УВЕДОМЛЕНИЙ -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- Докинг -->
|
||||
<RowDefinition Height="*" />
|
||||
<!-- Статус-бар -->
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Нативный TitleBar Windows 11 -->
|
||||
<TitleBar x:Name="AppTitleBar"
|
||||
Title="{x:Bind Title, Mode=OneWay}"
|
||||
Subtitle="{x:Bind Subtitle, Mode=OneWay}"
|
||||
IsBackButtonVisible="False"
|
||||
IconSource="{x:Bind TitleBarIcon, Mode=OneWay}"
|
||||
IsPaneToggleButtonVisible="False">
|
||||
|
||||
<!-- Вставляем меню прямо в заголовок -->
|
||||
<TitleBar.Content>
|
||||
<Grid x:Name="TitleBarContentGrid" Margin="8,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Меню -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- Зона перетаскивания -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Слот для MenuBar -->
|
||||
<ContentPresenter x:Name="MenuSlot"
|
||||
Content="{x:Bind MenuContent, Mode=OneWay}"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<!-- Пустая область для захвата мышью (Drag Region) -->
|
||||
<Canvas Grid.Column="1" Background="Transparent" />
|
||||
</Grid>
|
||||
</TitleBar.Content>
|
||||
</TitleBar>
|
||||
|
||||
<!-- Тулбар -->
|
||||
<lui:LatticeContextualToolbar Grid.Row="1" x:Name="StudioToolbar" />
|
||||
<!-- Контейнер для уведомлений (StackPanel для нескольких сообщений) -->
|
||||
<StackPanel Grid.Row="2" x:Name="NotificationArea" VerticalAlignment="Top" Canvas.ZIndex="100" />
|
||||
<!-- Докинг -->
|
||||
<lui:LatticeDockHost Grid.Row="3" x:Name="MainDockHost" />
|
||||
<!-- Статус-бар -->
|
||||
<ContentPresenter Grid.Row="4" Content="{x:Bind StatusContent, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
144
Lattice.Studio/Controls/LatticeStudioShell.xaml.cs
Normal file
144
Lattice.Studio/Controls/LatticeStudioShell.xaml.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using Lattice.Core.Abstractions;
|
||||
using Lattice.Core.Models;
|
||||
using Lattice.Core.Models.Enums;
|
||||
using Microsoft.UI.Composition.SystemBackdrops;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
|
||||
namespace Lattice.Studio.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Îñíîâíàÿ îáîëî÷êà ïðèëîæåíèÿ â ñòèëå Visual Studio 2026.
|
||||
/// Îáåñïå÷èâàåò èíòåãðàöèþ íàòèâíîãî çàãîëîâêà, ñèñòåìû äîêèíãà è êîíòåêñòíûõ êîìàíä.
|
||||
/// </summary>
|
||||
public sealed partial class LatticeStudioShell : UserControl
|
||||
{
|
||||
private ILayoutService? _layoutManager;
|
||||
private IContextService? _contextService;
|
||||
private IEnumerable<ActionDefinition>? _allActions;
|
||||
|
||||
#region Dependency Properties (Ñëîòû êàñòîìèçàöèè)
|
||||
|
||||
public string Title { get => (string)GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
|
||||
public static readonly DependencyProperty TitleProperty =
|
||||
DependencyProperty.Register(nameof(Title), typeof(string), typeof(LatticeStudioShell), new PropertyMetadata("Lattice IDE"));
|
||||
|
||||
public string Subtitle { get => (string)GetValue(SubtitleProperty); set => SetValue(SubtitleProperty, value); }
|
||||
public static readonly DependencyProperty SubtitleProperty =
|
||||
DependencyProperty.Register(nameof(Subtitle), typeof(string), typeof(LatticeStudioShell), new PropertyMetadata(string.Empty));
|
||||
|
||||
public IconSource TitleBarIcon { get => (IconSource)GetValue(TitleBarIconProperty); set => SetValue(TitleBarIconProperty, value); }
|
||||
public static readonly DependencyProperty TitleBarIconProperty =
|
||||
DependencyProperty.Register(nameof(TitleBarIcon), typeof(IconSource), typeof(LatticeStudioShell), new PropertyMetadata(null));
|
||||
|
||||
public object MenuContent { get => GetValue(MenuContentProperty); set => SetValue(MenuContentProperty, value); }
|
||||
public static readonly DependencyProperty MenuContentProperty =
|
||||
DependencyProperty.Register(nameof(MenuContent), typeof(object), typeof(LatticeStudioShell), new PropertyMetadata(null));
|
||||
|
||||
public object StatusContent { get => GetValue(StatusContentProperty); set => SetValue(StatusContentProperty, value); }
|
||||
public static readonly DependencyProperty StatusContentProperty =
|
||||
DependencyProperty.Register(nameof(StatusContent), typeof(object), typeof(LatticeStudioShell), new PropertyMetadata(null));
|
||||
|
||||
#endregion
|
||||
|
||||
public LatticeStudioShell()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Èíèöèàëèçèðóåò îáîëî÷êó Studio è ñâÿçûâàåò å¸ ñ ñåðâèñàìè Lattice.Core.
|
||||
/// </summary>
|
||||
/// <param name="layoutManager">Ýêçåìïëÿð ILayoutService äëÿ óïðàâëåíèÿ îêíàìè.</param>
|
||||
/// <param name="contextService">Ýêçåìïëÿð IContextService äëÿ óïðàâëåíèÿ êíîïêàìè òóëáàðà.</param>
|
||||
/// <param name="actions">Ïîëíûé ñïèñîê îïðåäåëåíèé êîìàíä (ActionDefinition).</param>
|
||||
public void Initialize(ILayoutService layoutManager, IContextService contextService, IEnumerable<ActionDefinition> actions)
|
||||
{
|
||||
_layoutManager = layoutManager;
|
||||
_contextService = contextService;
|
||||
_allActions = actions;
|
||||
|
||||
// Ñâÿçûâàåì âèçóàëüíûé õîñò äîêèíãà ñ ëîãè÷åñêèì äâèæêîì
|
||||
MainDockHost.Manager = _layoutManager;
|
||||
|
||||
// Ïîäïèñûâàåìñÿ íà ñìåíó êîíòåêñòà (âûçûâàåòñÿ ïðè ïåðåêëþ÷åíèè âêëàäîê â Lattice.UI)
|
||||
_contextService.ContextChanged += (s, newContext) =>
|
||||
{
|
||||
// Îáíîâëÿåì òóëáàð â ïîòîêå ïîëüçîâàòåëüñêîãî èíòåðôåéñà
|
||||
this.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
StudioToolbar.UpdateItems(_allActions, newContext);
|
||||
});
|
||||
};
|
||||
|
||||
// Íà÷àëüíàÿ èíèöèàëèçàöèÿ òóëáàðà òåêóùèì êîíòåêñòîì
|
||||
StudioToolbar.UpdateItems(_allActions, _contextService.CurrentContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Íàñòðàèâàåò èíòåãðàöèþ ñ íàòèâíûì îêíîì Windows 11 (TitleBar è Backdrop).
|
||||
/// Âûçûâàåòñÿ èç MainWindow ïðèëîæåíèÿ.
|
||||
/// </summary>
|
||||
/// <param name="window">Òåêóùåå îêíî WinUI 3.</param>
|
||||
public void SetupWindow(Window window)
|
||||
{
|
||||
// 1. Ðàñøèðÿåì êîíòåíò â îáëàñòü çàãîëîâêà (Windowing SDK 1.8)
|
||||
window.ExtendsContentIntoTitleBar = true;
|
||||
|
||||
// 2. Óêàçûâàåì íàòèâíûé TitleBar äëÿ óïðàâëåíèÿ ïåðåòàñêèâàíèåì îêíà
|
||||
if (AppTitleBar != null)
|
||||
{
|
||||
window.SetTitleBar(AppTitleBar);
|
||||
}
|
||||
|
||||
// 3. Ïðèìåíÿåì Mica Alt äëÿ ôîíà â ñòèëå Visual Studio 2026
|
||||
window.SystemBackdrop = new MicaBackdrop()
|
||||
{
|
||||
Kind = MicaKind.BaseAlt
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ïîäêëþ÷àåò ñåðâèñ óâåäîìëåíèé ê îáîëî÷êå.
|
||||
/// </summary>
|
||||
public void InitializeNotifications(INotificationService notificationService)
|
||||
{
|
||||
notificationService.NotificationReceived += (s, e) =>
|
||||
{
|
||||
this.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
var infoBar = new InfoBar
|
||||
{
|
||||
Message = e.Message,
|
||||
Severity = MapSeverity(e.Severity),
|
||||
IsOpen = true,
|
||||
Style = (Style)Application.Current.Resources["LatticeNotificationStyle"]
|
||||
};
|
||||
|
||||
// Àâòîìàòè÷åñêîå çàêðûòèå
|
||||
if (e.DurationSeconds > 0)
|
||||
{
|
||||
var timer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(e.DurationSeconds)
|
||||
};
|
||||
timer.Tick += (st, et) => { infoBar.IsOpen = false; timer.Stop(); };
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
// Óäàëåíèå èç ïàìÿòè ïîñëå çàêðûòèÿ
|
||||
infoBar.CloseButtonClick += (sender, args) => NotificationArea.Children.Remove(infoBar);
|
||||
|
||||
NotificationArea.Children.Insert(0, infoBar); // Íîâûå ñâåðõó
|
||||
});
|
||||
};
|
||||
}
|
||||
private InfoBarSeverity MapSeverity(NotificationSeverity severity) => severity switch
|
||||
{
|
||||
NotificationSeverity.Error => InfoBarSeverity.Error,
|
||||
NotificationSeverity.Warning => InfoBarSeverity.Warning,
|
||||
NotificationSeverity.Success => InfoBarSeverity.Success,
|
||||
_ => InfoBarSeverity.Informational
|
||||
};
|
||||
}
|
||||
18
Lattice.Studio/Controls/LatticeStudioWindow.xaml
Normal file
18
Lattice.Studio/Controls/LatticeStudioWindow.xaml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Window
|
||||
x:Class="Lattice.Studio.Controls.LatticeStudioWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Lattice.Studio.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="LatticeStudioWindow">
|
||||
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
|
||||
<local:LatticeStudioShell x:Name="ShellRoot" />
|
||||
|
||||
</Window>
|
||||
116
Lattice.Studio/Controls/LatticeStudioWindow.xaml.cs
Normal file
116
Lattice.Studio/Controls/LatticeStudioWindow.xaml.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using Lattice.Core.Abstractions;
|
||||
using Lattice.Core.Models;
|
||||
using Lattice.Core.Services;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Lattice.Studio.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Îêíî âåðõíåãî óðîâíÿ, ñîäåðæàùåå LatticeStudioShell.
|
||||
/// Îò íåãî íàñëåäóåòñÿ ðåàëüíîå ïðèëîæåíèå.
|
||||
/// </summary>
|
||||
public partial class LatticeStudioWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Âíóòðåííèé âèçóàëüíûé Shell.
|
||||
/// </summary>
|
||||
public LatticeStudioShell Shell => ShellRoot;
|
||||
|
||||
public LatticeStudioWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Ñòàðòîâûé çàãîëîâîê
|
||||
Title = "Lattice IDE";
|
||||
Shell.Title = Title;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ïåðåîïðåäåëÿåì Title, ÷òîáû ñèíõðîíèçèðîâàòü åãî ñ Shell.
|
||||
/// </summary>
|
||||
public new string Title
|
||||
{
|
||||
get => base.Title;
|
||||
set
|
||||
{
|
||||
base.Title = value;
|
||||
if (ShellRoot is not null)
|
||||
{
|
||||
ShellRoot.Title = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Ïðîêñèðóåì ñâîéñòâà Shell íàðóæó
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
public string Subtitle
|
||||
{
|
||||
get => Shell.Subtitle;
|
||||
set => Shell.Subtitle = value;
|
||||
}
|
||||
|
||||
public IconSource TitleBarIcon
|
||||
{
|
||||
get => Shell.TitleBarIcon;
|
||||
set => Shell.TitleBarIcon = value;
|
||||
}
|
||||
|
||||
public object MenuContent
|
||||
{
|
||||
get => Shell.MenuContent;
|
||||
set => Shell.MenuContent = value;
|
||||
}
|
||||
|
||||
public object StatusContent
|
||||
{
|
||||
get => Shell.StatusContent;
|
||||
set => Shell.StatusContent = value;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Èíèöèàëèçàöèÿ ñåðâèñîâ Lattice.Core
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Åäèíàÿ òî÷êà èíèöèàëèçàöèè îêíà.
|
||||
/// Âûçûâàåòñÿ èç êîíñòðóêòîðà íàñëåäíèêà (MainWindow).
|
||||
/// </summary>
|
||||
public void Initialize(
|
||||
ILayoutService layoutService,
|
||||
IContextService contextService,
|
||||
IEnumerable<ActionDefinition> actions,
|
||||
INotificationService notificationService)
|
||||
{
|
||||
Shell.Initialize(layoutService, contextService, actions);
|
||||
Shell.InitializeNotifications(notificationService);
|
||||
Shell.SetupWindow(this);
|
||||
|
||||
OnShellInitialized();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Èíèöèàëèçèðóåò îêíî ñòàíäàðòíûìè ðåàëèçàöèÿìè ñåðâèñîâ Lattice.Core.
|
||||
/// Ïîäõîäèò äëÿ áûñòðûõ ïðîòîòèïîâ è ïðîñòûõ ïðèëîæåíèé.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
var layout = new LayoutService();
|
||||
var context = new ContextService();
|
||||
var notifications = new NotificationService();
|
||||
|
||||
// Ïóñòîé íàáîð êîìàíä ïî óìîë÷àíèþ
|
||||
var actions = Enumerable.Empty<ActionDefinition>();
|
||||
|
||||
Initialize(layout, context, actions, notifications);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Õóê äëÿ íàñëåäíèêîâ — âûçûâàåòñÿ ïîñëå ïîëíîé èíèöèàëèçàöèè Shell.
|
||||
/// </summary>
|
||||
protected virtual void OnShellInitialized()
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user