From 26191110745b24623f09cf6f03634c7ef9a7f5d4 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Sun, 10 Mar 2024 21:28:43 -0400 Subject: [PATCH] Add color table debug floater --- indra/llui/lluicolortable.cpp | 34 ++ indra/llui/lluicolortable.h | 7 + indra/newview/CMakeLists.txt | 2 + indra/newview/alfloatersettingscolor.cpp | 333 ++++++++++++++++++ indra/newview/alfloatersettingscolor.h | 81 +++++ .../newview/app_settings/settings_alchemy.xml | 11 + indra/newview/llviewerfloaterreg.cpp | 2 + .../default/xui/en/floater_settings_color.xml | 117 ++++++ .../skins/default/xui/en/menu_login.xml | 7 + .../skins/default/xui/en/menu_viewer.xml | 9 +- 10 files changed, 602 insertions(+), 1 deletion(-) create mode 100644 indra/newview/alfloatersettingscolor.cpp create mode 100644 indra/newview/alfloatersettingscolor.h create mode 100644 indra/newview/skins/default/xui/en/floater_settings_color.xml diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 87d76e84cec..8f660fd3144 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -201,6 +201,40 @@ void LLUIColorTable::setColor(std::string_view name, const LLColor4& color) setColor(name, color, mUserSetColors); } +bool LLUIColorTable::isDefault(std::string_view name) const +{ + string_color_map_t::const_iterator base_iter = mLoadedColors.find(name); + string_color_map_t::const_iterator user_iter = mUserSetColors.find(name); + if (base_iter != mLoadedColors.end()) + { + if(user_iter != mUserSetColors.end()) + return user_iter->second == base_iter->second; + + return true; + } + else if (user_iter != mUserSetColors.end()) // user only color ??? + { + return true; + } + + return false; +} + +void LLUIColorTable::resetToDefault(std::string_view name) +{ + string_color_map_t::iterator iter = mUserSetColors.find(name); + + if (iter != mUserSetColors.end()) + { + auto default_iter = mLoadedColors.find(name); + + if (default_iter != mLoadedColors.end()) + { + iter->second = default_iter->second.get(); + } + } +} + bool LLUIColorTable::loadFromSettings() { bool result = false; diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 7f2ae3150af..6bba1bcae3c 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -85,12 +85,19 @@ class LLUIColorTable final : public LLSingleton<LLUIColorTable> // returns true if color_name exists in the table bool colorExists(std::string_view color_name) const; + bool isDefault(std::string_view color_name) const; + + void resetToDefault(std::string_view color_name); + // loads colors from settings files bool loadFromSettings(); // saves colors specified by the user to the users skin directory void saveUserSettings(const bool scrub = false) const; + const auto& getLoadedColors() { return mLoadedColors; } + const auto& getUserColors() { return mUserSetColors; } + private: bool loadFromFilename(const std::string& filename, string_color_map_t& table); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 49fa4980db2..355611a0a84 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -96,6 +96,7 @@ set(viewer_SOURCE_FILES alfloaterlightbox.cpp alfloaterparticleeditor.cpp alfloaterregiontracker.cpp + alfloatersettingscolor.cpp alpanelaomini.cpp alpanelaopulldown.cpp alpanelmusicticker.cpp @@ -831,6 +832,7 @@ set(viewer_HEADER_FILES alfloaterlightbox.h alfloaterparticleeditor.h alfloaterregiontracker.h + alfloatersettingscolor.h alpanelaomini.h alpanelaopulldown.h alpanelmusicticker.h diff --git a/indra/newview/alfloatersettingscolor.cpp b/indra/newview/alfloatersettingscolor.cpp new file mode 100644 index 00000000000..fc38ffdc80a --- /dev/null +++ b/indra/newview/alfloatersettingscolor.cpp @@ -0,0 +1,333 @@ +/** + * @file alfloatersettingscolor.cpp + * @brief floater for debugging internal viewer colors + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Alchemy Viewer Source Code + * Copyright (C) 2024, Rye Mutt<rye@alchemyviewer.org>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "alfloatersettingscolor.h" +#include "llfloater.h" +#include "llfiltereditor.h" +#include "lluictrlfactory.h" +#include "llcombobox.h" +// [RLVa:KB] - Patch: RLVa-2.1.0 +#include "llsdserialize.h" +// [/RLVa:KB] +#include "llspinctrl.h" +#include "llcolorswatch.h" +#include "llviewercontrol.h" +#include "lltexteditor.h" + + +ALFloaterSettingsColor::ALFloaterSettingsColor(const LLSD& key) +: LLFloater(key), + mSettingList(NULL) +{ + mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&ALFloaterSettingsColor::onCommitSettings, this)); + mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&ALFloaterSettingsColor::onClickDefault, this)); +} + +ALFloaterSettingsColor::~ALFloaterSettingsColor() +{} + +BOOL ALFloaterSettingsColor::postBuild() +{ + enableResizeCtrls(true, false, true); + + mAlphaSpinner = getChild<LLSpinCtrl>("alpha_spinner"); + mColorSwatch = getChild<LLColorSwatchCtrl>("color_swatch"); + + mDefaultButton = getChild<LLUICtrl>("default_btn"); + mSettingNameText = getChild<LLTextBox>("color_name_txt"); + + getChild<LLFilterEditor>("filter_input")->setCommitCallback(boost::bind(&ALFloaterSettingsColor::setSearchFilter, this, _2)); + + mSettingList = getChild<LLScrollListCtrl>("setting_list"); + mSettingList->setCommitOnSelectionChange(TRUE); + mSettingList->setCommitCallback(boost::bind(&ALFloaterSettingsColor::onSettingSelect, this)); + + updateList(); + + gSavedSettings.getControl("ColorSettingsHideDefault")->getCommitSignal()->connect(boost::bind(&ALFloaterSettingsColor::updateList, this, false)); + + return TRUE; +} + +void ALFloaterSettingsColor::draw() +{ + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + if(auto cell = first_selected->getColumn(1)) + { + updateControl(cell->getValue().asString()); + } + } + + LLFloater::draw(); +} + +void ALFloaterSettingsColor::onCommitSettings() +{ + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (!first_selected) + { + return; + } + auto cell = first_selected->getColumn(1); + + if (!cell) + { + return; + } + + auto color_name = cell->getValue().asString(); + if (color_name.empty()) + { + return; + } + + LLColor4 col4; + LLColor3 col3; + col3.setValue(mColorSwatch->getValue()); + col4 = LLColor4(col3, (F32)mAlphaSpinner->getValue().asReal()); + LLUIColorTable::instance().setColor(color_name, col4); + + updateDefaultColumn(color_name); +} + +// static +void ALFloaterSettingsColor::onClickDefault() +{ + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + auto cell = first_selected->getColumn(1); + if (cell) + { + auto name = cell->getValue().asString(); + LLUIColorTable::instance().resetToDefault(name); + updateDefaultColumn(name); + updateControl(name); + } + } +} + +// we've switched controls, or doing per-frame update, so update spinners, etc. +void ALFloaterSettingsColor::updateControl(const std::string& color_name) +{ + hideUIControls(); + + if (!isSettingHidden(color_name)) + { + mDefaultButton->setVisible(true); + mSettingNameText->setVisible(true); + mSettingNameText->setText(color_name); + mSettingNameText->setToolTip(color_name); + + LLColor4 clr = LLUIColorTable::instance().getColor(color_name); + mColorSwatch->setVisible(TRUE); + // only set if changed so color picker doesn't update + if (clr != LLColor4(mColorSwatch->getValue())) + { + mColorSwatch->setOriginal(clr); + } + mAlphaSpinner->setVisible(TRUE); + mAlphaSpinner->setLabel(std::string("Alpha")); + if (!mAlphaSpinner->hasFocus()) + { + mAlphaSpinner->setPrecision(3); + mAlphaSpinner->setMinValue(0.0); + mAlphaSpinner->setMaxValue(1.f); + mAlphaSpinner->setValue(clr.mV[VALPHA]); + } + } + +} + +void ALFloaterSettingsColor::updateList(bool skip_selection) +{ + std::string last_selected; + LLScrollListItem* item = mSettingList->getFirstSelected(); + if (item) + { + LLScrollListCell* cell = item->getColumn(1); + if (cell) + { + last_selected = cell->getValue().asString(); + } + } + + mSettingList->deleteAllItems(); + + const auto& base_colors = LLUIColorTable::instance().getLoadedColors(); + for (const auto& pair : base_colors) + { + const auto& name = pair.first; + if (matchesSearchFilter(name) && !isSettingHidden(name)) + { + LLSD row; + + row["columns"][0]["column"] = "changed_color"; + row["columns"][0]["value"] = LLUIColorTable::instance().isDefault(name) ? "" : "*"; + + row["columns"][1]["column"] = "color"; + row["columns"][1]["value"] = name; + + LLScrollListItem* item = mSettingList->addElement(row, ADD_BOTTOM, nullptr); + if (!mSearchFilter.empty() && (last_selected == name) && !skip_selection) + { + std::string lower_name(name); + LLStringUtil::toLower(lower_name); + if (LLStringUtil::startsWith(lower_name, mSearchFilter)) + { + item->setSelected(true); + } + } + } + } + + for (const auto& pair : LLUIColorTable::instance().getUserColors()) + { + const auto& name = pair.first; + if (base_colors.find(name) == base_colors.end() && matchesSearchFilter(name) && !isSettingHidden(name)) + { + LLSD row; + + row["columns"][0]["column"] = "changed_color"; + row["columns"][0]["value"] = LLUIColorTable::instance().isDefault(name) ? "" : "*"; + + row["columns"][1]["column"] = "color"; + row["columns"][1]["value"] = name; + + LLScrollListItem* item = mSettingList->addElement(row, ADD_BOTTOM, nullptr); + if (!mSearchFilter.empty() && (last_selected == name) && !skip_selection) + { + std::string lower_name(name); + LLStringUtil::toLower(lower_name); + if (LLStringUtil::startsWith(lower_name, mSearchFilter)) + { + item->setSelected(true); + } + } + } + } + + mSettingList->updateSort(); + + if (!mSettingList->isEmpty()) + { + if (mSettingList->hasSelectedItem()) + { + mSettingList->scrollToShowSelected(); + } + else if (!mSettingList->hasSelectedItem() && !mSearchFilter.empty() && !skip_selection) + { + if (!mSettingList->selectItemByPrefix(mSearchFilter, false, 1)) + { + mSettingList->selectFirstItem(); + } + mSettingList->scrollToShowSelected(); + } + } + else + { + LLSD row; + + row["columns"][0]["column"] = "changed_color"; + row["columns"][0]["value"] = ""; + row["columns"][1]["column"] = "color"; + row["columns"][1]["value"] = "No matching colors."; + + mSettingList->addElement(row); + hideUIControls(); + } +} + +void ALFloaterSettingsColor::onSettingSelect() +{ + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + auto cell = first_selected->getColumn(1); + if (cell) + { + updateControl(cell->getValue().asString()); + } + } +} + +void ALFloaterSettingsColor::setSearchFilter(const std::string& filter) +{ + if(mSearchFilter == filter) + return; + mSearchFilter = filter; + LLStringUtil::toLower(mSearchFilter); + updateList(); +} + +bool ALFloaterSettingsColor::matchesSearchFilter(std::string setting_name) +{ + // If the search filter is empty, everything passes. + if (mSearchFilter.empty()) return true; + + LLStringUtil::toLower(setting_name); + std::string::size_type match_name = setting_name.find(mSearchFilter); + + return (std::string::npos != match_name); +} + +bool ALFloaterSettingsColor::isSettingHidden(const std::string& color_name) +{ + static LLCachedControl<bool> hide_default(gSavedSettings, "ColorSettingsHideDefault", false); + return hide_default && LLUIColorTable::instance().isDefault(color_name); +} + +void ALFloaterSettingsColor::updateDefaultColumn(const std::string& color_name) +{ + if (isSettingHidden(color_name)) + { + hideUIControls(); + updateList(true); + return; + } + + LLScrollListItem* item = mSettingList->getFirstSelected(); + if (item) + { + LLScrollListCell* cell = item->getColumn(0); + if (cell) + { + std::string is_default = LLUIColorTable::instance().isDefault(color_name) ? "" : "*"; + cell->setValue(is_default); + } + } +} + +void ALFloaterSettingsColor::hideUIControls() +{ + mColorSwatch->setVisible(false); + mAlphaSpinner->setVisible(false); + mDefaultButton->setVisible(false); + mSettingNameText->setVisible(false); +} + diff --git a/indra/newview/alfloatersettingscolor.h b/indra/newview/alfloatersettingscolor.h new file mode 100644 index 00000000000..9d49e59ca0f --- /dev/null +++ b/indra/newview/alfloatersettingscolor.h @@ -0,0 +1,81 @@ +/** + * @file alfloatersettingscolor.h + * @brief floater for debugging internal viewer colors + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Alchemy Viewer Source Code + * Copyright (C) 2024, Rye Mutt<rye@alchemyviewer.org>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $/LicenseInfo$ + */ + +#ifndef ALFLOATERCOLORSETTINGS_H +#define ALFLOATERCOLORSETTINGS_H + +#include "llcontrol.h" +#include "llfloater.h" + +class LLColorSwatchCtrl; +class LLScrollListCtrl; +class LLSpinCtrl; +class LLTextBox; + +class ALFloaterSettingsColor final +: public LLFloater +{ + friend class LLFloaterReg; + +public: + + virtual BOOL postBuild(); + virtual void draw(); + + void updateControl(const std::string& color_name); + + void onCommitSettings(); + void onClickDefault(); + + bool matchesSearchFilter(std::string setting_name); + bool isSettingHidden(const std::string& color_name); + +private: + // key - selects which settings to show, one of: + // "all", "base", "account", "skin" + ALFloaterSettingsColor(const LLSD& key); + virtual ~ALFloaterSettingsColor(); + + void updateList(bool skip_selection = false); + void onSettingSelect(); + void setSearchFilter(const std::string& filter); + + void updateDefaultColumn(const std::string& color_name); + void hideUIControls(); + + LLScrollListCtrl* mSettingList; + +protected: + LLUICtrl* mDefaultButton = nullptr; + LLTextBox* mSettingNameText = nullptr; + + LLSpinCtrl* mAlphaSpinner = nullptr; + LLColorSwatchCtrl* mColorSwatch = nullptr; + + std::string mSearchFilter; +}; + +#endif //ALFLOATERCOLORSETTINGS_H + diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml index 4920cd6560c..0527b7511ab 100644 --- a/indra/newview/app_settings/settings_alchemy.xml +++ b/indra/newview/app_settings/settings_alchemy.xml @@ -1965,5 +1965,16 @@ <key>Value</key> <integer>0</integer> </map> + <key>ColorSettingsHideDefault</key> + <map> + <key>Comment</key> + <string>Show non-default settings only in Color Settings list</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 6f76d89454d..475688f7bc8 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -37,6 +37,7 @@ #include "alfloaterlightbox.h" #include "alfloaterparticleeditor.h" #include "alfloaterregiontracker.h" +#include "alfloatersettingscolor.h" #include "llchatbar.h" #include "llcommandhandler.h" #include "llcompilequeue.h" @@ -583,6 +584,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("quick_settings", "floater_quick_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); LLFloaterReg::add("region_tracker", "floater_region_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterRegionTracker>); LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>); + LLFloaterReg::add("settings_color", "floater_settings_color.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterSettingsColor>); LLFloaterReg::add("sound_explorer", "floater_explore_sounds.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterExploreSounds>); LLFloaterReg::add("webprofile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); diff --git a/indra/newview/skins/default/xui/en/floater_settings_color.xml b/indra/newview/skins/default/xui/en/floater_settings_color.xml new file mode 100644 index 00000000000..0722677f1d1 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_settings_color.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + legacy_header_height="18" + can_minimize="false" + height="360" + min_height="367" + layout="topleft" + name="settings_color" + help_topic="settings_color" + title="COLOR SETTINGS" + reuse_instance="true" + can_resize="true" + min_width="550" + width="570"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="10" + right="-10" + label="Enter search text" + max_length_chars="300" + name="filter_input" + text_pad_left="10" + top="30" /> + <scroll_list + column_padding="0" + draw_heading="true" + draw_stripes="false" + heading_height="23" + height="266" + layout="topleft" + search_column="1" + sort_column="1" + left="10" + follows="left|top|bottom" + name="setting_list" + top_pad="2" + width="300"> + <scroll_list.columns + name="changed_color" + relative_width="0.05" /> + <scroll_list.columns + label="Color" + name="color" /> + </scroll_list> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + name="color_name_txt" + font="SansSerifSmallBold" + top_delta="8" + left_pad="10" + visible="true" + use_ellipses="true" + text_color="White" + width="240"> + Color name + </text> + <color_swatch + top_pad="0" + left_delta="0" + follows="top|left" + can_apply_immediately="true" + height="180" + name="color_swatch" + visible="true" + layout="topleft" + width="240"> + <color_swatch.commit_callback + function="CommitSettings" /> + </color_swatch> + <spinner + height="20" + label="Alpha" + layout="topleft" + follows="top|left" + left_delta="0" + min_val="0" + max_val="1" + decimal_digits="3" + name="alpha_spinner" + top_pad="5" + visible="true" + width="120"> + <spinner.commit_callback + function="CommitSettings" /> + </spinner> + <button + height="22" + label="Reset to default" + follows="left|top" + layout="topleft" + left_delta="0" + name="default_btn" + visible="true" + top_pad="15" + width="150"> + <button.commit_callback + function="ClickDefault" /> + </button> + <check_box + control_name="ColorSettingsHideDefault" + height="16" + initial_value="true" + label="Show changed colors only" + layout="topleft" + top_pad="10" + left="10" + follows="left|bottom" + name="hide_default" + width="330"> + </check_box> +</floater> \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 3d16450fbe3..be5ae7260c7 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -187,6 +187,13 @@ function="Floater.Toggle" parameter="ui_preview" /> </menu_item_call> + <menu_item_call + label="Color Settings" + name="Color Settings"> + <menu_item_call.on_click + function="Floater.Toggle" + parameter="settings_color" /> + </menu_item_call> <menu_item_separator /> <menu create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index f2b9c4bad0a..5bfec207d33 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -4214,7 +4214,7 @@ function="World.EnvPreset" </menu> <menu create_jump_keys="true" - label="XUI" + label="XUI / Colors" name="XUI" tear_off="true"> <menu_item_call @@ -4224,6 +4224,13 @@ function="World.EnvPreset" function="Floater.Toggle" parameter="ui_preview" /> </menu_item_call> + <menu_item_call + label="Color Settings" + name="Color Settings"> + <menu_item_call.on_click + function="Floater.Toggle" + parameter="settings_color" /> + </menu_item_call> <menu_item_call label="Reload Color Settings" name="Reload Color Settings"> -- GitLab