Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8aeb9164c3 | |||
| a46d89c197 | |||
| 57b6ead003 | |||
| a42cc2a97e | |||
| 96ff4ddfd8 | |||
| 0bfe3a62cb | |||
| 01a7f9b4ec | |||
| 0237602ab7 | |||
| a600f014eb | |||
| a35067f80a | |||
| 74b07519f5 | |||
| 8dade8c4b2 |
@@ -0,0 +1,9 @@
|
||||
---
|
||||
subtitle: "Theme-Crossfade, Quick-Picker, Hover-Animationen"
|
||||
versionsnatur: "Polish & Motion"
|
||||
---
|
||||
- **Theme-Crossfade.** Theme-Wechsel blenden jetzt sanft über rund 300 ms ineinander, statt hart umzuschalten. Alle Hellion-Flächen gleiten mit: Sidebar, Titel, Buttons, Tabs, Scrollbar, Trennlinien. Der Fenster-Hintergrund snappt bewusst weiter, damit das Per-Window-Deckkraft-Setting aus Dalamuds Pinning-Menü unangetastet bleibt.
|
||||
- **Header-Quick-Picker.** Neuer Paletten-Button links vom Zahnrad im Chat-Header. Ein Klick öffnet ein kompaktes Popup mit zwei Sektionen: alle Built-in- und Custom-Themes sowie alle Tabs. Der aktive Eintrag trägt ein Häkchen, ein Klick wechselt ohne das Popup zu schließen. So lassen sich mehrere Wechsel hintereinander erledigen, ohne den Umweg über die Einstellungen.
|
||||
- **Sanfte Hover-Animationen.** Sidebar-Icons faden bei Hover sanft von gedimmt auf volle Deckkraft. Card-Mode-Trennlinien heben sich beim Überfahren einer Zeile für den ganzen Tab dezent ab. Beides framerate-unabhängig gerechnet, also auch bei Wine-Stall-Frames stabil.
|
||||
- **Bewegung reduzieren.** Neuer Toggle im Tab für Theme und Layout. Er deaktiviert Crossfade, Hover-Animationen und das Pulsieren ungelesener Tabs für alle, die eine statische Oberfläche bevorzugen.
|
||||
- Drei P3-Items plus der Accessibility-Toggle, kein Schema-Bump, keine Migration. Eine kleine Polish-Welle vor den größeren Cycles.
|
||||
@@ -485,6 +485,17 @@ public class Tab
|
||||
[NonSerialized]
|
||||
internal string? _cachedTellIcon;
|
||||
|
||||
// PM-3 hover-lerp state. Default 0f means "not hovered". Sidebar
|
||||
// path animates per tab; card-mode-border path is tab-aggregate
|
||||
// (any card-row hover ramps the alpha for all cards in this tab).
|
||||
// Lerp speed lives in the render loop, not here, so the same field
|
||||
// serves both sites at the same animation curve.
|
||||
[NonSerialized]
|
||||
internal float _hoverAlpha;
|
||||
|
||||
[NonSerialized]
|
||||
internal float _cardHoverAlpha;
|
||||
|
||||
public bool Matches(Message message)
|
||||
{
|
||||
if (!message.Matches(SelectedChannels, ExtraChatAll, ExtraChatChannels))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Dalamud.NET.Sdk/15.0.0">
|
||||
<PropertyGroup>
|
||||
<!-- Independent versioning; see yaml changelog for upstream Chat 2 base -->
|
||||
<Version>1.5.3</Version>
|
||||
<Version>1.5.4</Version>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<!-- Use lock file to pin exact versions -->
|
||||
|
||||
@@ -35,6 +35,44 @@ tags:
|
||||
- Replacement
|
||||
- Privacy
|
||||
changelog: |-
|
||||
**v1.5.4 — Polish and Motion (2026-05-20)**
|
||||
|
||||
A polish cycle: smoother theme switching, faster theme and tab
|
||||
access, and subtle hover motion. Three P3 items plus an
|
||||
accessibility toggle.
|
||||
|
||||
User-visible:
|
||||
|
||||
- Theme switches now crossfade smoothly over ~300 ms across every
|
||||
Hellion-rendered surface — sidebar, title, buttons, tabs,
|
||||
scrollbar, separators. The window background snaps deliberately
|
||||
so the per-window opacity override from Dalamud's pinning menu
|
||||
stays untouched.
|
||||
- New header quick-picker: a palette button left of the cog opens
|
||||
a compact popup with two sections — every built-in and custom
|
||||
theme, and every tab. The active entry carries a check glyph;
|
||||
clicking another switches without closing the popup.
|
||||
- Sidebar icons ease their opacity on hover, and card-mode message
|
||||
borders highlight per tab while the cursor is over their rows.
|
||||
Framerate-independent, so a stalled Wine frame cannot overshoot
|
||||
the animation.
|
||||
- New "Reduce motion" toggle in Theme & Layout disables the
|
||||
crossfade, the hover animations and the unread-tab pulse for
|
||||
users who prefer a static UI.
|
||||
|
||||
Under the hood:
|
||||
|
||||
- Two pure-helper lerp paths (ThemeAbgrCacheLerp, FrameLerp) with
|
||||
xUnit coverage in the Build Suite, plus a ColourUtil.ApplyAlpha
|
||||
alpha modulator. Two new /xlperf self-test steps pin the
|
||||
crossfade and quick-picker contracts.
|
||||
|
||||
No schema bump, no migration. Migration v17 stays.
|
||||
|
||||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||||
|
||||
---
|
||||
|
||||
**v1.5.3 — Localisation Wave + Bundled-Font Overhaul (2026-05-19)**
|
||||
|
||||
Multi-language pass plus a long-standing first-frame HITCH lands
|
||||
@@ -194,52 +232,4 @@ changelog: |-
|
||||
|
||||
---
|
||||
|
||||
**v1.5.0 — DI Foundation and Service Refactor (2026-05-17)**
|
||||
|
||||
Major architecture cycle. The plugin bootstrap moves to a
|
||||
generic-host DI container (Microsoft.Extensions.Hosting +
|
||||
IServiceCollection) modelled on Lightless Sync. Service logging
|
||||
moves from a static Plugin.LogProxy locator to typed
|
||||
Microsoft.Extensions.Logging.ILogger<T> via constructor injection,
|
||||
bridged over Dalamud's IPluginLog by a custom DalamudLogger trio.
|
||||
|
||||
What changes under the hood:
|
||||
|
||||
- 18 instance-class services migrate to ILogger<T> via constructor
|
||||
injection across four slices: data layer (MessageStore,
|
||||
MessageManager, AutoTellTabsService), IPC and integrations
|
||||
(HonorificService, IpcManager, TypingIpc, ExtraChat, the three
|
||||
GameFunctions classes), UI window layer (ChatLogWindow,
|
||||
DbViewer, Popout, three settings tabs), and root (Commands,
|
||||
ThemeRegistry, PayloadHandler).
|
||||
- Plugin.LogProxy stays in place for the eight buckets ctor
|
||||
injection cannot reach: static helpers (EmoteCache,
|
||||
AutoTranslate, MemoryUtil, WrapperUtil), Dalamud-reflected
|
||||
types (Configuration), the Message data class, and instance
|
||||
classes that only log from static methods (FontManager, one
|
||||
GameFunctions site).
|
||||
- Plugin.cs finishes at 1012 lines — virtually identical to the
|
||||
pre-cycle 1013. The new Phase-1 host build and Plugin.X bridge
|
||||
wiring trade out exactly the service and window allocations
|
||||
that previously lived in LoadAsync.
|
||||
- Cross-plugin baseline confirms no performance penalty against
|
||||
Chat 2: HellionChat first-frame HITCH 77 ms median, Chat 2
|
||||
74 ms median. Lightless and XIVInstantMessenger sit around
|
||||
7 ms by deferring their font-atlas build past Finished
|
||||
loading — that pattern is the v1.5.1 follow-up.
|
||||
|
||||
User-visible:
|
||||
|
||||
- Slash-command insert fix: pasting a slash command into the
|
||||
chat input (Friend List "/tell" action, plugin-driven inserts
|
||||
from Artisan, AllaganTools etc.) now replaces the existing
|
||||
input instead of concatenating. Cherry-picked from ChatTwo
|
||||
upstream ee7768ac with namespace adaptation.
|
||||
|
||||
Migration v17 stays (no schema bump).
|
||||
|
||||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||||
|
||||
---
|
||||
|
||||
Full history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases
|
||||
|
||||
@@ -19,7 +19,7 @@ internal sealed class ThemeRegistryInitHostedService(ThemeRegistry registry) : I
|
||||
// warm cache; otherwise the first Switch falls through to the built-in
|
||||
// default when Config.Theme points at a custom slug.
|
||||
foreach (var _ in registry.AllCustom()) { }
|
||||
registry.Switch(Plugin.Config.Theme);
|
||||
registry.SwitchSilent(Plugin.Config.Theme);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -330,9 +330,11 @@ public sealed class Plugin : IAsyncDalamudPlugin
|
||||
|
||||
SelfTestRegistry.RegisterTestSteps([
|
||||
new SelfTests.ThemeSwitchSelfTestStep(this),
|
||||
new SelfTests.ThemeCrossfadeSelfTestStep(this),
|
||||
new SelfTests.FontManagerCtorSmokeStep(this),
|
||||
new SelfTests.FontPushSmokeStep(this),
|
||||
new SelfTests.WizardStateSmokeStep(this),
|
||||
new SelfTests.QuickPickerSelfTestStep(this),
|
||||
]);
|
||||
|
||||
// Re-surface the wizard for existing users when a major UX
|
||||
@@ -912,6 +914,7 @@ public sealed class Plugin : IAsyncDalamudPlugin
|
||||
// Theme engine is always active; Classic is a theme, not a disabled state.
|
||||
using IDisposable _style = HellionStyle.PushGlobal(
|
||||
ThemeRegistry.Active,
|
||||
ThemeRegistry,
|
||||
Config.WindowOpacity
|
||||
);
|
||||
|
||||
|
||||
@@ -444,4 +444,11 @@ internal class HellionStrings
|
||||
internal static string DbViewer_FullTextToggle => Get(nameof(DbViewer_FullTextToggle));
|
||||
internal static string DbViewer_FullTextToggle_Hint_Indexing => Get(nameof(DbViewer_FullTextToggle_Hint_Indexing));
|
||||
internal static string DbViewer_FullTextToggle_Hint_PhraseMode => Get(nameof(DbViewer_FullTextToggle_Hint_PhraseMode));
|
||||
|
||||
// Hellion Chat — v1.5.4 header quick-picker + reduce-motion toggle
|
||||
internal static string Settings_QuickPicker_Tooltip => Get(nameof(Settings_QuickPicker_Tooltip));
|
||||
internal static string Settings_QuickPicker_Themes_Header => Get(nameof(Settings_QuickPicker_Themes_Header));
|
||||
internal static string Settings_QuickPicker_Tabs_Header => Get(nameof(Settings_QuickPicker_Tabs_Header));
|
||||
internal static string Settings_ThemeAndLayout_ReduceMotion_Name => Get(nameof(Settings_ThemeAndLayout_ReduceMotion_Name));
|
||||
internal static string Settings_ThemeAndLayout_ReduceMotion_Description => Get(nameof(Settings_ThemeAndLayout_ReduceMotion_Description));
|
||||
}
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat mostra les 24 llengües, però l'entrada de xat de FFXIV només admet completament EN, DE, FR i JA. Altres alfabets poden mostrar-se com a caràcters incorrectes en escriure al xat del joc o en enviar missatges.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Selector ràpid de temes i pestanyes</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temes</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Pestanyes</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Redueix el moviment</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Desactiva la transició de temes, les animacions en passar el cursor per la barra lateral i les targetes, i la pulsació de pestanyes no llegides. Els canvis de tema i els estats de cursor s'apliquen a l'instant.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat zobrazuje všech 24 jazyků, ale chatovací vstup FFXIV plně podporuje pouze EN, DE, FR a JA. Ostatní písma se mohou zobrazovat jako poškozené znaky při psaní do herního chatu nebo při odesílání zpráv.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Rychlý výběr motivů a karet</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Motivy</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Karty</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Omezit pohyb</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Vypne prolínání motivů, animace najetí myší na postranní panel a karty a pulzování nepřečtených karet. Změny motivu a stavy najetí myší se použijí okamžitě.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat viser alle 24 sprog, men FFXIV's chatinput understøtter kun EN, DE, FR og JA fuldt ud. Andre skrifter kan vises som forvrængede tegn, når de skrives i spillets chat eller sendes som beskeder.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Hurtigvælger til temaer og faner</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temaer</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Faner</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reducér bevægelse</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Deaktiverer temaovergangen, hover-animationer for sidepanel og kort samt pulseringen af ulæste faner. Temaskift og hover-tilstande anvendes i stedet med det samme.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,19 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat zeigt alle 24 Sprachen, aber FFXIVs Chat-Eingabe unterstützt nur EN, DE, FR und JA vollständig. Andere Schriften können beim Tippen in den Spiel-Chat oder beim Senden von Nachrichten als unleserliche Zeichen erscheinen.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Schnellauswahl für Themes und Tabs</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Themes</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Tabs</value>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Bewegung reduzieren</value>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Deaktiviert die Theme-Überblendung, die Hover-Animationen von Seitenleiste und Karten sowie das Pulsieren ungelesener Tabs. Theme-Wechsel und Hover-Zustände greifen dann sofort.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>Το HellionChat εμφανίζει και τις 24 γλώσσες, αλλά η εισαγωγή συνομιλίας του FFXIV υποστηρίζει πλήρως μόνο EN, DE, FR και JA. Άλλες γραφές ενδέχεται να εμφανίζονται ως αλλοιωμένοι χαρακτήρες όταν πληκτρολογούνται στη συνομιλία του παιχνιδιού ή αποστέλλονται ως μηνύματα.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Γρήγορη επιλογή θεμάτων και καρτελών</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Θέματα</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Καρτέλες</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Μείωση κίνησης</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Απενεργοποιεί τη σταδιακή εναλλαγή θεμάτων, τα εφέ αιώρησης στην πλαϊνή μπάρα και τις κάρτες, και την παλμική ένδειξη μη αναγνωσμένων καρτελών. Οι αλλαγές θέματος και οι καταστάσεις αιώρησης εφαρμόζονται άμεσα.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat muestra los 24 idiomas, pero la entrada de chat de FFXIV solo admite completamente EN, DE, FR y JA. Otros alfabetos pueden mostrarse como caracteres ilegibles al escribir en el chat del juego o al enviar mensajes.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Selector rápido de temas y pestañas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Pestañas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reducir movimiento</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Desactiva la transición de temas, las animaciones al pasar el cursor por la barra lateral y las tarjetas, y el parpadeo de pestañas no leídas. Los cambios de tema y los estados del cursor se aplican al instante.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat näyttää kaikki 24 kieltä, mutta FFXIV:n chat-syöte tukee täysin vain EN, DE, FR ja JA. Muut kirjoitusjärjestelmät voivat näkyä virheellisinä merkkeinä, kun ne kirjoitetaan pelin chattiin tai lähetetään viesteinä.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Teemojen ja välilehtien pikavalitsin</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Teemat</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Välilehdet</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Vähennä liikettä</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Poistaa käytöstä teeman ristihäivytyksen, sivupalkin ja korttien osoitinanimaatiot sekä lukemattomien välilehtien sykkeen. Teeman vaihdot ja osoitintilat tulevat voimaan välittömästi.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat affiche les 24 langues, mais la saisie de chat de FFXIV ne prend en charge intégralement que EN, DE, FR et JA. Les autres scripts peuvent apparaître comme des caractères illisibles lors de la saisie dans le chat du jeu ou lors de l'envoi de messages.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Sélecteur rapide de thèmes et d'onglets</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Thèmes</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Onglets</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Réduire les animations</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Désactive le fondu enchaîné des thèmes, les animations de survol de la barre latérale et des cartes, ainsi que la pulsation des onglets non lus. Les changements de thème et les états de survol s'appliquent alors instantanément.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>A HellionChat mind a 24 nyelvet megjeleníti, de a FFXIV csevegési bemenete csak az EN, DE, FR és JA nyelveket támogatja teljes mértékben. Más írásrendszerek torzított karakterekként jelenhetnek meg a játék csevegésébe írva vagy üzenetként elküldve.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Témák és lapok gyorsválasztója</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Témák</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Lapok</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Mozgás csökkentése</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Letiltja a témák áttűnését, az oldalsáv és a kártyák rámutatási animációit, valamint az olvasatlan lapok pulzálását. A témaváltások és a rámutatási állapotok ehelyett azonnal érvénybe lépnek.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat mostra tutte le 24 lingue, ma l'input chat di FFXIV supporta completamente solo EN, DE, FR e JA. Altre scritture potrebbero apparire come caratteri illeggibili durante la digitazione nella chat di gioco o l'invio di messaggi.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Selettore rapido di temi e schede</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temi</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Schede</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Riduci movimento</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Disattiva la dissolvenza dei temi, le animazioni al passaggio del mouse su barra laterale e schede e la pulsazione delle schede non lette. I cambi di tema e gli stati al passaggio del mouse vengono applicati immediatamente.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat は 24 言語すべてを表示しますが、FFXIV のチャット入力が完全に対応しているのは EN、DE、FR、JA のみです。他のスクリプトはゲーム内チャットへの入力時やメッセージ送信時に文字化けする可能性があります。</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>テーマとタブのクイックピッカー</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>テーマ</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>タブ</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>モーションを減らす</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>テーマのクロスフェード、サイドバーとカードのホバーアニメーション、未読タブのパルスを無効にします。テーマの切り替えとホバー状態は即座に適用されます。</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat은 24개 언어 모두를 표시하지만, FFXIV의 채팅 입력은 EN, DE, FR, JA만 완전히 지원합니다. 다른 문자 체계는 게임 내 채팅에 입력하거나 메시지로 보낼 때 깨진 문자로 표시될 수 있습니다.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>테마 및 탭 빠른 선택기</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>테마</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>탭</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>모션 줄이기</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>테마 크로스페이드, 사이드바 및 카드 호버 애니메이션, 읽지 않은 탭의 펄스 효과를 비활성화합니다. 테마 전환과 호버 상태가 즉시 적용됩니다.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat viser alle 24 språk, men FFXIVs chat-innmating støtter bare EN, DE, FR og JA fullt ut. Andre skrifter kan vises som forvrengte tegn når de skrives i spillets chat eller sendes som meldinger.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Hurtigvelger for temaer og faner</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temaer</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Faner</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reduser bevegelse</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Deaktiverer temaovergangen, hover-animasjoner for sidepanel og kort samt pulseringen av uleste faner. Temabytter og hover-tilstander brukes i stedet umiddelbart.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat toont alle 24 talen, maar de chat-invoer van FFXIV ondersteunt alleen EN, DE, FR en JA volledig. Andere schriften kunnen als onleesbare tekens verschijnen wanneer ze in de in-game chat worden getypt of als berichten worden verzonden.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Snelkiezer voor thema's en tabbladen</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Thema's</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Tabbladen</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Beweging beperken</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Schakelt de themaovergang, de hover-animaties van de zijbalk en kaarten, en het pulseren van ongelezen tabbladen uit. Themawissels en hover-statussen worden in plaats daarvan direct toegepast.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat wyświetla wszystkie 24 języki, ale wprowadzanie czatu FFXIV w pełni obsługuje tylko EN, DE, FR i JA. Inne systemy pisma mogą być wyświetlane jako zniekształcone znaki podczas wpisywania do czatu w grze lub wysyłania wiadomości.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Szybki wybór motywów i kart</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Motywy</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Karty</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Ogranicz ruch</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Wyłącza płynne przejścia motywów, animacje najechania kursorem na pasek boczny i karty oraz pulsowanie nieprzeczytanych kart. Zmiany motywu i stany najechania są wtedy stosowane natychmiast.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>O HellionChat exibe todos os 24 idiomas, mas a entrada de chat do FFXIV oferece suporte completo apenas para EN, DE, FR e JA. Outros alfabetos podem aparecer como caracteres ilegíveis ao digitar no chat do jogo ou enviar mensagens.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Seletor rápido de temas e abas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Abas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reduzir movimento</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Desativa a transição de temas, as animações de foco da barra lateral e dos cartões e a pulsação de abas não lidas. As trocas de tema e os estados de foco passam a ser aplicados instantaneamente.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>O HellionChat apresenta os 24 idiomas, mas a entrada de chat do FFXIV apenas suporta totalmente EN, DE, FR e JA. Outros alfabetos podem aparecer como caracteres ilegíveis ao escrever no chat do jogo ou enviar mensagens.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Seletor rápido de temas e separadores</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temas</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Separadores</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reduzir movimento</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Desativa a transição de temas, as animações de passagem do rato sobre a barra lateral e os cartões e a pulsação de separadores não lidos. As mudanças de tema e os estados de passagem do rato passam a ser aplicados instantaneamente.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,19 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat renders all 24 languages, but FFXIV's chat input only fully supports EN, DE, FR and JA. Other scripts may display as garbled characters when typed into the in-game chat or sent as messages.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Quick picker for themes and tabs</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Themes</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Tabs</value>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reduce motion</value>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Disables the theme crossfade, the sidebar and card-row hover animations, and the unread-tab pulse. Theme switches and hover states apply instantly instead.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat afișează toate cele 24 de limbi, dar intrarea chatului FFXIV acceptă complet doar EN, DE, FR și JA. Alte scrieri pot apărea ca caractere deteriorate când sunt tastate în chatul jocului sau trimise ca mesaje.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Selector rapid pentru teme și file</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Teme</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>File</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Reducere mișcare</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Dezactivează tranziția temelor, animațiile la trecerea cursorului peste bara laterală și carduri și pulsația filelor necitite. Schimbările de temă și stările de cursor se aplică instantaneu.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat отображает все 24 языка, но ввод чата FFXIV полностью поддерживает только EN, DE, FR и JA. Другие письменности могут отображаться как искажённые символы при наборе во внутриигровом чате или отправке сообщений.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Быстрый выбор тем и вкладок</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Темы</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Вкладки</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Уменьшить движение</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Отключает плавное переключение тем, анимации наведения для боковой панели и карточек, а также пульсацию непрочитанных вкладок. Смена темы и состояния наведения применяются мгновенно.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat visar alla 24 språk, men FFXIV:s chattinmatning stödjer endast EN, DE, FR och JA fullt ut. Andra skriftsystem kan visas som förvrängda tecken när de skrivs i spelets chatt eller skickas som meddelanden.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Snabbväljare för teman och flikar</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Teman</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Flikar</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Minska rörelse</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Inaktiverar temaövergången, hover-animationerna för sidofältet och korten samt pulseringen av olästa flikar. Temabyten och hover-tillstånd tillämpas i stället direkt.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat 24 dilin tümünü gösterir, ancak FFXIV'in sohbet girişi yalnızca EN, DE, FR ve JA dillerini tam olarak destekler. Diğer alfabeler, oyun içi sohbete yazıldığında veya mesaj olarak gönderildiğinde bozuk karakterler olarak görünebilir.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Temalar ve sekmeler için hızlı seçici</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Temalar</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Sekmeler</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Hareketi azalt</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Tema geçişini, kenar çubuğu ve kart vurgulama animasyonlarını ve okunmamış sekme nabzını devre dışı bırakır. Tema değişiklikleri ve vurgulama durumları bunun yerine anında uygulanır.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1033,4 +1033,24 @@
|
||||
<data name="Settings_Language_FFXIVCoverage_Warning" xml:space="preserve">
|
||||
<value>HellionChat відображає всі 24 мови, але введення чату FFXIV повністю підтримує лише EN, DE, FR та JA. Інші писемності можуть відображатися як спотворені символи під час введення в ігровий чат або надсилання повідомлень.</value>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>Швидкий вибір тем і вкладок</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>Теми</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>Вкладки</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>Зменшити рух</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>Вимикає плавне перемикання тем, анімації наведення для бічної панелі та карток, а також пульсацію непрочитаних вкладок. Зміна теми та стани наведення застосовуються миттєво.</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat 显示全部 24 种语言,但 FFXIV 的聊天输入仅完全支持 EN、DE、FR 和 JA。其他文字在游戏内聊天输入或作为消息发送时可能显示为乱码。</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>主题和标签页快速选择器</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>主题</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>标签页</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>减少动态效果</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>禁用主题交叉淡入淡出、侧边栏和卡片的悬停动画以及未读标签页的脉冲效果。主题切换和悬停状态将立即应用。</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1034,4 +1034,24 @@
|
||||
<value>HellionChat 顯示全部 24 種語言,但 FFXIV 的聊天輸入僅完全支援 EN、DE、FR 和 JA。其他文字在遊戲內聊天輸入或作為訊息傳送時可能顯示為亂碼。</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tooltip" xml:space="preserve">
|
||||
<value>佈景主題與分頁快速選擇器</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Themes_Header" xml:space="preserve">
|
||||
<value>佈景主題</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_QuickPicker_Tabs_Header" xml:space="preserve">
|
||||
<value>分頁</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Name" xml:space="preserve">
|
||||
<value>減少動態效果</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
<data name="Settings_ThemeAndLayout_ReduceMotion_Description" xml:space="preserve">
|
||||
<value>停用佈景主題交叉淡入淡出、側邊欄與卡片的滑鼠停留動畫以及未讀分頁的脈衝效果。佈景主題切換與滑鼠停留狀態將立即套用。</value>
|
||||
<comment>AI-assisted machine translation. Pending native-speaker review.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Plugin.SelfTest;
|
||||
using HellionChat.Resources;
|
||||
|
||||
namespace HellionChat.SelfTests;
|
||||
|
||||
// Verifies the v1.5.4 PM-2 quick-picker plumbing without rendering:
|
||||
// resource strings resolve, the theme registry yields the expected
|
||||
// minimum built-in count, and Config.Tabs is populated.
|
||||
internal sealed class QuickPickerSelfTestStep : ISelfTestStep
|
||||
{
|
||||
private readonly Plugin plugin;
|
||||
|
||||
public QuickPickerSelfTestStep(Plugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public string Name => "Hellion Chat - Quick picker plumbing";
|
||||
|
||||
public SelfTestStepResult RunStep()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(HellionStrings.Settings_QuickPicker_Tooltip))
|
||||
{
|
||||
ImGui.Text("Settings_QuickPicker_Tooltip is empty in the active locale.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(HellionStrings.Settings_QuickPicker_Themes_Header))
|
||||
{
|
||||
ImGui.Text("Settings_QuickPicker_Themes_Header is empty in the active locale.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(HellionStrings.Settings_QuickPicker_Tabs_Header))
|
||||
{
|
||||
ImGui.Text("Settings_QuickPicker_Tabs_Header is empty in the active locale.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
var registry = this.plugin.ThemeRegistry;
|
||||
if (registry is null)
|
||||
{
|
||||
ImGui.Text("ThemeRegistry not resolved.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
var builtIns = registry.AllBuiltIns().ToList();
|
||||
if (builtIns.Count < 10)
|
||||
{
|
||||
ImGui.Text($"Expected at least 10 built-in themes, found {builtIns.Count}.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
var tabs = Plugin.Config.Tabs;
|
||||
if (tabs is null || tabs.Count == 0)
|
||||
{
|
||||
ImGui.Text("Config.Tabs is empty.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Pass;
|
||||
}
|
||||
|
||||
public void CleanUp() { }
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Plugin.SelfTest;
|
||||
using HellionChat.Themes;
|
||||
|
||||
namespace HellionChat.SelfTests;
|
||||
|
||||
// Verifies the v1.5.4 PM-1 crossfade contract: switching the active
|
||||
// theme arms TryGetActiveCrossfade for ~300ms, then the registry
|
||||
// returns to direct AbgrCache reads. A second switch within 100ms
|
||||
// keeps the lerped path active (no identity-snap). CleanUp restores
|
||||
// the initial theme so /xlperf stays idempotent.
|
||||
internal sealed class ThemeCrossfadeSelfTestStep : ISelfTestStep
|
||||
{
|
||||
private readonly Plugin plugin;
|
||||
|
||||
private string? initialSlug;
|
||||
private string? targetSlug;
|
||||
private string? midSwitchSlug;
|
||||
private long armedAtTickMs = long.MinValue;
|
||||
private long midArmedAtTickMs = long.MinValue;
|
||||
private bool sawCrossfade;
|
||||
private bool sawMidCrossfadeSwitch;
|
||||
private bool sawCrossfadeEnd;
|
||||
private bool restoredInitial;
|
||||
|
||||
public ThemeCrossfadeSelfTestStep(Plugin plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public string Name => "Hellion Chat - Theme crossfade";
|
||||
|
||||
public SelfTestStepResult RunStep()
|
||||
{
|
||||
var registry = this.plugin.ThemeRegistry;
|
||||
if (registry is null)
|
||||
return SelfTestStepResult.Fail;
|
||||
|
||||
if (this.initialSlug is null)
|
||||
{
|
||||
this.initialSlug = registry.Active.Slug;
|
||||
this.targetSlug = PickDifferentSlug(registry, this.initialSlug);
|
||||
if (this.targetSlug is null)
|
||||
{
|
||||
ImGui.Text("Need at least two themes available; only one built-in found.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
registry.Switch(this.targetSlug);
|
||||
this.armedAtTickMs = Environment.TickCount64;
|
||||
ImGui.Text($"Crossfade armed: {this.initialSlug} -> {this.targetSlug}");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (!this.sawCrossfade)
|
||||
{
|
||||
if (registry.TryGetActiveCrossfade(out _))
|
||||
{
|
||||
this.sawCrossfade = true;
|
||||
this.midArmedAtTickMs = Environment.TickCount64;
|
||||
ImGui.Text("Crossfade observed mid-window, arming mid-switch test...");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
// If the window already closed before we observed it, that
|
||||
// is acceptable only on extremely slow frame paths; accept
|
||||
// it as "saw the start" if more than 300ms have elapsed.
|
||||
// Skip the mid-crossfade-switch phase in that case -- the
|
||||
// lerped path is no longer active, so a second switch would
|
||||
// re-arm a fresh crossfade and not exercise PM-1b's
|
||||
// mid-flight-origin override.
|
||||
if (Environment.TickCount64 - this.armedAtTickMs > 300)
|
||||
{
|
||||
this.sawCrossfade = true;
|
||||
this.sawMidCrossfadeSwitch = true;
|
||||
this.sawCrossfadeEnd = true;
|
||||
ImGui.Text("Crossfade window closed before observation; accepting.");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (!this.sawMidCrossfadeSwitch)
|
||||
{
|
||||
// PM-Test-3 mid-crossfade-switch phase: within ~100ms of the
|
||||
// first observed crossfade, fire a second Switch to a THIRD
|
||||
// theme. ArmCrossfade must compose the current lerped state
|
||||
// as the new origin -- TryGetActiveCrossfade still returns
|
||||
// true (lerped path stays active, no identity-snap) and the
|
||||
// lerped value is neither the identity-from nor the
|
||||
// identity-to of the new switch (origin shifted to the
|
||||
// mid-flight cache, target is the third theme).
|
||||
if (Environment.TickCount64 - this.midArmedAtTickMs < 100)
|
||||
{
|
||||
this.midSwitchSlug = PickDifferentSlug(
|
||||
registry,
|
||||
[this.initialSlug!, this.targetSlug!]
|
||||
);
|
||||
if (this.midSwitchSlug is null)
|
||||
{
|
||||
// Only two themes available -- mid-switch phase cannot
|
||||
// exercise the lerped-origin path. Accept and move on
|
||||
// (the v1.5.3 baseline ships >=10 built-ins, so this
|
||||
// branch is defensive).
|
||||
this.sawMidCrossfadeSwitch = true;
|
||||
ImGui.Text("Only two themes available; skipping mid-switch assert.");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
var fromCache = registry.Active.AbgrCache;
|
||||
registry.Switch(this.midSwitchSlug);
|
||||
var toCache = registry.Active.AbgrCache;
|
||||
|
||||
if (!registry.TryGetActiveCrossfade(out var midLerped))
|
||||
{
|
||||
ImGui.Text("Mid-switch failed: TryGetActiveCrossfade returned false.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
// Lerped value must be neither the new identity-from
|
||||
// (target cache of the first switch) nor the new
|
||||
// identity-to (third theme cache) -- it must originate
|
||||
// from the mid-flight composed snapshot.
|
||||
if (midLerped.Equals(fromCache) || midLerped.Equals(toCache))
|
||||
{
|
||||
ImGui.Text("Mid-switch failed: lerped value is an identity snap.");
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
this.sawMidCrossfadeSwitch = true;
|
||||
ImGui.Text(
|
||||
$"Mid-switch armed: {this.targetSlug} -> {this.midSwitchSlug} (lerped origin)."
|
||||
);
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
// Window for mid-switch already elapsed; accept and continue.
|
||||
this.sawMidCrossfadeSwitch = true;
|
||||
ImGui.Text("Mid-switch window elapsed before fire; accepting.");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (!this.sawCrossfadeEnd)
|
||||
{
|
||||
if (!registry.TryGetActiveCrossfade(out _))
|
||||
{
|
||||
this.sawCrossfadeEnd = true;
|
||||
ImGui.Text("Crossfade window closed cleanly.");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (!this.restoredInitial)
|
||||
{
|
||||
registry.Switch(this.initialSlug);
|
||||
this.restoredInitial = true;
|
||||
ImGui.Text($"Restored: {this.initialSlug}");
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
// Wait for the restore-crossfade to also conclude before
|
||||
// declaring Pass, so /xlperf does not flicker out mid-fade.
|
||||
if (registry.TryGetActiveCrossfade(out _))
|
||||
return SelfTestStepResult.Waiting;
|
||||
|
||||
return SelfTestStepResult.Pass;
|
||||
}
|
||||
|
||||
public void CleanUp()
|
||||
{
|
||||
// Best-effort: if anything went sideways, snap back to the
|
||||
// initial slug. Switch is idempotent on same-slug.
|
||||
var registry = this.plugin.ThemeRegistry;
|
||||
if (registry is not null && this.initialSlug is not null)
|
||||
{
|
||||
registry.Switch(this.initialSlug);
|
||||
}
|
||||
|
||||
this.initialSlug = null;
|
||||
this.targetSlug = null;
|
||||
this.midSwitchSlug = null;
|
||||
this.armedAtTickMs = long.MinValue;
|
||||
this.midArmedAtTickMs = long.MinValue;
|
||||
this.sawCrossfade = false;
|
||||
this.sawMidCrossfadeSwitch = false;
|
||||
this.sawCrossfadeEnd = false;
|
||||
this.restoredInitial = false;
|
||||
}
|
||||
|
||||
private static string? PickDifferentSlug(ThemeRegistry registry, string activeSlug) =>
|
||||
PickDifferentSlug(registry, [activeSlug]);
|
||||
|
||||
private static string? PickDifferentSlug(
|
||||
ThemeRegistry registry,
|
||||
IReadOnlyCollection<string> excludeSlugs
|
||||
)
|
||||
{
|
||||
foreach (var theme in registry.AllBuiltIns())
|
||||
{
|
||||
var match = false;
|
||||
foreach (var excluded in excludeSlugs)
|
||||
{
|
||||
if (string.Equals(theme.Slug, excluded, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
return theme.Slug;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
namespace HellionChat.Themes;
|
||||
|
||||
// Per-slot ABGR byte-lerp between two ThemeAbgrCache value-records.
|
||||
// Pattern anchor: imgui.cpp:2820-2828 ImAlphaBlendColors -- decompose
|
||||
// each byte, lerp via Math.Round, recompose. Stack-allocated output
|
||||
// (readonly record struct), no heap pressure inside the crossfade
|
||||
// window. t is clamped to [0, 1] so float drift cannot overshoot.
|
||||
internal static class ThemeAbgrCacheLerp
|
||||
{
|
||||
public static ThemeAbgrCache Lerp(ThemeAbgrCache from, ThemeAbgrCache to, float t)
|
||||
{
|
||||
t = Math.Clamp(t, 0f, 1f);
|
||||
|
||||
return new ThemeAbgrCache(
|
||||
PrimaryDark: LerpAbgr(from.PrimaryDark, to.PrimaryDark, t),
|
||||
Primary: LerpAbgr(from.Primary, to.Primary, t),
|
||||
PrimaryLight: LerpAbgr(from.PrimaryLight, to.PrimaryLight, t),
|
||||
PrimaryGlow: LerpAbgr(from.PrimaryGlow, to.PrimaryGlow, t),
|
||||
AccentDark: LerpAbgr(from.AccentDark, to.AccentDark, t),
|
||||
Accent: LerpAbgr(from.Accent, to.Accent, t),
|
||||
AccentLight: LerpAbgr(from.AccentLight, to.AccentLight, t),
|
||||
Identity: LerpAbgr(from.Identity, to.Identity, t),
|
||||
WindowBg: LerpAbgr(from.WindowBg, to.WindowBg, t),
|
||||
ChildBg: LerpAbgr(from.ChildBg, to.ChildBg, t),
|
||||
FrameBg: LerpAbgr(from.FrameBg, to.FrameBg, t),
|
||||
Surface: LerpAbgr(from.Surface, to.Surface, t),
|
||||
SurfaceHover: LerpAbgr(from.SurfaceHover, to.SurfaceHover, t),
|
||||
Border: LerpAbgr(from.Border, to.Border, t),
|
||||
TextPrimary: LerpAbgr(from.TextPrimary, to.TextPrimary, t),
|
||||
TextMuted: LerpAbgr(from.TextMuted, to.TextMuted, t),
|
||||
TextDim: LerpAbgr(from.TextDim, to.TextDim, t),
|
||||
StatusSuccess: LerpAbgr(from.StatusSuccess, to.StatusSuccess, t),
|
||||
StatusDanger: LerpAbgr(from.StatusDanger, to.StatusDanger, t),
|
||||
StatusWarning: LerpAbgr(from.StatusWarning, to.StatusWarning, t),
|
||||
StatusInfo: LerpAbgr(from.StatusInfo, to.StatusInfo, t)
|
||||
);
|
||||
}
|
||||
|
||||
private static uint LerpAbgr(uint from, uint to, float t)
|
||||
{
|
||||
var ra = (byte)(from & 0xFFu);
|
||||
var ga = (byte)((from >> 8) & 0xFFu);
|
||||
var ba = (byte)((from >> 16) & 0xFFu);
|
||||
var aa = (byte)((from >> 24) & 0xFFu);
|
||||
|
||||
var rb = (byte)(to & 0xFFu);
|
||||
var gb = (byte)((to >> 8) & 0xFFu);
|
||||
var bb = (byte)((to >> 16) & 0xFFu);
|
||||
var ab = (byte)((to >> 24) & 0xFFu);
|
||||
|
||||
// Math.Round (default ToEven) matches ColourUtil.ApplyAlpha so a
|
||||
// crossfade-into-hover transition does not produce a one-byte
|
||||
// jump at the midpoint between the two paths.
|
||||
var r = (byte)Math.Round(ra + (rb - ra) * t);
|
||||
var g = (byte)Math.Round(ga + (gb - ga) * t);
|
||||
var b = (byte)Math.Round(ba + (bb - ba) * t);
|
||||
var a = (byte)Math.Round(aa + (ab - aa) * t);
|
||||
|
||||
return ((uint)a << 24) | ((uint)b << 16) | ((uint)g << 8) | r;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,16 @@ public sealed class ThemeRegistry
|
||||
private long _lastActiveStampCheckMs = -ActiveStampPollIntervalMs;
|
||||
private DateTime _lastActiveStamp = DateTime.MinValue;
|
||||
|
||||
// PM-1 crossfade state. Switch() captures the previous AbgrCache as a
|
||||
// VALUE-COPY (not a Theme reference) -- the built-in singletons share
|
||||
// their RecomputeAbgrCache identity, so a reference would mutate
|
||||
// alongside the new active. _crossfadeStartTickMs == long.MinValue
|
||||
// means "no crossfade armed yet"; the field stays MinValue after
|
||||
// SwitchSilent so the plugin-load init-path does not trigger a fade.
|
||||
private ThemeAbgrCache? _previousAbgrSnapshot;
|
||||
private long _crossfadeStartTickMs = long.MinValue;
|
||||
private const int CrossfadeDurationMs = 300;
|
||||
|
||||
public ThemeRegistry(string? customThemesDir = null, ILogger<ThemeRegistry>? logger = null)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -87,6 +97,13 @@ public sealed class ThemeRegistry
|
||||
// a state where _active and Get(_active.Slug) disagree.
|
||||
public void Switch(string slug)
|
||||
{
|
||||
// Same-slug switch is a no-op -- avoids a 300ms identity-crossfade
|
||||
// when the user re-selects the active theme in the picker.
|
||||
if (string.Equals(_active.Slug, slug, StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
ArmCrossfade();
|
||||
|
||||
if (_builtIns.TryGetValue(slug, out var builtin))
|
||||
{
|
||||
_active = builtin;
|
||||
@@ -115,6 +132,84 @@ public sealed class ThemeRegistry
|
||||
_activeCustomPath = null;
|
||||
}
|
||||
|
||||
// SwitchSilent is the plugin-load init path -- identical to Switch
|
||||
// but does NOT arm the crossfade state. Called from
|
||||
// ThemeRegistryInitHostedService.StartAsync so opening the plugin
|
||||
// does not produce a 300ms fade from the default theme to the user's
|
||||
// saved theme.
|
||||
public void SwitchSilent(string slug)
|
||||
{
|
||||
if (string.Equals(_active.Slug, slug, StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
if (_builtIns.TryGetValue(slug, out var builtin))
|
||||
{
|
||||
_active = builtin;
|
||||
_active.RecomputeAbgrCache();
|
||||
_activeCustomPath = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var customTheme = LoadCustomBySlug(slug, out var customPath);
|
||||
if (customTheme is not null)
|
||||
{
|
||||
_active = customTheme;
|
||||
_active.RecomputeAbgrCache();
|
||||
_activeCustomPath = customPath;
|
||||
_lastActiveStamp = DateTime.MinValue;
|
||||
return;
|
||||
}
|
||||
|
||||
_active = _builtIns[DefaultSlug];
|
||||
_active.RecomputeAbgrCache();
|
||||
_activeCustomPath = null;
|
||||
}
|
||||
|
||||
// Captures the AbgrCache snapshot that PushGlobal should fade FROM.
|
||||
// If a crossfade is already mid-flight (second Switch within 300ms),
|
||||
// the current lerped state replaces the snapshot -- the next fade
|
||||
// starts from where we currently are, not from the original "from".
|
||||
private void ArmCrossfade()
|
||||
{
|
||||
var now = Environment.TickCount64;
|
||||
ThemeAbgrCache snapshot;
|
||||
if (
|
||||
_previousAbgrSnapshot.HasValue
|
||||
&& _crossfadeStartTickMs != long.MinValue
|
||||
&& now - _crossfadeStartTickMs < CrossfadeDurationMs
|
||||
)
|
||||
{
|
||||
var t = (float)(now - _crossfadeStartTickMs) / CrossfadeDurationMs;
|
||||
snapshot = ThemeAbgrCacheLerp.Lerp(_previousAbgrSnapshot.Value, _active.AbgrCache, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
snapshot = _active.AbgrCache;
|
||||
}
|
||||
|
||||
_previousAbgrSnapshot = snapshot;
|
||||
_crossfadeStartTickMs = now;
|
||||
}
|
||||
|
||||
// Returns the lerped AbgrCache while the crossfade is active.
|
||||
// PushGlobal reads this once per frame; outside the 300ms window
|
||||
// it short-circuits via the TickCount64 delta so the per-frame
|
||||
// overhead is a couple of integer comparisons.
|
||||
public bool TryGetActiveCrossfade(out ThemeAbgrCache lerped)
|
||||
{
|
||||
lerped = default;
|
||||
if (_crossfadeStartTickMs == long.MinValue || !_previousAbgrSnapshot.HasValue)
|
||||
return false;
|
||||
|
||||
var elapsed = Environment.TickCount64 - _crossfadeStartTickMs;
|
||||
if (elapsed >= CrossfadeDurationMs)
|
||||
return false;
|
||||
|
||||
var t = (float)elapsed / CrossfadeDurationMs;
|
||||
lerped = ThemeAbgrCacheLerp.Lerp(_previousAbgrSnapshot.Value, _active.AbgrCache, t);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1Hz-throttled disk-stat on the currently active custom theme file.
|
||||
// When the file's LastWriteTime moves forward (editor save), reload the
|
||||
// theme via Get() so the user sees the edit immediately without
|
||||
|
||||
@@ -472,6 +472,105 @@ public sealed class ChatLogWindow : Window
|
||||
ChangeTab(newIndex);
|
||||
}
|
||||
|
||||
// PM-2b v1.5.4 header quick-picker. Two scrollable sections -- every
|
||||
// built-in plus custom theme, and every tab. Clicking a theme arms
|
||||
// the PM-1 crossfade via ThemeRegistry.Switch; clicking a tab routes
|
||||
// through ChangeTab so LastActivityTime stays consistent with the
|
||||
// sidebar and top-bar click paths. DontClosePopups keeps the popup
|
||||
// open so the user can hop between entries without re-opening it.
|
||||
private void DrawQuickPickerPopup()
|
||||
{
|
||||
using var popup = ImRaii.Popup("##hellion-quick-picker");
|
||||
if (!popup.Success)
|
||||
return;
|
||||
|
||||
ImGui.TextUnformatted(HellionStrings.Settings_QuickPicker_Themes_Header);
|
||||
ImGui.Separator();
|
||||
|
||||
var activeSlug = Plugin.ThemeRegistry.Active.Slug;
|
||||
var allThemes = Plugin
|
||||
.ThemeRegistry.AllBuiltIns()
|
||||
.Concat(Plugin.ThemeRegistry.AllCustom())
|
||||
.ToList();
|
||||
|
||||
using (
|
||||
var scroll = ImRaii.Child(
|
||||
"##hellion-quick-picker-themes",
|
||||
new Vector2(220f, Math.Min(allThemes.Count * 22f, 200f))
|
||||
)
|
||||
)
|
||||
{
|
||||
if (scroll.Success)
|
||||
{
|
||||
foreach (var theme in allThemes)
|
||||
{
|
||||
var isActive = string.Equals(
|
||||
theme.Slug,
|
||||
activeSlug,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
DrawQuickPickerGlyph(isActive);
|
||||
if (
|
||||
ImGui.Selectable(
|
||||
$"{theme.Name}##quick-theme-{theme.Slug}",
|
||||
isActive,
|
||||
ImGuiSelectableFlags.DontClosePopups
|
||||
) && !isActive
|
||||
)
|
||||
Plugin.ThemeRegistry.Switch(theme.Slug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.TextUnformatted(HellionStrings.Settings_QuickPicker_Tabs_Header);
|
||||
ImGui.Separator();
|
||||
|
||||
var tabs = Plugin.Config.Tabs;
|
||||
var activeTabIndex = Plugin.LastTab;
|
||||
using (
|
||||
var scroll = ImRaii.Child(
|
||||
"##hellion-quick-picker-tabs",
|
||||
new Vector2(220f, Math.Min(tabs.Count * 22f, 200f))
|
||||
)
|
||||
)
|
||||
{
|
||||
if (scroll.Success)
|
||||
{
|
||||
for (var i = 0; i < tabs.Count; i++)
|
||||
{
|
||||
var isActive = i == activeTabIndex;
|
||||
DrawQuickPickerGlyph(isActive);
|
||||
if (
|
||||
ImGui.Selectable(
|
||||
$"{tabs[i].Name}##quick-tab-{i}",
|
||||
isActive,
|
||||
ImGuiSelectableFlags.DontClosePopups
|
||||
) && !isActive
|
||||
)
|
||||
ChangeTab(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Leading check-glyph slot for a quick-picker row. Active rows get a
|
||||
// FontAwesome check; inactive rows get a same-width blank so the
|
||||
// labels stay aligned. The glyph font push stays on its own line so
|
||||
// it never bleeds into the body-font Selectable label.
|
||||
private void DrawQuickPickerGlyph(bool isActive)
|
||||
{
|
||||
using (Plugin.FontManager.FontAwesome.Push())
|
||||
{
|
||||
var check = FontAwesomeIcon.Check.ToIconString();
|
||||
if (isActive)
|
||||
ImGui.TextUnformatted(check);
|
||||
else
|
||||
ImGui.Dummy(new Vector2(ImGui.CalcTextSize(check).X, ImGui.GetTextLineHeight()));
|
||||
}
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
private void TabSwitched(Tab newTab, Tab previousTab)
|
||||
{
|
||||
// Use the fixed channel if set by the user. Otherwise, if the new tab
|
||||
@@ -903,7 +1002,15 @@ public sealed class ChatLogWindow : Window
|
||||
var buttonWidth = afterIcon.X - beforeIcon.X;
|
||||
var showNovice = Plugin.Config.ShowNoviceNetwork && GameFunctions.GameFunctions.IsMentor();
|
||||
var buttonsRight = (showNovice ? 1 : 0) + (Plugin.Config.ShowHideButton ? 1 : 0);
|
||||
var inputWidth = ImGui.GetContentRegionAvail().X - buttonWidth * (1 + buttonsRight);
|
||||
// Right-side buttons: quick-picker palette + cog (always present)
|
||||
// plus the optional hide / novice buttons. Each slot costs the
|
||||
// measured button width AND one ItemSpacing for the SameLine gap
|
||||
// in front of it -- leaving the spacing term out overflows the
|
||||
// header row by one gap per button (v1.5.4 quick-picker fix).
|
||||
var rightButtonCount = 2 + buttonsRight;
|
||||
var inputWidth =
|
||||
ImGui.GetContentRegionAvail().X
|
||||
- rightButtonCount * (buttonWidth + ImGui.GetStyle().ItemSpacing.X);
|
||||
|
||||
var normalColor = ImGui.GetColorU32(ImGuiCol.Text);
|
||||
var push = inputColour != null;
|
||||
@@ -1013,6 +1120,19 @@ public sealed class ChatLogWindow : Window
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (
|
||||
ImGuiUtil.IconButton(
|
||||
FontAwesomeIcon.Palette,
|
||||
tooltip: HellionStrings.Settings_QuickPicker_Tooltip,
|
||||
width: (int)buttonWidth
|
||||
)
|
||||
)
|
||||
ImGui.OpenPopup("##hellion-quick-picker");
|
||||
|
||||
DrawQuickPickerPopup();
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGuiUtil.IconButton(FontAwesomeIcon.Cog, width: (int)buttonWidth))
|
||||
Plugin.SettingsWindow.Toggle();
|
||||
|
||||
@@ -1505,15 +1625,19 @@ public sealed class ChatLogWindow : Window
|
||||
var maxLines = Plugin.Config.MaxLinesToRender;
|
||||
var startLine = messages.Count > maxLines ? messages.Count - maxLines : 0;
|
||||
|
||||
// Card-mode pre-loop: theme/drawList/winLeft/winRight/border are invariant
|
||||
// per DrawMessages call; only cursorY moves per row.
|
||||
// Card-mode pre-loop: theme/drawList/winLeft/winRight are
|
||||
// invariant per DrawMessages call. borderColorAbgr used to be
|
||||
// hoisted here too, but PM-3d (v1.5.4) modulates it by
|
||||
// tab._cardHoverAlpha per row, so it moves into the AddLine
|
||||
// call below. anyCardHovered aggregates the row-hover state
|
||||
// across all card-rows; the lerp runs once at the loop end so
|
||||
// the next frame paints with the updated alpha.
|
||||
var theme = Plugin.ThemeRegistry.Active;
|
||||
var drawList = ImGui.GetWindowDrawList();
|
||||
var winLeft = ImGui.GetWindowPos().X;
|
||||
var winRight = winLeft + ImGui.GetWindowSize().X;
|
||||
var borderColorAbgr = ColourUtil.RgbaToAbgr(
|
||||
(theme.Colors.Border & 0xFFFFFF00u) | 0x33u
|
||||
);
|
||||
var baseBorderRgba = (theme.Colors.Border & 0xFFFFFF00u) | 0x33u;
|
||||
var anyCardHovered = false;
|
||||
|
||||
for (var i = startLine; i < messages.Count; i++)
|
||||
{
|
||||
@@ -1669,6 +1793,8 @@ public sealed class ChatLogWindow : Window
|
||||
var useCard = !Plugin.Config.UseCompactDensity;
|
||||
if (useCard)
|
||||
{
|
||||
var rowStartY = ImGui.GetCursorScreenPos().Y;
|
||||
|
||||
if (message.Sender.Count > 0)
|
||||
{
|
||||
var senderColor =
|
||||
@@ -1692,9 +1818,18 @@ public sealed class ChatLogWindow : Window
|
||||
else
|
||||
DrawChunks(message.Content, true, handler, lineWidth);
|
||||
|
||||
// Border bottom as card separator. Alpha reduced to 0x33 for subtlety.
|
||||
// Border bottom as card separator. Base alpha 0x33;
|
||||
// PM-3d lifts it by up to ~+0x70 while any row in this
|
||||
// tab is hovered. _cardHoverAlpha lerps at the loop
|
||||
// end, so the one-frame lag is invisible at 10f speed.
|
||||
{
|
||||
var rowEndY = ImGui.GetCursorScreenPos().Y;
|
||||
var hoverBoost = 0.45f * tab._cardHoverAlpha;
|
||||
var alphaByte = (uint)
|
||||
Math.Clamp((int)(0x33u + hoverBoost * 255f), 0x33, 0xCC);
|
||||
var borderColorAbgr = ColourUtil.RgbaToAbgr(
|
||||
(baseBorderRgba & 0xFFFFFF00u) | alphaByte
|
||||
);
|
||||
drawList.AddLine(
|
||||
new Vector2(winLeft + 4, rowEndY - 1),
|
||||
new Vector2(winRight - 4, rowEndY - 1),
|
||||
@@ -1702,6 +1837,17 @@ public sealed class ChatLogWindow : Window
|
||||
1f
|
||||
);
|
||||
ImGui.Dummy(new Vector2(0, 2));
|
||||
|
||||
// Whole-row hover test. IsItemHovered would only see
|
||||
// the 2px Dummy above, so hit-test the row rect from
|
||||
// its start Y down to the separator line instead.
|
||||
if (
|
||||
ImGui.IsMouseHoveringRect(
|
||||
new Vector2(winLeft, rowStartY),
|
||||
new Vector2(winRight, rowEndY)
|
||||
)
|
||||
)
|
||||
anyCardHovered = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1726,6 +1872,20 @@ public sealed class ChatLogWindow : Window
|
||||
|
||||
message.IsVisible[tab.Identifier] = ImGui.IsItemVisible();
|
||||
}
|
||||
|
||||
// PM-3d: update the per-tab card-hover lerp once per
|
||||
// DrawMessages call. ReduceMotion snaps to the target;
|
||||
// otherwise the border alpha eases toward it over a few
|
||||
// frames the next time the rows paint.
|
||||
var cardTarget = anyCardHovered ? 1f : 0f;
|
||||
tab._cardHoverAlpha = Plugin.Config.ReduceMotion
|
||||
? cardTarget
|
||||
: FrameLerp.Smooth(
|
||||
tab._cardHoverAlpha,
|
||||
cardTarget,
|
||||
speed: 10f,
|
||||
deltaTime: ImGui.GetIO().DeltaTime
|
||||
);
|
||||
}
|
||||
catch (ApplicationException)
|
||||
{
|
||||
@@ -1976,7 +2136,19 @@ public sealed class ChatLogWindow : Window
|
||||
ColourUtil.RgbaToAbgr(theme.Colors.Surface)
|
||||
)
|
||||
)
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(iconColor)))
|
||||
// PM-3c: icon alpha eases from 40% (dim) to 100% on
|
||||
// hover. _hoverAlpha lerps at the end of this block,
|
||||
// so the colour for frame N uses frame N-1's value --
|
||||
// a sub-frame lag that is invisible at 10f speed.
|
||||
using (
|
||||
ImRaii.PushColor(
|
||||
ImGuiCol.Text,
|
||||
ColourUtil.ApplyAlpha(
|
||||
ColourUtil.RgbaToAbgr(iconColor),
|
||||
0.4f + 0.6f * tab._hoverAlpha
|
||||
)
|
||||
)
|
||||
)
|
||||
using (Plugin.FontManager.FontAwesome.Push())
|
||||
{
|
||||
// Button stretches with the configured sidebar width so a
|
||||
@@ -1988,6 +2160,19 @@ public sealed class ChatLogWindow : Window
|
||||
);
|
||||
}
|
||||
|
||||
// PM-3c hover-lerp: ramp _hoverAlpha toward 1 while the
|
||||
// icon button is hovered, back to 0 otherwise.
|
||||
// ReduceMotion snaps so the dim/full states stay binary.
|
||||
var hoverTarget = ImGui.IsItemHovered() ? 1f : 0f;
|
||||
tab._hoverAlpha = Plugin.Config.ReduceMotion
|
||||
? hoverTarget
|
||||
: FrameLerp.Smooth(
|
||||
tab._hoverAlpha,
|
||||
hoverTarget,
|
||||
speed: 10f,
|
||||
deltaTime: ImGui.GetIO().DeltaTime
|
||||
);
|
||||
|
||||
if (isCurrentTab)
|
||||
{
|
||||
// Vertical accent pill on the left window edge, 3px wide, half tab height,
|
||||
|
||||
@@ -33,11 +33,31 @@ internal static class HellionStyle
|
||||
|
||||
// Global color and style stack pushed once per frame.
|
||||
// windowOpacity: window background alpha (0.5-1.0).
|
||||
internal static IDisposable PushGlobal(Theme theme, float windowOpacity = 1.0f)
|
||||
internal static IDisposable PushGlobal(
|
||||
Theme theme,
|
||||
ThemeRegistry registry,
|
||||
float windowOpacity = 1.0f
|
||||
)
|
||||
{
|
||||
var c = theme.Colors;
|
||||
var l = theme.Layout;
|
||||
var a = theme.AbgrCache;
|
||||
|
||||
// Crossfade: PM-1 reads a lerped snapshot during the 300ms window
|
||||
// following a Switch (TryGetActiveCrossfade returns false outside
|
||||
// the window or while ReduceMotion is on). Only the ABGR-slot path
|
||||
// crossfades -- WindowBg/ChildBg RGBA stays bound to the user's
|
||||
// per-window opacity override and must not fade. See
|
||||
// feedback_dalamud_pinning_override.
|
||||
ThemeAbgrCache a;
|
||||
if (!Plugin.Config.ReduceMotion && registry.TryGetActiveCrossfade(out var lerped))
|
||||
{
|
||||
a = lerped;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = theme.AbgrCache;
|
||||
}
|
||||
|
||||
var stack = new StackHandle();
|
||||
|
||||
var alphaByte = (uint)Math.Clamp((int)(windowOpacity * 255f), 0x55, 0xFF);
|
||||
|
||||
@@ -295,6 +295,20 @@ internal sealed class ThemeAndLayout : ISettingsTab
|
||||
Mutable.WindowOpacity = opacityPercent / 100f;
|
||||
}
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Settings_ThemeAndLayout_WindowOpacity_Description);
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
// Master accessibility toggle for the v1.5.4 motion work: the
|
||||
// theme crossfade, the sidebar/card hover lerps and the
|
||||
// unread-tab pulse all read Config.ReduceMotion and snap
|
||||
// instantly when it is on.
|
||||
ImGui.Checkbox(
|
||||
HellionStrings.Settings_ThemeAndLayout_ReduceMotion_Name,
|
||||
ref Mutable.ReduceMotion
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Settings_ThemeAndLayout_ReduceMotion_Description);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,18 @@ internal static class ColourUtil
|
||||
return ((uint)a << 24) | ((uint)nb << 16) | ((uint)ng << 8) | nr;
|
||||
}
|
||||
|
||||
// Modulates the alpha byte of an ABGR color by a factor in [0, 1].
|
||||
// RGB stays intact. Used by the PM-3 hover-lerp path where each
|
||||
// frame produces a fractional alpha value but the colour itself
|
||||
// must not shift.
|
||||
internal static uint ApplyAlpha(uint abgr, float alphaFactor)
|
||||
{
|
||||
alphaFactor = Math.Clamp(alphaFactor, 0f, 1f);
|
||||
var origAlpha = (byte)((abgr >> 24) & 0xFFu);
|
||||
var newAlpha = (byte)Math.Round(origAlpha * alphaFactor);
|
||||
return (abgr & 0x00FFFFFFu) | ((uint)newAlpha << 24);
|
||||
}
|
||||
|
||||
public static uint HexToRgba(string hex)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(hex);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace HellionChat.Util;
|
||||
|
||||
// Framerate-independent smoothing for per-frame hover and motion
|
||||
// values. Pattern anchor: Umbra Toolbar.Autohide.cs:55
|
||||
// (`v += (target - v) * deltaTime`). The Math.Min(1f, speed*dt)
|
||||
// clamp is a deliberate HellionChat addition -- on Wine/DXVK a
|
||||
// stalled frame can push deltaTime well over 16ms, which would
|
||||
// otherwise let the raw factor exceed 1.0 and overshoot the target.
|
||||
// Clamping makes a stalled frame land exactly on target instead.
|
||||
internal static class FrameLerp
|
||||
{
|
||||
public static float Smooth(float current, float target, float speed, float deltaTime)
|
||||
{
|
||||
var factor = Math.Min(1f, speed * deltaTime);
|
||||
return current + (target - current) * factor;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/actions/workflows/build.yml)
|
||||
[](LICENSE)
|
||||
[](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/latest)
|
||||
[](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/latest)
|
||||
[](https://github.com/goatcorp/Dalamud)
|
||||
[](https://dotnet.microsoft.com/)
|
||||
[](https://www.finalfantasyxiv.com/)
|
||||
@@ -11,7 +11,7 @@
|
||||
<img src="docs/images/hellion-forge.png" alt="Hellion Forge" width="180" />
|
||||
</p>
|
||||
|
||||
**Version 1.5.3** — Privacy-first chat plugin for FINAL FANTASY XIV / Dalamud, built on
|
||||
**Version 1.5.4** — Privacy-first chat plugin for FINAL FANTASY XIV / Dalamud, built on
|
||||
[Chat 2](https://github.com/Infiziert90/ChatTwo) (EUPL-1.2).
|
||||
|
||||
Hellion Chat is a privacy-first plugin built on the Chat 2 foundation. The majority of the engine
|
||||
@@ -299,6 +299,22 @@ An optional submission to the Dalamud main plugin repo (in addition to the custo
|
||||
|
||||
## Project Status
|
||||
|
||||
**Version 1.5.4** — Polish and Motion. Theme switches now crossfade smoothly over
|
||||
~300 ms across every Hellion-rendered surface — sidebar, title, buttons, tabs,
|
||||
scrollbar, separators. The window background snaps deliberately so the per-window
|
||||
opacity override from Dalamud's pinning menu stays intact. A new header quick-picker —
|
||||
a palette button left of the cog — opens a compact popup that switches themes and tabs
|
||||
without opening Settings; the active entry carries a check glyph and the popup stays
|
||||
open between picks. Sidebar icons ease their opacity on hover and card-mode message
|
||||
borders highlight per tab, both framerate-independent so a stalled Wine frame cannot
|
||||
overshoot. A new "Reduce motion" toggle in Theme & Layout disables the crossfade, the
|
||||
hover animations and the unread-tab pulse for users who prefer a static UI. No schema
|
||||
bump, migration v17 stays.
|
||||
|
||||
---
|
||||
|
||||
### Project status (pre-v1.5.4, kept for context)
|
||||
|
||||
**Version 1.5.3** — Localisation Wave + Bundled-Font Overhaul. Twenty-four selectable UI languages
|
||||
(Catalan, Czech, Danish, Dutch, English, Finnish, French, German, Greek, Hungarian, Italian,
|
||||
Japanese, Korean, Norsk bokmål, Polish, Portuguese (Brazil), Portuguese (Portugal), Romanian,
|
||||
@@ -319,8 +335,6 @@ EN/DE/FR/JA — other languages may garble when typed in-game. Migration v17 sta
|
||||
|
||||
---
|
||||
|
||||
### Project status (pre-v1.5.3, kept for context)
|
||||
|
||||
**Version 1.5.2** — First-Run Wizard Rework. The single-page wizard becomes a four-step
|
||||
staged-commit flow (Welcome → Privacy → Power Settings → Done). The privacy picker becomes a 2×2
|
||||
grid with a fourth profile "Roleplay" that extends Privacy-First with `Say` and both emote types
|
||||
|
||||
@@ -11,6 +11,17 @@ releases as an overview and links to the release pages for details.
|
||||
|
||||
---
|
||||
|
||||
## Hellion Chat 1.5.4 — Polish and Motion (2026-05-20)
|
||||
|
||||
A polish cycle of three P3 items. Theme switches now crossfade smoothly over ~300 ms
|
||||
across every Hellion-rendered surface; the window background snaps deliberately so the
|
||||
per-window opacity override from Dalamud's pinning menu stays intact. A new header
|
||||
quick-picker — a palette button left of the cog — opens a compact popup for switching
|
||||
themes and tabs without opening Settings. Sidebar icons and card-mode message borders
|
||||
gain framerate-independent hover animations. A new "Reduce motion" toggle in Theme &
|
||||
Layout disables the crossfade, hover animations and unread-tab pulse for accessibility.
|
||||
No schema bump, migration v17 stays.
|
||||
|
||||
## Hellion Chat 1.5.3 — Localisation Wave + Bundled-Font Overhaul (2026-05-19)
|
||||
|
||||
Multi-language pass plus a long-standing first-frame HITCH lands as a side effect of a font-stack
|
||||
|
||||
@@ -22,6 +22,18 @@ parallel as a continuous correction pass, gathered via the Hellion Forge Discord
|
||||
|
||||
---
|
||||
|
||||
## v1.5.4 — Polish and Motion (released 2026-05-20)
|
||||
|
||||
A polish cycle of three P3 items. Theme switches crossfade over ~300 ms across every
|
||||
Hellion-rendered surface; the window background snaps deliberately to preserve the
|
||||
per-window opacity override from Dalamud's pinning menu. A header quick-picker — a
|
||||
palette button left of the cog — switches themes and tabs from a compact popup without
|
||||
opening Settings. Sidebar icons and card-mode borders gain framerate-independent hover
|
||||
animations. A new "Reduce motion" toggle in Theme & Layout covers accessibility. No
|
||||
schema bump; migration v17 stays.
|
||||
|
||||
---
|
||||
|
||||
## v1.5.3 — Localisation Wave + Bundled-Font Overhaul (released 2026-05-19)
|
||||
|
||||
Twenty-four selectable UI languages: from FR-only as the original plan scope, the cycle expanded to
|
||||
|
||||
Reference in New Issue
Block a user