summaryrefslogtreecommitdiff
path: root/src/gui/guiChatConsole.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/guiChatConsole.cpp')
-rw-r--r--src/gui/guiChatConsole.cpp131
1 files changed, 109 insertions, 22 deletions
diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp
index ef471106d..01e10ea2e 100644
--- a/src/gui/guiChatConsole.cpp
+++ b/src/gui/guiChatConsole.cpp
@@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "IrrCompileConfig.h"
#include "guiChatConsole.h"
#include "chat.h"
#include "client/client.h"
@@ -29,17 +30,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/fontengine.h"
#include "log.h"
#include "gettext.h"
+#include "irrlicht_changes/CGUITTFont.h"
#include <string>
-#if USE_FREETYPE
- #include "irrlicht_changes/CGUITTFont.h"
-#endif
-
inline u32 clamp_u8(s32 value)
{
return (u32) MYMIN(MYMAX(value, 0), 255);
}
+inline bool isInCtrlKeys(const irr::EKEY_CODE& kc)
+{
+ return kc == KEY_LCONTROL || kc == KEY_RCONTROL || kc == KEY_CONTROL;
+}
GUIChatConsole::GUIChatConsole(
gui::IGUIEnvironment* env,
@@ -90,6 +92,10 @@ GUIChatConsole::GUIChatConsole(
// set default cursor options
setCursor(true, true, 2.0, 0.1);
+
+ // track ctrl keys for mouse event
+ m_is_ctrl_down = false;
+ m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks");
}
GUIChatConsole::~GUIChatConsole()
@@ -319,20 +325,16 @@ void GUIChatConsole::drawText()
core::rect<s32> destrect(
x, y, x + m_fontsize.X * fragment.text.size(), y + m_fontsize.Y);
-#if USE_FREETYPE
if (m_font->getType() == irr::gui::EGFT_CUSTOM) {
- // Draw colored text if FreeType is enabled
- irr::gui::CGUITTFont *tmp = dynamic_cast<irr::gui::CGUITTFont *>(m_font);
+ // Draw colored text if possible
+ gui::CGUITTFont *tmp = static_cast<gui::CGUITTFont*>(m_font);
tmp->draw(
fragment.text,
destrect,
- video::SColor(255, 255, 255, 255),
false,
false,
&AbsoluteClippingRect);
- } else
-#endif
- {
+ } else {
// Otherwise use standard text
m_font->draw(
fragment.text.c_str(),
@@ -405,8 +407,21 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
ChatPrompt &prompt = m_chat_backend->getPrompt();
- if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
+ if (event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
+ {
+ // CTRL up
+ if (isInCtrlKeys(event.KeyInput.Key))
+ {
+ m_is_ctrl_down = false;
+ }
+ }
+ else if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
{
+ // CTRL down
+ if (isInCtrlKeys(event.KeyInput.Key)) {
+ m_is_ctrl_down = true;
+ }
+
// Key input
if (KeyPress(event.KeyInput) == getKeySetting("keymap_console")) {
closeConsole();
@@ -559,8 +574,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
const c8 *text = os_operator->getTextFromClipboard();
if (!text)
return true;
- std::basic_string<unsigned char> str((const unsigned char*)text);
- prompt.input(std::wstring(str.begin(), str.end()));
+ prompt.input(utf8_to_wide(text));
return true;
}
else if(event.KeyInput.Key == KEY_KEY_X && event.KeyInput.Control)
@@ -607,24 +621,38 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
prompt.nickCompletion(names, backwards);
return true;
} else if (!iswcntrl(event.KeyInput.Char) && !event.KeyInput.Control) {
- #if defined(__linux__) && (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9)
- wchar_t wc = L'_';
- mbtowc( &wc, (char *) &event.KeyInput.Char, sizeof(event.KeyInput.Char) );
- prompt.input(wc);
- #else
- prompt.input(event.KeyInput.Char);
- #endif
+ prompt.input(event.KeyInput.Char);
return true;
}
}
else if(event.EventType == EET_MOUSE_INPUT_EVENT)
{
- if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)
+ if (event.MouseInput.Event == EMIE_MOUSE_WHEEL)
{
s32 rows = myround(-3.0 * event.MouseInput.Wheel);
m_chat_backend->scroll(rows);
}
+ // Middle click or ctrl-click opens weblink, if enabled in config
+ else if(m_cache_clickable_chat_weblinks && (
+ event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN ||
+ (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN && m_is_ctrl_down)
+ ))
+ {
+ // If clicked within console output region
+ if (event.MouseInput.Y / m_fontsize.Y < (m_height / m_fontsize.Y) - 1 )
+ {
+ // Translate pixel position to font position
+ middleClick(event.MouseInput.X / m_fontsize.X, event.MouseInput.Y / m_fontsize.Y);
+ }
+ }
}
+#if (IRRLICHT_VERSION_MT_REVISION >= 2)
+ else if(event.EventType == EET_STRING_INPUT_EVENT)
+ {
+ prompt.input(std::wstring(event.StringInput.Str->c_str()));
+ return true;
+ }
+#endif
return Parent ? Parent->OnEvent(event) : false;
}
@@ -639,3 +667,62 @@ void GUIChatConsole::setVisible(bool visible)
}
}
+void GUIChatConsole::middleClick(s32 col, s32 row)
+{
+ // Prevent accidental rapid clicking
+ static u64 s_oldtime = 0;
+ u64 newtime = porting::getTimeMs();
+
+ // 0.6 seconds should suffice
+ if (newtime - s_oldtime < 600)
+ return;
+ s_oldtime = newtime;
+
+ const std::vector<ChatFormattedFragment> &
+ frags = m_chat_backend->getConsoleBuffer().getFormattedLine(row).fragments;
+ std::string weblink = ""; // from frag meta
+
+ // Identify targetted fragment, if exists
+ int indx = frags.size() - 1;
+ if (indx < 0) {
+ // Invalid row, frags is empty
+ return;
+ }
+ // Scan from right to left, offset by 1 font space because left margin
+ while (indx > -1 && (u32)col < frags[indx].column + 1) {
+ --indx;
+ }
+ if (indx > -1) {
+ weblink = frags[indx].weblink;
+ // Note if(indx < 0) then a frag somehow had a corrupt column field
+ }
+
+ /*
+ // Debug help. Please keep this in case adjustments are made later.
+ std::string ws;
+ ws = "Middleclick: (" + std::to_string(col) + ',' + std::to_string(row) + ')' + " frags:";
+ // show all frags <position>(<length>) for the clicked row
+ for (u32 i=0;i<frags.size();++i) {
+ if (indx == int(i))
+ // tag the actual clicked frag
+ ws += '*';
+ ws += std::to_string(frags.at(i).column) + '('
+ + std::to_string(frags.at(i).text.size()) + "),";
+ }
+ actionstream << ws << std::endl;
+ */
+
+ // User notification
+ if (weblink.size() != 0) {
+ std::ostringstream msg;
+ msg << " * ";
+ if (porting::open_url(weblink)) {
+ msg << gettext("Opening webpage");
+ }
+ else {
+ msg << gettext("Failed to open webpage");
+ }
+ msg << " '" << weblink << "'";
+ m_chat_backend->addUnparsedMessage(utf8_to_wide(msg.str()));
+ }
+}