Add the emoji helper class which can be used by text-input controls to provide emoji picker support
parent
ec23b4bc63
commit
dad25bcb1e
|
|
@ -54,6 +54,7 @@ set(llui_SOURCE_FILES
|
|||
lldraghandle.cpp
|
||||
lleditmenuhandler.cpp
|
||||
llemojidictionary.cpp
|
||||
llemojihelper.cpp
|
||||
llf32uictrl.cpp
|
||||
llfiltereditor.cpp
|
||||
llflashtimer.cpp
|
||||
|
|
@ -165,6 +166,7 @@ set(llui_HEADER_FILES
|
|||
lldockcontrol.h
|
||||
lleditmenuhandler.h
|
||||
llemojidictionary.h
|
||||
llemojihelper.h
|
||||
llf32uictrl.h
|
||||
llfiltereditor.h
|
||||
llflashtimer.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* @file llemojihelper.h
|
||||
* @brief Header file for LLEmojiHelper
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, Linden Research, Inc.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llemojidictionary.h"
|
||||
#include "llemojihelper.h"
|
||||
#include "llfloater.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lluictrl.h"
|
||||
|
||||
// ============================================================================
|
||||
// Constants
|
||||
//
|
||||
|
||||
constexpr char DEFAULT_EMOJI_HELPER_FLOATER[] = "emoji_complete";
|
||||
constexpr S32 HELPER_FLOATER_OFFSET_X = 20;
|
||||
constexpr S32 HELPER_FLOATER_OFFSET_Y = 0;
|
||||
|
||||
// ============================================================================
|
||||
// LLEmojiHelper
|
||||
//
|
||||
|
||||
std::string LLEmojiHelper::getToolTip(llwchar ch) const
|
||||
{
|
||||
return LLEmojiDictionary::instance().getNameFromEmoji(ch);
|
||||
}
|
||||
|
||||
bool LLEmojiHelper::isActive(const LLUICtrl* ctrl_p) const
|
||||
{
|
||||
return mHostHandle.get() == ctrl_p;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S32* pShortCodePos)
|
||||
{
|
||||
S32 shortCodePos = cursorPos;
|
||||
|
||||
while (shortCodePos > 1 &&
|
||||
(LLStringOps::isAlnum(wtext[shortCodePos - 1]) || wtext[shortCodePos - 1] == L'-' || wtext[shortCodePos - 1] == L'_') )
|
||||
{
|
||||
shortCodePos--;
|
||||
}
|
||||
|
||||
bool isShortCode = (L':' == wtext[shortCodePos - 1]) && (cursorPos - shortCodePos >= 2);
|
||||
if (pShortCodePos)
|
||||
*pShortCodePos = (isShortCode) ? shortCodePos - 1 : -1;
|
||||
return isShortCode;
|
||||
}
|
||||
|
||||
void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(LLWString)> cb)
|
||||
{
|
||||
if (mHelperHandle.isDead())
|
||||
{
|
||||
LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
|
||||
mHelperHandle = pHelperFloater->getHandle();
|
||||
mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())); }, std::placeholders::_2));
|
||||
}
|
||||
setHostCtrl(hostctrl_p);
|
||||
mEmojiCommitCb = cb;
|
||||
|
||||
S32 floater_x, floater_y;
|
||||
if (!hostctrl_p->localPointToOtherView(local_x, local_y, &floater_x, &floater_y, gFloaterView))
|
||||
{
|
||||
LL_ERRS() << "Cannot show emoji helper for non-floater controls." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloater* pHelperFloater = mHelperHandle.get();
|
||||
LLRect rct = pHelperFloater->getRect();
|
||||
rct.setLeftTopAndSize(floater_x - HELPER_FLOATER_OFFSET_X, floater_y - HELPER_FLOATER_OFFSET_Y + rct.getHeight(), rct.getWidth(), rct.getHeight());
|
||||
pHelperFloater->setRect(rct);
|
||||
pHelperFloater->openFloater(LLSD().with("hint", short_code));
|
||||
}
|
||||
|
||||
void LLEmojiHelper::hideHelper(const LLUICtrl* ctrl_p)
|
||||
{
|
||||
setHostCtrl(nullptr);
|
||||
}
|
||||
|
||||
bool LLEmojiHelper::handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask)
|
||||
{
|
||||
if (mHelperHandle.isDead() || !isActive(ctrl_p))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return mHelperHandle.get()->handleKey(key, mask, true);
|
||||
}
|
||||
|
||||
void LLEmojiHelper::onCommitEmoji(const LLWString& wstr)
|
||||
{
|
||||
if (!mHostHandle.isDead() && mEmojiCommitCb)
|
||||
{
|
||||
mEmojiCommitCb(wstr);
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmojiHelper::setHostCtrl(LLUICtrl* hostctrl_p)
|
||||
{
|
||||
const LLUICtrl* pCurHostCtrl = mHostHandle.get();
|
||||
if (pCurHostCtrl != hostctrl_p)
|
||||
{
|
||||
mHostCtrlFocusLostConn.disconnect();
|
||||
mHostHandle.markDead();
|
||||
mEmojiCommitCb = {};
|
||||
|
||||
if (!mHelperHandle.isDead())
|
||||
{
|
||||
mHelperHandle.get()->closeFloater();
|
||||
}
|
||||
|
||||
if (hostctrl_p)
|
||||
{
|
||||
mHostHandle = hostctrl_p->getHandle();
|
||||
mHostCtrlFocusLostConn = hostctrl_p->setFocusLostCallback(std::bind([&]() { hideHelper(getHostCtrl()); }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* @file llemojihelper.h
|
||||
* @brief Header file for LLEmojiHelper
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, Linden Research, Inc.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llhandle.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
class LLFloater;
|
||||
class LLUICtrl;
|
||||
|
||||
class LLEmojiHelper : public LLSingleton<LLEmojiHelper>
|
||||
{
|
||||
LLSINGLETON(LLEmojiHelper) {}
|
||||
~LLEmojiHelper() override {}
|
||||
|
||||
public:
|
||||
// General
|
||||
std::string getToolTip(llwchar ch) const;
|
||||
bool isActive(const LLUICtrl* ctrl_p) const;
|
||||
static bool isCursorInEmojiCode(const LLWString& wtext, S32 cursor_pos, S32* short_code_pos_p = nullptr);
|
||||
void showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, const std::string& short_code, std::function<void(LLWString)> commit_cb);
|
||||
void hideHelper(const LLUICtrl* ctrl_p);
|
||||
|
||||
// Eventing
|
||||
bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask);
|
||||
void onCommitEmoji(const LLWString& wstr);
|
||||
|
||||
protected:
|
||||
LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
|
||||
void setHostCtrl(LLUICtrl* hostctrl_p);
|
||||
|
||||
private:
|
||||
LLHandle<LLUICtrl> mHostHandle;
|
||||
LLHandle<LLFloater> mHelperHandle;
|
||||
boost::signals2::connection mHostCtrlFocusLostConn;
|
||||
boost::signals2::connection mHelperCommitConn;
|
||||
std::function<void(LLWString)> mEmojiCommitCb;
|
||||
};
|
||||
Loading…
Reference in New Issue