Skip to content

Commit 84e3cb4

Browse files
committed
Split IRC-name lightness, and add chat preview
1 parent eecbb9d commit 84e3cb4

8 files changed

Lines changed: 251 additions & 35 deletions

File tree

indra/newview/alavatargroups.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ bool ALAvatarGroups::getIRCChatColor(const LLChat& chat, LLUIColor& color)
322322
return false;
323323
}
324324

325-
bool ALAvatarGroups::getIRCNameColor(const LLChat& chat, const LLUIColor& chat_color, LLUIColor& color)
325+
bool ALAvatarGroups::getIRCNameColor(const LLChat& chat, LLUIColor& color)
326326
{
327327
static LLCachedControl<bool> enabled(gSavedSettings, "AlchemyChatIRCColorsEnabled", false);
328328
if (!enabled)
@@ -337,7 +337,7 @@ bool ALAvatarGroups::getIRCNameColor(const LLChat& chat, const LLUIColor& chat_c
337337
return false;
338338
}
339339

340-
color = dimNameColor(chat_color.get());
340+
color = nameColor(chat.mFromID);
341341
return true;
342342
}
343343

@@ -353,11 +353,11 @@ bool ALAvatarGroups::getIRCNameTagColor(const LLUUID& id, LLColor4& color)
353353
// Mirror the chat-color override: only other agents get a per-avatar color,
354354
// self keeps the user-configured name tag colors. Skip while restricted from
355355
// seeing this avatar's name so the color can't defeat @shownames. The name
356-
// dimming applied to chat names is applied here too so tags match.
356+
// lightness applied to chat names is applied here too so tags match.
357357
if (id.notNull() && id != gAgentID
358358
&& RlvActions::canShowName(RlvActions::SNC_DEFAULT, id))
359359
{
360-
color = dimNameColor(deterministicAgentColor(id));
360+
color = nameColor(id);
361361
return true;
362362
}
363363

@@ -376,17 +376,18 @@ LLColor4 ALAvatarGroups::deterministicAgentColor(const LLUUID& id)
376376
return color;
377377
}
378378

379-
LLColor4 ALAvatarGroups::dimNameColor(const LLColor4& color)
379+
LLColor4 ALAvatarGroups::nameColor(const LLUUID& id)
380380
{
381-
static LLCachedControl<F32> scale(gSavedSettings, "AlchemyChatIRCNameLightnessScale", 0.8f);
382-
383-
F32 hue = 0.f;
384-
F32 saturation = 0.f;
385-
F32 lightness = 0.f;
386-
color.calcHSL(&hue, &saturation, &lightness);
381+
static LLCachedControl<F32> saturation(gSavedSettings, "AlchemyChatIRCAgentSaturation", 0.7f);
382+
static LLCachedControl<F32> name_lightness(gSavedSettings, "AlchemyChatIRCNameLightness", 0.7f);
387383

384+
// Same hue and saturation as the per-agent chat color, but with the name's
385+
// own independent lightness. Built from the same inputs as the chat color
386+
// rather than derived from it, so the chat Lightness slider doesn't bleed
387+
// into the name (a very light/dark chat color loses saturation, and hue at
388+
// the extremes, when round-tripped through RGB).
388389
LLColor4 result;
389-
result.setHSL(hue, saturation, lightness * scale());
390+
result.setHSL(static_cast<F32>(id.getCRC32() % 360) / 360.f, saturation(), name_lightness());
390391
result.mV[VALPHA] = 1.f;
391392

392393
return result;

indra/newview/alavatargroups.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ class ALAvatarGroups final : public LLSingleton < ALAvatarGroups >
6262
// Other message categories (self, system, objects, owner-say) keep their
6363
// user-configured chat colors.
6464
bool getIRCChatColor(const LLChat& chat, LLUIColor& color);
65-
bool getIRCNameColor(const LLChat& chat, const LLUIColor& chat_color, LLUIColor& color);
65+
bool getIRCNameColor(const LLChat& chat, LLUIColor& color);
6666
bool getIRCNameTagColor(const LLUUID& id, LLColor4& color);
6767

6868
private:
6969
LLColor4 deterministicAgentColor(const LLUUID& id);
70-
LLColor4 dimNameColor(const LLColor4& color);
70+
LLColor4 nameColor(const LLUUID& id);
7171
};

indra/newview/app_settings/settings_alchemy.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,16 +431,16 @@
431431
<key>Value</key>
432432
<real>0.9</real>
433433
</map>
434-
<key>AlchemyChatIRCNameLightnessScale</key>
434+
<key>AlchemyChatIRCNameLightness</key>
435435
<map>
436436
<key>Comment</key>
437-
<string>Scales the lightness of the displayed name relative to its IRC-style chat color (0-1).</string>
437+
<string>Lightness of the displayed name in IRC-style chat colors; shares the chat color's hue and saturation (0-1).</string>
438438
<key>Persist</key>
439439
<integer>1</integer>
440440
<key>Type</key>
441441
<string>F32</string>
442442
<key>Value</key>
443-
<real>0.8</real>
443+
<real>0.7</real>
444444
</map>
445445
<key>AlchemyChatMarkUnnamedObjects</key>
446446
<map>

indra/newview/llchathistory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
13391339
LLUIColor txt_color = LLUIColorTable::instance().getColor("White");
13401340
LLUIColor name_color = LLUIColorTable::instance().getColor("ChatHeaderDisplayNameColor"); // <alchemy/>
13411341
LLViewerChat::getChatColor(chat, txt_color, alpha);
1342-
const bool irc_name_color = ALAvatarGroups::instance().getIRCNameColor(chat, txt_color, name_color);
1342+
const bool irc_name_color = ALAvatarGroups::instance().getIRCNameColor(chat, name_color);
13431343

13441344
LLFontGL* fontp = LLViewerChat::getChatFont();
13451345
std::string font_name = LLFontGL::nameFromFont(fontp);

indra/newview/llfloaterpreference.cpp

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@
3434

3535
#include "llfloaterpreference.h"
3636

37+
#include "alavatargroups.h"
3738
#include "llaudioengine.h"
39+
#include "llchat.h"
40+
#include "llstyle.h"
41+
#include "lluicolortable.h"
42+
#include "llviewerchat.h"
3843
#include "message.h"
3944
#include "llfloaterautoreplacesettings.h"
4045
#include "llagent.h"
@@ -74,6 +79,8 @@
7479
#include "llscrolllistitem.h"
7580
#include "llsliderctrl.h"
7681
#include "lltabcontainer.h"
82+
#include "lltextbox.h"
83+
#include "lltexteditor.h"
7784
#include "lltrans.h"
7885
#include "lluri.h"
7986
#include "llviewercontrol.h"
@@ -3066,6 +3073,162 @@ class LLPanelPreferencePrivacy : public LLPanelPreference
30663073
static LLPanelInjector<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics");
30673074
static LLPanelInjector<LLPanelPreferencePrivacy> t_pref_privacy("panel_preference_privacy");
30683075
static LLPanelInjector<LLPanelPreferenceSound> t_pref_sound("panel_preference_sound");
3076+
static LLPanelInjector<LLPanelPreferenceColors> t_pref_colors("panel_preference_colors");
3077+
3078+
bool LLPanelPreferenceColors::postBuild()
3079+
{
3080+
mPreviewEditor = getChild<LLTextEditor>("irc_chat_preview");
3081+
updatePreview();
3082+
return LLPanelPreference::postBuild();
3083+
}
3084+
3085+
void LLPanelPreferenceColors::draw()
3086+
{
3087+
// The chat-color swatches commit straight into LLUIColorTable (no settings
3088+
// signal to listen to), so poll a cheap signature of everything the preview
3089+
// depends on and re-render only when it actually changes.
3090+
static const char* const color_names[] = {
3091+
"UserChatColor", "AgentChatColor", "FriendChatColor", "SystemChatColor",
3092+
"ObjectChatColor", "llOwnerSayChatColor", "LindenChatColor", "HTMLLinkColor",
3093+
};
3094+
std::string signature;
3095+
for (const char* name : color_names)
3096+
{
3097+
const LLColor4& c = LLUIColorTable::instance().getColor(name).get();
3098+
signature += llformat("%.3f,%.3f,%.3f;", c.mV[VRED], c.mV[VGREEN], c.mV[VBLUE]);
3099+
}
3100+
signature += llformat("%d;%.3f;%.3f;%.3f;%d",
3101+
gSavedSettings.getBOOL("AlchemyChatIRCColorsEnabled") ? 1 : 0,
3102+
gSavedSettings.getF32("AlchemyChatIRCAgentSaturation"),
3103+
gSavedSettings.getF32("AlchemyChatIRCAgentLightness"),
3104+
gSavedSettings.getF32("AlchemyChatIRCNameLightness"),
3105+
gSavedSettings.getBOOL("Use24HourClock") ? 1 : 0);
3106+
3107+
if (signature != mPreviewSignature)
3108+
{
3109+
mPreviewSignature = signature;
3110+
updatePreview();
3111+
}
3112+
3113+
LLPanelPreference::draw();
3114+
}
3115+
3116+
void LLPanelPreferenceColors::updatePreview()
3117+
{
3118+
if (!mPreviewEditor)
3119+
return;
3120+
3121+
// One line per chat category the panel above exposes. Each carries the base
3122+
// color the real getChatColor() switch would pick (friend/Linden can't be
3123+
// detected from a fake id, so we set it explicitly), plus a stable id so the
3124+
// per-avatar IRC color stays constant between refreshes. The IRC override and
3125+
// name dimming are then applied through the real ALAvatarGroups calls, so the
3126+
// preview tracks the live colors and settings exactly like in-world local chat.
3127+
enum EKind { K_SYSTEM, K_SELF, K_RESIDENT, K_FRIEND, K_LINDEN, K_OBJECT, K_OWNER };
3128+
static const struct
3129+
{
3130+
EKind kind;
3131+
const char* color; // base text color name
3132+
const char* id; // stable per-avatar id (empty for system/self)
3133+
S32 hour; // mock 24h timestamp, formatted per Use24HourClock
3134+
S32 minute;
3135+
const char* name; // speaker name ("" hides the name prefix)
3136+
const char* text;
3137+
} samples[] = {
3138+
{ K_SYSTEM, "SystemChatColor", "", 13, 42, "", "Welcome to Quirk Island. Mind the dancing llamas." },
3139+
{ K_SELF, "UserChatColor", "", 13, 43, "You", "ok who moved my virtual cheese" },
3140+
{ K_RESIDENT, "AgentChatColor", "a1a1a1a1-0000-0000-0000-000000000001", 13, 44, "Bartholomew Bumblecrash", "anyone else seeing the sky do the wobble thing?" },
3141+
{ K_RESIDENT, "AgentChatColor", "f6f6f6f6-0000-0000-0000-000000000006", 13, 45, "Wandering Pixel", "https://marketplace.secondlife.com/" },
3142+
{ K_FRIEND, "FriendChatColor", "b2b2b2b2-0000-0000-0000-000000000002", 13, 46, "Glittertoes McSparkle", "omg hi!! brb taming a baby dragon" },
3143+
{ K_LINDEN, "LindenChatColor", "c3c3c3c3-0000-0000-0000-000000000003", 13, 47, "Governor Linden", "Rolling restart in 5, hold onto your hats." },
3144+
{ K_OBJECT, "ObjectChatColor", "d4d4d4d4-0000-0000-0000-000000000004", 13, 48, "Object", "Welcome to Help Island!" },
3145+
{ K_OWNER, "llOwnerSayChatColor", "e5e5e5e5-0000-0000-0000-000000000005", 13, 49, "Animation HUD", "Memory Free: 2167 KiB :)" },
3146+
};
3147+
3148+
static const LLUIColor time_color = LLUIColorTable::instance().getColor("ChatHeaderTimestampColor");
3149+
const bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
3150+
3151+
mPreviewEditor->clear(); // clear before re-appending
3152+
3153+
bool prepend_newline = false; // newline before every line except the first
3154+
for (const auto& s : samples)
3155+
{
3156+
LLChat chat;
3157+
chat.mFromName = s.name;
3158+
chat.mText = s.text;
3159+
switch (s.kind)
3160+
{
3161+
case K_SYSTEM:
3162+
chat.mSourceType = CHAT_SOURCE_SYSTEM;
3163+
break;
3164+
case K_SELF:
3165+
chat.mSourceType = CHAT_SOURCE_AGENT;
3166+
chat.mFromID = gAgentID;
3167+
break;
3168+
case K_OBJECT:
3169+
chat.mSourceType = CHAT_SOURCE_OBJECT;
3170+
chat.mFromID = LLUUID(s.id);
3171+
break;
3172+
case K_OWNER:
3173+
chat.mSourceType = CHAT_SOURCE_OBJECT;
3174+
chat.mChatType = CHAT_TYPE_OWNER;
3175+
chat.mFromID = LLUUID(s.id);
3176+
break;
3177+
default: // resident / friend / Linden are all "other agents"
3178+
chat.mSourceType = CHAT_SOURCE_AGENT;
3179+
chat.mFromID = LLUUID(s.id);
3180+
break;
3181+
}
3182+
3183+
// Base category color, then the live IRC overrides (mirrors getChatColor +
3184+
// getIRCNameColor in llchathistory.cpp). getIRCChatColor only recolors other
3185+
// agents, so self/system/object/owner keep their configured color. Names are
3186+
// clickable SLURLs in chat, so by default they take the link color; when IRC
3187+
// coloring is on, getIRCNameColor overrides that with the per-agent name color.
3188+
LLUIColor txt_color = LLUIColorTable::instance().getColor(s.color);
3189+
ALAvatarGroups::instance().getIRCChatColor(chat, txt_color);
3190+
3191+
LLUIColor name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
3192+
ALAvatarGroups::instance().getIRCNameColor(chat, name_color);
3193+
3194+
// Timestamp prefix, like nearby chat: "[hh:mm] ", honoring the
3195+
// Use24HourClock pref the way LLFloaterIMSessionTab::appendTime() does.
3196+
std::string time_str;
3197+
if (use_24h)
3198+
{
3199+
time_str = llformat("%d:%02d", s.hour, s.minute);
3200+
}
3201+
else
3202+
{
3203+
S32 h12 = s.hour % 12;
3204+
if (h12 == 0) h12 = 12;
3205+
time_str = llformat("%d:%02d %s", h12, s.minute, s.hour < 12 ? "AM" : "PM");
3206+
}
3207+
3208+
LLStyle::Params time_style;
3209+
time_style.color(time_color);
3210+
time_style.readonly_color(time_color);
3211+
mPreviewEditor->appendText("[" + time_str + "] ", prepend_newline, time_style);
3212+
prepend_newline = false; // keep the rest of the line attached to the timestamp
3213+
3214+
if (!chat.mFromName.empty())
3215+
{
3216+
LLStyle::Params name_style;
3217+
name_style.color(name_color);
3218+
name_style.readonly_color(name_color);
3219+
mPreviewEditor->appendText(chat.mFromName + ": ", prepend_newline, name_style);
3220+
}
3221+
3222+
// parse_urls is set on the widget, so any URL in the text is linkified
3223+
// (and colored HTMLLinkColor) automatically by appendText.
3224+
LLStyle::Params text_style;
3225+
text_style.color(txt_color);
3226+
text_style.readonly_color(txt_color);
3227+
mPreviewEditor->appendText(chat.mText, prepend_newline, text_style);
3228+
3229+
prepend_newline = true;
3230+
}
3231+
}
30693232

30703233
bool LLPanelPreferenceSound::postBuild()
30713234
{

indra/newview/llfloaterpreference.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class LLScrollListCell;
5353
class LLSliderCtrl;
5454
class LLSD;
5555
class LLTextBox;
56+
class LLTextEditor;
5657
struct skin_t;
5758

5859
namespace ll
@@ -388,6 +389,27 @@ class LLPanelPreferenceSound : public LLPanelPreference
388389
boost::signals2::scoped_connection mDevicesChangedConn;
389390
};
390391

392+
// Colors > Chat preferences panel. Renders a live mock-chat preview that
393+
// re-colors whenever a chat-color swatch or any AlchemyChatIRC* setting
394+
// changes, using the real chat-color path so it matches in-world local chat.
395+
class LLPanelPreferenceColors : public LLPanelPreference
396+
{
397+
LOG_CLASS(LLPanelPreferenceColors);
398+
public:
399+
bool postBuild() override;
400+
void draw() override;
401+
402+
private:
403+
void updatePreview();
404+
405+
LLTextEditor* mPreviewEditor = nullptr;
406+
407+
// Signature of the colors/settings the preview depends on. The chat-color
408+
// swatches commit straight into LLUIColorTable (no settings signal), so
409+
// draw() polls this and re-renders only when it actually changes.
410+
std::string mPreviewSignature;
411+
};
412+
391413
class LLPanelPreferenceControls : public LLPanelPreference, public LLKeyBindResponderInterface
392414
{
393415
LOG_CLASS(LLPanelPreferenceControls);

indra/newview/skins/default/xui/en/floater_preferences.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
help_topic="preferences_msgs_tab"
145145
name="msgs" />
146146
<panel
147-
class="panel_preference"
147+
class="panel_preference_colors"
148148
filename="panel_preferences_colors.xml"
149149
label="Colors"
150150
layout="topleft"

0 commit comments

Comments
 (0)