Use LinkHelper::openURL on highlighted URL

This commit is contained in:
Benau 2021-09-06 14:19:39 +08:00
parent f5f821c925
commit ae98b0cf9b
7 changed files with 60 additions and 3 deletions

View File

@ -127,7 +127,7 @@ namespace gui
virtual void setUseGlyphLayoutsOnly(bool gls_only) = 0; virtual void setUseGlyphLayoutsOnly(bool gls_only) = 0;
virtual bool useGlyphLayoutsOnly() const = 0; virtual bool useGlyphLayoutsOnly() const = 0;
virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) {} virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) {}
virtual s32 getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str) { return -1; } virtual s32 getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str, int* out_glyph_idx = NULL) { return -1; }
}; };

View File

@ -379,7 +379,7 @@ bool CGUIStaticText::OnEvent(const SEvent& event)
} }
s32 CGUIStaticText::getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str) s32 CGUIStaticText::getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str, int* out_glyph_idx)
{ {
core::position2di p; core::position2di p;
p.X = x; p.X = x;
@ -473,6 +473,8 @@ s32 CGUIStaticText::getCluster(int x, int y, std::shared_ptr<std::u32string>* ou
if (cluster > s->size()) if (cluster > s->size())
return -1; return -1;
*out_orig_str = s; *out_orig_str = s;
if (out_glyph_idx)
*out_glyph_idx = idx;
return cluster; return cluster;
} }

View File

@ -113,7 +113,7 @@ namespace gui
//! called if an event happened. //! called if an event happened.
virtual bool OnEvent(const SEvent& event); virtual bool OnEvent(const SEvent& event);
virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) { m_callback = cb; } virtual void setMouseCallback(std::function<bool(IGUIStaticText* text, SEvent::SMouseInput)> cb) { m_callback = cb; }
virtual s32 getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str); virtual s32 getCluster(int x, int y, std::shared_ptr<std::u32string>* out_orig_str, int* out_glyph_idx = NULL);
private: private:
//! Breaks the single text line. //! Breaks the single text line.

View File

@ -17,6 +17,7 @@
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/widgets/bubble_widget.hpp" #include "guiengine/widgets/bubble_widget.hpp"
#include "online/link_helper.hpp"
#include <algorithm> #include <algorithm>
#include <IGUIStaticText.h> #include <IGUIStaticText.h>
@ -52,6 +53,7 @@ void BubbleWidget::add()
false, true /* word wrap */, m_parent, false, true /* word wrap */, m_parent,
(m_focusable ? getNewID() : getNewNoFocusID())); (m_focusable ? getNewID() : getNewNoFocusID()));
irrwidget->setTextRestrainedInside(false); irrwidget->setTextRestrainedInside(false);
irrwidget->setMouseCallback(Online::LinkHelper::openURLIrrElement);
m_element = irrwidget; m_element = irrwidget;
replaceText(); replaceText();

View File

@ -20,6 +20,7 @@
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp" #include "guiengine/scalable_font.hpp"
#include "guiengine/skin.hpp" #include "guiengine/skin.hpp"
#include "online/link_helper.hpp"
#include <IGUIElement.h> #include <IGUIElement.h>
#include <IGUIEnvironment.h> #include <IGUIEnvironment.h>
@ -84,6 +85,7 @@ void LabelWidget::add()
irrwidget->setTextRestrainedInside(false); irrwidget->setTextRestrainedInside(false);
} }
irrwidget->setMouseCallback(Online::LinkHelper::openURLIrrElement);
m_element = irrwidget; m_element = irrwidget;
irrwidget->setTextAlignment( align, valign ); irrwidget->setTextAlignment( align, valign );

View File

@ -17,7 +17,12 @@
#include "online/link_helper.hpp" #include "online/link_helper.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include <string> #include <string>
#include <GlyphLayout.h>
#include <IGUIStaticText.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <shellapi.h> #include <shellapi.h>
@ -40,6 +45,41 @@ using namespace Online;
namespace Online namespace Online
{ {
bool LinkHelper::openURLIrrElement(irr::gui::IGUIStaticText* text,
irr::SEvent::SMouseInput mouse)
{
if (mouse.Event != EMIE_LMOUSE_PRESSED_DOWN)
return false;
std::shared_ptr<std::u32string> s;
int glyph_idx = -1;
int cluster = text->getCluster(mouse.X, mouse.Y, &s, &glyph_idx);
if (cluster == -1 || (unsigned)cluster > s->size())
return false;
const std::vector<gui::GlyphLayout>& gls = text->getGlyphLayouts();
const gui::GlyphLayout& gl = gls[glyph_idx];
if ((gl.flags & gui::GLF_URL) == 0)
return false;
int start = glyph_idx;
while (start != 0)
{
if ((gls[start - 1].flags & gui::GLF_URL) == 0)
break;
start--;
}
size_t end = glyph_idx;
while (gls.size() - end > 1)
{
size_t next_end = end + 1;
if ((gls[next_end].flags & gui::GLF_URL) == 0)
break;
end = next_end;
}
std::u32string url = s->substr(gls[start].cluster.front(),
gls[end].cluster.back() - gls[start].cluster.front() + 1);
openURL(StringUtils::utf32ToUtf8(url));
return true;
}
bool LinkHelper::isSupported() bool LinkHelper::isSupported()
{ {
#ifdef SERVER_ONLY #ifdef SERVER_ONLY

View File

@ -19,6 +19,16 @@
#include <string> #include <string>
#include <IEventReceiver.h>
namespace irr
{
namespace gui
{
class IGUIStaticText;
}
}
namespace Online namespace Online
{ {
class LinkHelper class LinkHelper
@ -26,6 +36,7 @@ namespace Online
public: public:
static bool isSupported(); static bool isSupported();
static void openURL(const std::string& url); static void openURL(const std::string& url);
static bool openURLIrrElement(irr::gui::IGUIStaticText* text, irr::SEvent::SMouseInput mouse);
}; //class LinkHelper }; //class LinkHelper
} // namespace Online } // namespace Online
#endif // link_helper_HPP #endif // link_helper_HPP