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.
122 lines
3.6 KiB
C#
122 lines
3.6 KiB
C#
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);
|
|
}
|
|
}
|