From 97ddd995d7484ae239c62f061c4ebf61677f7385 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Mon, 5 May 2025 23:43:30 +0200 Subject: [PATCH] Transplant emoji picker button toggle behavior and show correct arrow for recent emoji panel toggle button --- indra/newview/fsfloaterim.cpp | 55 +++++++++++++++++++++++---- indra/newview/fsfloaterim.h | 7 +++- indra/newview/fsfloaternearbychat.cpp | 45 +++++++++++++++++++++- indra/newview/fsfloaternearbychat.h | 7 +++- 4 files changed, 101 insertions(+), 13 deletions(-) diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp index e4308d15d0..19b11b4027 100644 --- a/indra/newview/fsfloaterim.cpp +++ b/indra/newview/fsfloaterim.cpp @@ -51,6 +51,7 @@ #include "llchiclet.h" #include "llchicletbar.h" #include "llconsole.h" +#include "llemojihelper.h" #include "llfloaterabout.h" // for sysinfo button -Zi #include "llfloateravatarpicker.h" #include "llfloaterchatmentionpicker.h" @@ -179,7 +180,7 @@ FSFloaterIM::FSFloaterIM(const LLUUID& session_id) // only dock when chiclets are visible, or the floater will get stuck in the top left // FIRE-9984 -Zi - bool disable_chiclets = gSavedSettings.getBOOL("FSDisableIMChiclets"); + const bool disable_chiclets = gSavedSettings.getBOOL("FSDisableIMChiclets"); setDocked(!disable_chiclets); // make sure to save position and size with chiclets disabled (torn off floater does that) setTornOff(disable_chiclets); @@ -649,6 +650,8 @@ FSFloaterIM::~FSFloaterIM() mRecentEmojisUpdatedCallbackConnection.disconnect(); } + mEmojiCloseConn.disconnect(); + LLFloaterChatMentionPicker::removeParticipantSource(this); } @@ -1014,8 +1017,8 @@ bool FSFloaterIM::postBuild() mEmojiRecentIconsCtrl->setCommitCallback([this](LLUICtrl*, const LLSD& value) { onRecentEmojiPicked(value); }); mEmojiRecentIconsCtrl->setVisible(false); - static bool usePrettyEmojiButton = gSavedSettings.getBOOL( "FSUsePrettyEmojiButton" ); - static bool useBWEmojis = gSavedSettings.getBOOL( "FSUseBWEmojis" ); + static bool usePrettyEmojiButton = gSavedSettings.getBOOL("FSUsePrettyEmojiButton"); + static bool useBWEmojis = gSavedSettings.getBOOL("FSUseBWEmojis"); mEmojiPickerToggleBtn = getChild("emoji_picker_toggle_btn"); if (usePrettyEmojiButton) { @@ -1030,14 +1033,16 @@ bool FSFloaterIM::postBuild() mEmojiPickerToggleBtn->setImageOverlay("Emoji_Picker_Icon"); } mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(); }); + mEmojiPickerToggleBtn->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnDown(); }); + mEmojiCloseConn = LLEmojiHelper::instance().setCloseCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerClosed(); }); mRecentEmojisUpdatedCallbackConnection = LLFloaterEmojiPicker::setRecentEmojisUpdatedCallback([this](const std::list& recent_emojis_list) { initEmojiRecentPanel(); }); getChild("send_chat")->setCommitCallback(boost::bind(&FSFloaterIM::sendMsgFromInputEditor, this, CHAT_TYPE_NORMAL)); getChild("chat_search_btn")->setCommitCallback(boost::bind(&FSFloaterIM::onChatSearchButtonClicked, this)); - bool isFSSupportGroup = FSData::getInstance()->isFirestormGroup(mSessionID); - bool isFSTestingGroup = FSData::getInstance()->isTestingGroup(mSessionID); + const bool isFSSupportGroup = FSData::getInstance()->isFirestormGroup(mSessionID); + const bool isFSTestingGroup = FSData::getInstance()->isTestingGroup(mSessionID); //We can show the testing group button simply by checking testing group childSetVisible("testing_panel", isFSTestingGroup); @@ -2534,6 +2539,7 @@ void FSFloaterIM::onEmojiRecentPanelToggleBtnClicked() } mEmojiRecentPanel->setVisible(show); + mEmojiRecentPanelToggleBtn->setImageOverlay(show ? "Arrow_Up" : "Arrow_Down"); mInputEditor->setFocus(true); } @@ -2574,8 +2580,43 @@ void FSFloaterIM::onRecentEmojiPicked(const LLSD& value) void FSFloaterIM::onEmojiPickerToggleBtnClicked() { - mInputEditor->setFocus(true); - mInputEditor->showEmojiHelper(); + if (!mEmojiPickerToggleBtn->getToggleState()) + { + mInputEditor->hideEmojiHelper(); + mInputEditor->setFocus(true); + mInputEditor->showEmojiHelper(); + mEmojiPickerToggleBtn->setToggleState(true); // in case hideEmojiHelper closed a visible instance + } + else + { + mInputEditor->hideEmojiHelper(); + mEmojiPickerToggleBtn->setToggleState(false); + } +} + +void FSFloaterIM::onEmojiPickerToggleBtnDown() +{ + if (mEmojiHelperLastCallbackFrame == LLFrameTimer::getFrameCount()) + { + // Helper gets closed by focus lost event on Down before before onEmojiPickerShowBtnDown + // triggers. + // If this condition is true, user pressed button and it was 'toggled' during press, + // restore 'toggled' state so that button will not reopen helper. + mEmojiPickerToggleBtn->setToggleState(true); + } +} + +void FSFloaterIM::onEmojiPickerClosed() +{ + if (mEmojiPickerToggleBtn->getToggleState()) + { + mEmojiPickerToggleBtn->setToggleState(false); + // Helper gets closed by focus lost event on Down before onEmojiPickerShowBtnDown + // triggers. If mEmojiHelperLastCallbackFrame is set and matches Down, means close + // was triggered by user's press. + // A bit hacky, but I can't think of a better way to handle this without rewriting helper. + mEmojiHelperLastCallbackFrame = LLFrameTimer::getFrameCount(); + } } uuid_vec_t FSFloaterIM::getSessionParticipants() const diff --git a/indra/newview/fsfloaterim.h b/indra/newview/fsfloaterim.h index 238313e67b..0b5d65bf7e 100644 --- a/indra/newview/fsfloaterim.h +++ b/indra/newview/fsfloaterim.h @@ -162,8 +162,6 @@ public: void timedUpdate(); - void onEmojiPickerToggleBtnClicked(); - uuid_vec_t getSessionParticipants() const; protected: @@ -244,7 +242,10 @@ private: bool onChatOptionsVisibleContextMenuItem(const LLSD& userdata); bool onChatOptionsEnableContextMenuItem(const LLSD& userdata); + void onEmojiPickerToggleBtnClicked(); + void onEmojiPickerToggleBtnDown(); void onEmojiRecentPanelToggleBtnClicked(); + void onEmojiPickerClosed(); void initEmojiRecentPanel(); void onRecentEmojiPicked(const LLSD& value); @@ -299,6 +300,8 @@ private: FSFloaterIMTimer* mIMFloaterTimer; boost::signals2::connection mRecentEmojisUpdatedCallbackConnection{}; + boost::signals2::connection mEmojiCloseConn{}; + U32 mEmojiHelperLastCallbackFrame{ 0 }; }; class FSFloaterIMTimer : public LLEventTimer diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp index eb59eea67c..67f8c6b34d 100644 --- a/indra/newview/fsfloaternearbychat.cpp +++ b/indra/newview/fsfloaternearbychat.cpp @@ -50,6 +50,7 @@ #include "llcommandhandler.h" #include "llconsole.h" #include "lldraghandle.h" +#include "llemojihelper.h" #include "llfloaterchatmentionpicker.h" #include "llfloateremojipicker.h" #include "llfloaterreg.h" @@ -111,6 +112,8 @@ FSFloaterNearbyChat::~FSFloaterNearbyChat() mRecentEmojisUpdatedCallbackConnection.disconnect(); } + mEmojiCloseConn.disconnect(); + LLFloaterChatMentionPicker::removeParticipantSource(this); } @@ -181,6 +184,8 @@ bool FSFloaterNearbyChat::postBuild() mEmojiPickerToggleBtn->setImageOverlay("Emoji_Picker_Icon"); } mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(); }); + mEmojiPickerToggleBtn->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnDown(); }); + mEmojiCloseConn = LLEmojiHelper::instance().setCloseCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerClosed(); }); mRecentEmojisUpdatedCallbackConnection = LLFloaterEmojiPicker::setRecentEmojisUpdatedCallback([this](const std::list& recent_emojis_list) { initEmojiRecentPanel(); }); @@ -997,6 +1002,7 @@ void FSFloaterNearbyChat::onEmojiRecentPanelToggleBtnClicked() } mEmojiRecentPanel->setVisible(show); + mEmojiRecentPanelToggleBtn->setImageOverlay(show ? "Arrow_Up" : "Arrow_Down"); mInputEditor->setFocus(true); } @@ -1037,8 +1043,43 @@ void FSFloaterNearbyChat::onRecentEmojiPicked(const LLSD& value) void FSFloaterNearbyChat::onEmojiPickerToggleBtnClicked() { - mInputEditor->setFocus(true); - mInputEditor->showEmojiHelper(); + if (!mEmojiPickerToggleBtn->getToggleState()) + { + mInputEditor->hideEmojiHelper(); + mInputEditor->setFocus(true); + mInputEditor->showEmojiHelper(); + mEmojiPickerToggleBtn->setToggleState(true); // in case hideEmojiHelper closed a visible instance + } + else + { + mInputEditor->hideEmojiHelper(); + mEmojiPickerToggleBtn->setToggleState(false); + } +} + +void FSFloaterNearbyChat::onEmojiPickerToggleBtnDown() +{ + if (mEmojiHelperLastCallbackFrame == LLFrameTimer::getFrameCount()) + { + // Helper gets closed by focus lost event on Down before before onEmojiPickerShowBtnDown + // triggers. + // If this condition is true, user pressed button and it was 'toggled' during press, + // restore 'toggled' state so that button will not reopen helper. + mEmojiPickerToggleBtn->setToggleState(true); + } +} + +void FSFloaterNearbyChat::onEmojiPickerClosed() +{ + if (mEmojiPickerToggleBtn->getToggleState()) + { + mEmojiPickerToggleBtn->setToggleState(false); + // Helper gets closed by focus lost event on Down before onEmojiPickerShowBtnDown + // triggers. If mEmojiHelperLastCallbackFrame is set and matches Down, means close + // was triggered by user's press. + // A bit hacky, but I can't think of a better way to handle this without rewriting helper. + mEmojiHelperLastCallbackFrame = LLFrameTimer::getFrameCount(); + } } void FSFloaterNearbyChat::onFocusLost() diff --git a/indra/newview/fsfloaternearbychat.h b/indra/newview/fsfloaternearbychat.h index 164612308e..37641a4be3 100644 --- a/indra/newview/fsfloaternearbychat.h +++ b/indra/newview/fsfloaternearbychat.h @@ -102,8 +102,6 @@ public: void handleMinimized(bool minimized); - void onEmojiPickerToggleBtnClicked(); - uuid_vec_t getSessionParticipants() const; protected: @@ -126,7 +124,10 @@ private: bool onChatOptionsVisibleContextMenuItem(const LLSD& userdata); bool onChatOptionsEnableContextMenuItem(const LLSD& userdata); + void onEmojiPickerToggleBtnClicked(); + void onEmojiPickerToggleBtnDown(); void onEmojiRecentPanelToggleBtnClicked(); + void onEmojiPickerClosed(); void initEmojiRecentPanel(); void onRecentEmojiPicked(const LLSD& value); @@ -163,6 +164,8 @@ private: bool FSUseNearbyChatConsole; boost::signals2::connection mRecentEmojisUpdatedCallbackConnection{}; + boost::signals2::connection mEmojiCloseConn{}; + U32 mEmojiHelperLastCallbackFrame{ 0 }; }; #endif // FS_FLOATERNEARBYCHAT_H