feat(ui): assemble MainWindow from the components layer
Top-level chat window composes HonorificHeader, Sidebar, MessageList, InputBar and StatusBar in the layout from the master spec: header row, horizontal body (sidebar + main area with messages + input), status strip pinned to the bottom. Component types are fully qualified through the Ui.Components prefix so the v1.5.6 Ui.StatusBar type cannot shadow the new layer through parent-namespace resolution before it is removed. Toggle is a new-shadow on Window.Toggle so the open path also writes Config.MainWindowOpen; OnClose covers the close path through the base behaviour. InputBar.Height is now public so the layout math can reach it from outside the components folder.
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using System.Numerics;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
|
||||
namespace HellionChat.Ui.Windows;
|
||||
|
||||
// Top-level chat window assembled from the components layer. Layout from
|
||||
// top to bottom: honorific header, horizontal body with sidebar + main
|
||||
// area (messages + input bar), and the status strip pinned to the
|
||||
// bottom. The window-level theme push stays on the global plugin draw
|
||||
// path for now — this window only composes content.
|
||||
//
|
||||
// Components are fully qualified through the Ui.Components prefix so the
|
||||
// old Ui.StatusBar type (still alive until the cleanup block removes it)
|
||||
// cannot shadow the new layer through parent-namespace resolution.
|
||||
internal sealed class MainWindow : Window
|
||||
{
|
||||
private const float DefaultWidth = 620f;
|
||||
private const float DefaultHeight = 340f;
|
||||
private const float MinWidth = 480f;
|
||||
private const float MinHeight = 260f;
|
||||
|
||||
private readonly Components.HonorificHeader _honorific;
|
||||
private readonly Components.Sidebar _sidebar;
|
||||
private readonly Components.MessageList _messages;
|
||||
private readonly Components.InputBar _input;
|
||||
private readonly Components.StatusBar _status;
|
||||
|
||||
private Tab? _activeTab;
|
||||
|
||||
public MainWindow(
|
||||
Components.HonorificHeader honorific,
|
||||
Components.Sidebar sidebar,
|
||||
Components.MessageList messages,
|
||||
Components.InputBar input,
|
||||
Components.StatusBar status
|
||||
)
|
||||
: base($"{Plugin.PluginName}###hellion-main")
|
||||
{
|
||||
_honorific = honorific;
|
||||
_sidebar = sidebar;
|
||||
_messages = messages;
|
||||
_input = input;
|
||||
_status = status;
|
||||
|
||||
Size = new Vector2(DefaultWidth, DefaultHeight);
|
||||
SizeCondition = ImGuiCond.FirstUseEver;
|
||||
SizeConstraints = new WindowSizeConstraints
|
||||
{
|
||||
MinimumSize = new Vector2(MinWidth, MinHeight),
|
||||
MaximumSize = new Vector2(float.MaxValue, float.MaxValue),
|
||||
};
|
||||
IsOpen = Plugin.Config.MainWindowOpen;
|
||||
RespectCloseHotkey = false;
|
||||
}
|
||||
|
||||
public Tab? ActiveTab => _activeTab;
|
||||
|
||||
// new-shadow on Window.Toggle so the open path also writes Config —
|
||||
// OnClose already covers the close path through the base behaviour.
|
||||
public new void Toggle()
|
||||
{
|
||||
IsOpen = !IsOpen;
|
||||
Plugin.Config.MainWindowOpen = IsOpen;
|
||||
}
|
||||
|
||||
public override void OnClose()
|
||||
{
|
||||
Plugin.Config.MainWindowOpen = false;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
// First-frame seed: the active tab defaults to the first persisted
|
||||
// tab so the message list isn't empty on a clean session.
|
||||
if (_activeTab is null && Plugin.Config.Tabs.Count > 0)
|
||||
_activeTab = Plugin.Config.Tabs[0];
|
||||
|
||||
var statusHeight = Components.StatusBar.Height;
|
||||
|
||||
using (var body = ImRaii.Child("##hellion-body", new Vector2(-1f, -statusHeight)))
|
||||
{
|
||||
if (body.Success)
|
||||
DrawBody();
|
||||
}
|
||||
|
||||
_status.Draw(_activeTab);
|
||||
}
|
||||
|
||||
private void DrawBody()
|
||||
{
|
||||
var bodyWidth = ImGui.GetContentRegionAvail().X;
|
||||
_honorific.Draw(bodyWidth);
|
||||
|
||||
using (ImRaii.Group())
|
||||
{
|
||||
_sidebar.Draw(bodyWidth, Plugin.Config.Tabs, ref _activeTab);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
using (ImRaii.Group())
|
||||
{
|
||||
DrawMainArea();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMainArea()
|
||||
{
|
||||
var inputHeight = Components.InputBar.Height;
|
||||
|
||||
using (var messages = ImRaii.Child("##hellion-main-area", new Vector2(-1f, -inputHeight)))
|
||||
{
|
||||
if (messages.Success)
|
||||
_messages.Draw(_activeTab!);
|
||||
}
|
||||
|
||||
_input.Draw(_activeTab);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user