aboutsummaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorElias Fleckenstein <eliasfleckenstein@web.de>2021-09-19 20:56:13 +0200
committerElias Fleckenstein <eliasfleckenstein@web.de>2021-09-19 20:56:13 +0200
commitc8900e169a1ddceec07a449f1ae7c4322ff02036 (patch)
tree5156605fb473d25786426eb6876ba2e7d3b7507b /src/gui
parent950d2c9b3e10cbace9236e820c8119d1abb9e01f (diff)
parente0529da5c84f224c380e6d5e063392cb01f85683 (diff)
downloaddragonfireclient-c8900e169a1ddceec07a449f1ae7c4322ff02036.tar.xz
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/guiChatConsole.cpp102
-rw-r--r--src/gui/guiChatConsole.h8
-rw-r--r--src/gui/guiEditBox.cpp28
-rw-r--r--src/gui/guiEditBoxWithScrollbar.cpp15
-rw-r--r--src/gui/guiEngine.cpp22
-rw-r--r--src/gui/guiEngine.h4
-rw-r--r--src/gui/guiFormSpecMenu.cpp17
-rw-r--r--src/gui/guiVolumeChange.cpp15
-rw-r--r--src/gui/modalMenu.cpp2
-rw-r--r--src/gui/touchscreengui.cpp2
10 files changed, 161 insertions, 54 deletions
diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp
index baaaea5e8..0610c85cc 100644
--- a/src/gui/guiChatConsole.cpp
+++ b/src/gui/guiChatConsole.cpp
@@ -41,6 +41,10 @@ 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,
@@ -91,6 +95,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()
@@ -330,7 +338,7 @@ void GUIChatConsole::drawText()
false,
false,
&AbsoluteClippingRect);
- } else
+ } else
#endif
{
// Otherwise use standard text
@@ -405,8 +413,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 +580,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)
@@ -613,11 +633,24 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
}
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)
@@ -640,3 +673,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()));
+ }
+}
diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h
index 1152f2b2d..32628f0d8 100644
--- a/src/gui/guiChatConsole.h
+++ b/src/gui/guiChatConsole.h
@@ -84,6 +84,9 @@ private:
void drawText();
void drawPrompt();
+ // If clicked fragment has a web url, send it to the system default web browser
+ void middleClick(s32 col, s32 row);
+
private:
ChatBackend* m_chat_backend;
Client* m_client;
@@ -126,4 +129,9 @@ private:
// font
gui::IGUIFont *m_font = nullptr;
v2u32 m_fontsize;
+
+ // Enable clickable chat weblinks
+ bool m_cache_clickable_chat_weblinks;
+ // Track if a ctrl key is currently held down
+ bool m_is_ctrl_down;
};
diff --git a/src/gui/guiEditBox.cpp b/src/gui/guiEditBox.cpp
index ba548aa2d..8459107cd 100644
--- a/src/gui/guiEditBox.cpp
+++ b/src/gui/guiEditBox.cpp
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "IGUIFont.h"
#include "porting.h"
+#include "util/string.h"
GUIEditBox::~GUIEditBox()
{
@@ -232,10 +233,6 @@ bool GUIEditBox::OnEvent(const SEvent &event)
bool GUIEditBox::processKey(const SEvent &event)
{
- if (!m_writable) {
- return false;
- }
-
if (!event.KeyInput.PressedDown)
return false;
@@ -521,8 +518,7 @@ void GUIEditBox::onKeyControlC(const SEvent &event)
const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
- core::stringc s;
- s = Text.subString(realmbgn, realmend - realmbgn).c_str();
+ std::string s = stringw_to_utf8(Text.subString(realmbgn, realmend - realmbgn));
m_operator->copyToClipboard(s.c_str());
}
@@ -531,6 +527,9 @@ bool GUIEditBox::onKeyControlX(const SEvent &event, s32 &mark_begin, s32 &mark_e
// First copy to clipboard
onKeyControlC(event);
+ if (!m_writable)
+ return false;
+
if (m_passwordbox || !m_operator || m_mark_begin == m_mark_end)
return false;
@@ -556,7 +555,7 @@ bool GUIEditBox::onKeyControlX(const SEvent &event, s32 &mark_begin, s32 &mark_e
bool GUIEditBox::onKeyControlV(const SEvent &event, s32 &mark_begin, s32 &mark_end)
{
- if (!isEnabled())
+ if (!isEnabled() || !m_writable)
return false;
// paste from the clipboard
@@ -568,29 +567,28 @@ bool GUIEditBox::onKeyControlV(const SEvent &event, s32 &mark_begin, s32 &mark_e
// add new character
if (const c8 *p = m_operator->getTextFromClipboard()) {
+ core::stringw inserted_text = utf8_to_stringw(p);
if (m_mark_begin == m_mark_end) {
// insert text
core::stringw s = Text.subString(0, m_cursor_pos);
- s.append(p);
+ s.append(inserted_text);
s.append(Text.subString(
m_cursor_pos, Text.size() - m_cursor_pos));
if (!m_max || s.size() <= m_max) {
Text = s;
- s = p;
- m_cursor_pos += s.size();
+ m_cursor_pos += inserted_text.size();
}
} else {
// replace text
core::stringw s = Text.subString(0, realmbgn);
- s.append(p);
+ s.append(inserted_text);
s.append(Text.subString(realmend, Text.size() - realmend));
if (!m_max || s.size() <= m_max) {
Text = s;
- s = p;
- m_cursor_pos = realmbgn + s.size();
+ m_cursor_pos = realmbgn + inserted_text.size();
}
}
}
@@ -602,7 +600,7 @@ bool GUIEditBox::onKeyControlV(const SEvent &event, s32 &mark_begin, s32 &mark_e
bool GUIEditBox::onKeyBack(const SEvent &event, s32 &mark_begin, s32 &mark_end)
{
- if (!isEnabled() || Text.empty())
+ if (!isEnabled() || Text.empty() || !m_writable)
return false;
core::stringw s;
@@ -640,7 +638,7 @@ bool GUIEditBox::onKeyBack(const SEvent &event, s32 &mark_begin, s32 &mark_end)
bool GUIEditBox::onKeyDelete(const SEvent &event, s32 &mark_begin, s32 &mark_end)
{
- if (!isEnabled() || Text.empty())
+ if (!isEnabled() || Text.empty() || !m_writable)
return false;
core::stringw s;
diff --git a/src/gui/guiEditBoxWithScrollbar.cpp b/src/gui/guiEditBoxWithScrollbar.cpp
index c72070787..fb4bc2a0b 100644
--- a/src/gui/guiEditBoxWithScrollbar.cpp
+++ b/src/gui/guiEditBoxWithScrollbar.cpp
@@ -620,6 +620,17 @@ void GUIEditBoxWithScrollBar::createVScrollBar()
if (Environment)
skin = Environment->getSkin();
+ s32 fontHeight = 1;
+
+ if (m_override_font) {
+ fontHeight = m_override_font->getDimension(L"Ay").Height;
+ } else {
+ IGUIFont *font;
+ if (skin && (font = skin->getFont())) {
+ fontHeight = font->getDimension(L"Ay").Height;
+ }
+ }
+
m_scrollbar_width = skin ? skin->getSize(gui::EGDS_SCROLLBAR_SIZE) : 16;
irr::core::rect<s32> scrollbarrect = m_frame_rect;
@@ -628,8 +639,8 @@ void GUIEditBoxWithScrollBar::createVScrollBar()
scrollbarrect, false, true);
m_vscrollbar->setVisible(false);
- m_vscrollbar->setSmallStep(1);
- m_vscrollbar->setLargeStep(1);
+ m_vscrollbar->setSmallStep(3 * fontHeight);
+ m_vscrollbar->setLargeStep(10 * fontHeight);
}
diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp
index 694baf482..c39c3ee0d 100644
--- a/src/gui/guiEngine.cpp
+++ b/src/gui/guiEngine.cpp
@@ -437,9 +437,22 @@ void GUIEngine::drawBackground(video::IVideoDriver *driver)
return;
}
+ // Chop background image to the smaller screen dimension
+ v2u32 bg_size = screensize;
+ v2f32 scale(
+ (f32) bg_size.X / sourcesize.X,
+ (f32) bg_size.Y / sourcesize.Y);
+ if (scale.X < scale.Y)
+ bg_size.X = (int) (scale.Y * sourcesize.X);
+ else
+ bg_size.Y = (int) (scale.X * sourcesize.Y);
+ v2s32 offset = v2s32(
+ (s32) screensize.X - (s32) bg_size.X,
+ (s32) screensize.Y - (s32) bg_size.Y
+ ) / 2;
/* Draw background texture */
draw2DImageFilterScaled(driver, texture,
- core::rect<s32>(0, 0, screensize.X, screensize.Y),
+ core::rect<s32>(offset.X, offset.Y, bg_size.X + offset.X, bg_size.Y + offset.Y),
core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y),
NULL, NULL, true);
}
@@ -614,10 +627,3 @@ void GUIEngine::stopSound(s32 handle)
{
m_sound_manager->stopSound(handle);
}
-
-/******************************************************************************/
-unsigned int GUIEngine::queueAsync(const std::string &serialized_func,
- const std::string &serialized_params)
-{
- return m_script->queueAsync(serialized_func, serialized_params);
-}
diff --git a/src/gui/guiEngine.h b/src/gui/guiEngine.h
index 70abce181..d7e6485ef 100644
--- a/src/gui/guiEngine.h
+++ b/src/gui/guiEngine.h
@@ -175,10 +175,6 @@ public:
return m_scriptdir;
}
- /** pass async callback to scriptengine **/
- unsigned int queueAsync(const std::string &serialized_fct,
- const std::string &serialized_params);
-
private:
/** find and run the main menu script */
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index c6435804f..797fd3ff6 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -1577,11 +1577,10 @@ void GUIFormSpecMenu::createTextField(parserData *data, FieldSpec &spec,
}
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
- e->setDrawBorder(style.getBool(StyleSpec::BORDER, true));
e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
- if (style.get(StyleSpec::BGCOLOR, "") == "transparent") {
- e->setDrawBackground(false);
- }
+ bool border = style.getBool(StyleSpec::BORDER, true);
+ e->setDrawBorder(border);
+ e->setDrawBackground(border);
e->setOverrideFont(style.getFont());
e->drop();
@@ -3934,9 +3933,7 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode)
}
if (e != 0) {
- std::stringstream ss;
- ss << (e->getActiveTab() +1);
- fields[name] = ss.str();
+ fields[name] = itos(e->getActiveTab() + 1);
}
} else if (s.ftype == f_CheckBox) {
// No dynamic cast possible due to some distributions shipped
@@ -3962,12 +3959,10 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode)
e = static_cast<GUIScrollBar *>(element);
if (e) {
- std::stringstream os;
- os << e->getPos();
if (s.fdefault == L"Changed")
- fields[name] = "CHG:" + os.str();
+ fields[name] = "CHG:" + itos(e->getPos());
else
- fields[name] = "VAL:" + os.str();
+ fields[name] = "VAL:" + itos(e->getPos());
}
} else if (s.ftype == f_AnimatedImage) {
// No dynamic cast possible due to some distributions shipped
diff --git a/src/gui/guiVolumeChange.cpp b/src/gui/guiVolumeChange.cpp
index f17cfa986..61ab758a1 100644
--- a/src/gui/guiVolumeChange.cpp
+++ b/src/gui/guiVolumeChange.cpp
@@ -93,11 +93,12 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 160 * s, 20 * s);
rect = rect + v2s32(size.X / 2 - 80 * s, size.Y / 2 - 70 * s);
- const wchar_t *text = wgettext("Sound Volume: ");
+ wchar_t text[100];
+ const wchar_t *str = wgettext("Sound Volume: %d%%");
+ swprintf(text, sizeof(text) / sizeof(wchar_t), str, volume);
+ delete[] str;
core::stringw volume_text = text;
- delete [] text;
- volume_text += core::stringw(volume) + core::stringw("%");
Environment->addStaticText(volume_text.c_str(), rect, false,
true, this, ID_soundText);
}
@@ -183,11 +184,13 @@ bool GUIVolumeChange::OnEvent(const SEvent& event)
g_settings->setFloat("sound_volume", (float) pos / 100);
gui::IGUIElement *e = getElementFromId(ID_soundText);
- const wchar_t *text = wgettext("Sound Volume: ");
+ wchar_t text[100];
+ const wchar_t *str = wgettext("Sound Volume: %d%%");
+ swprintf(text, sizeof(text) / sizeof(wchar_t), str, pos);
+ delete[] str;
+
core::stringw volume_text = text;
- delete [] text;
- volume_text += core::stringw(pos) + core::stringw("%");
e->setText(volume_text.c_str());
return true;
}
diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp
index 0d3fb55f0..1016de389 100644
--- a/src/gui/modalMenu.cpp
+++ b/src/gui/modalMenu.cpp
@@ -268,7 +268,7 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
std::string label = wide_to_utf8(getLabelByID(hovered->getID()));
if (label.empty())
label = "text";
- message += gettext(label) + ":";
+ message += strgettext(label) + ":";
// single line text input
int type = 2;
diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp
index 78b18c2d9..eb20b7e70 100644
--- a/src/gui/touchscreengui.cpp
+++ b/src/gui/touchscreengui.cpp
@@ -32,8 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <iostream>
#include <algorithm>
-#include <ISceneCollisionManager.h>
-
using namespace irr::core;
const char **button_imagenames = (const char *[]) {