Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add chat console scrollbar #15104

Merged
merged 2 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ class ChatBuffer

void resize(u32 scrollback);

protected:
// Get the current scroll position
s32 getScrollPosition() const { return m_scroll; }
s32 getTopScrollPos() const;
s32 getBottomScrollPos() const;

Expand Down
4 changes: 3 additions & 1 deletion src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,9 @@ void Game::processUserInput(f32 dtime)
m_game_focused = true;
}

if (!guienv->hasFocus(gui_chat_console.get()) && gui_chat_console->isOpen()) {
if (!guienv->hasFocus(gui_chat_console.get()) && gui_chat_console->isOpen()
&& !gui_chat_console->isMyChild(guienv->getFocus()))
{
gui_chat_console->closeConsoleAtOnce();
}

Expand Down
66 changes: 54 additions & 12 deletions src/gui/guiChatConsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "gettext.h"
#include "irrlicht_changes/CGUITTFont.h"
#include "util/string.h"
#include "guiScrollBar.h"
#include <string>

inline u32 clamp_u8(s32 value)
Expand All @@ -28,6 +29,11 @@ inline bool isInCtrlKeys(const irr::EKEY_CODE& kc)
return kc == KEY_LCONTROL || kc == KEY_RCONTROL || kc == KEY_CONTROL;
}

inline u32 getScrollbarSize(IGUIEnvironment* env)
{
return env->getSkin()->getSize(gui::EGDS_SCROLLBAR_SIZE);
}

GUIChatConsole::GUIChatConsole(
gui::IGUIEnvironment* env,
gui::IGUIElement* parent,
Expand Down Expand Up @@ -62,15 +68,14 @@ GUIChatConsole::GUIChatConsole(
}

const u16 chat_font_size = g_settings->getU16("chat_font_size");
m_font = g_fontengine->getFont(chat_font_size != 0 ?
rangelim(chat_font_size, 5, 72) : FONT_SIZE_UNSPECIFIED, FM_Mono);
m_font.grab(g_fontengine->getFont(chat_font_size != 0 ?
rangelim(chat_font_size, 5, 72) : FONT_SIZE_UNSPECIFIED, FM_Mono));

if (!m_font) {
errorstream << "GUIChatConsole: Unable to load mono font" << std::endl;
} else {
core::dimension2d<u32> dim = m_font->getDimension(L"M");
m_fontsize = v2u32(dim.Width, dim.Height);
m_font->grab();
}
m_fontsize.X = MYMAX(m_fontsize.X, 1);
m_fontsize.Y = MYMAX(m_fontsize.Y, 1);
Expand All @@ -81,12 +86,11 @@ GUIChatConsole::GUIChatConsole(
// track ctrl keys for mouse event
m_is_ctrl_down = false;
m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks");
}

GUIChatConsole::~GUIChatConsole()
{
if (m_font)
m_font->drop();
m_scrollbar.reset(new GUIScrollBar(env, this, -1, core::rect<s32>(0, 0, 30, m_height), false, true, tsrc));
m_scrollbar->setSubElement(true);
m_scrollbar->setLargeStep(1);
m_scrollbar->setSmallStep(1);
}

void GUIChatConsole::openConsole(f32 scale)
Expand Down Expand Up @@ -121,6 +125,7 @@ void GUIChatConsole::closeConsole()
m_open = false;
Environment->removeFocus(this);
m_menumgr->deletingMenu(this);
m_scrollbar->setVisible(false);
}

void GUIChatConsole::closeConsoleAtOnce()
Expand Down Expand Up @@ -180,6 +185,10 @@ void GUIChatConsole::draw()
m_screensize = screensize;
m_desired_height = m_desired_height_fraction * m_screensize.Y;
reformatConsole();
} else if (!m_scrollbar->getAbsolutePosition().isPointInside(core::vector2di(screensize.X, m_height))) {
// the height of the chat window is no longer the height of the scrollbar
// happens while opening/closing the window
updateScrollbar(true);
}

// Animation
Expand All @@ -204,6 +213,9 @@ void GUIChatConsole::reformatConsole()
s32 rows = m_desired_height / m_fontsize.Y - 1; // make room for the input prompt
if (cols <= 0 || rows <= 0)
cols = rows = 0;

updateScrollbar(true);

recalculateConsolePosition();
m_chat_backend->reformat(cols, rows);
}
Expand Down Expand Up @@ -293,10 +305,17 @@ void GUIChatConsole::drawBackground()

void GUIChatConsole::drawText()
{
if (m_font == NULL)
if (!m_font)
return;

ChatBuffer& buf = m_chat_backend->getConsoleBuffer();

core::recti rect;
if (m_scrollbar->isVisible())
rect = core::rect<s32> (0, 0, m_screensize.X - getScrollbarSize(Environment), m_height);
else
rect = AbsoluteClippingRect;

for (u32 row = 0; row < buf.getRows(); ++row)
{
const ChatFormattedLine& line = buf.getFormattedLine(row);
Expand All @@ -315,13 +334,13 @@ void GUIChatConsole::drawText()

if (m_font->getType() == irr::gui::EGFT_CUSTOM) {
// Draw colored text if possible
gui::CGUITTFont *tmp = static_cast<gui::CGUITTFont*>(m_font);
auto *tmp = static_cast<gui::CGUITTFont*>(m_font.get());
tmp->draw(
fragment.text,
destrect,
false,
false,
&AbsoluteClippingRect);
&rect);
} else {
// Otherwise use standard text
m_font->draw(
Expand All @@ -330,10 +349,12 @@ void GUIChatConsole::drawText()
video::SColor(255, 255, 255, 255),
false,
false,
&AbsoluteClippingRect);
&rect);
}
}
}

updateScrollbar();
}

void GUIChatConsole::drawPrompt()
Expand Down Expand Up @@ -680,6 +701,11 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
prompt.input(std::wstring(event.StringInput.Str->c_str()));
return true;
}
else if (event.EventType == EET_GUI_EVENT && event.GUIEvent.EventType == EGET_SCROLL_BAR_CHANGED &&
(void*) event.GUIEvent.Caller == (void*) m_scrollbar.get())
{
m_chat_backend->getConsoleBuffer().scrollAbsolute(m_scrollbar->getPos());
}

return Parent ? Parent->OnEvent(event) : false;
}
Expand All @@ -692,6 +718,7 @@ void GUIChatConsole::setVisible(bool visible)
m_height = 0;
recalculateConsolePosition();
}
m_scrollbar->setVisible(visible);
}

bool GUIChatConsole::weblinkClick(s32 col, s32 row)
Expand Down Expand Up @@ -763,3 +790,18 @@ void GUIChatConsole::updatePrimarySelection()
std::string selected = wide_to_utf8(wselected);
Environment->getOSOperator()->copyToPrimarySelection(selected.c_str());
}

void GUIChatConsole::updateScrollbar(bool update_size)
{
ChatBuffer &buf = m_chat_backend->getConsoleBuffer();
m_scrollbar->setMin(buf.getTopScrollPos());
m_scrollbar->setMax(buf.getBottomScrollPos());
m_scrollbar->setPos(buf.getScrollPosition());
m_scrollbar->setPageSize(m_fontsize.Y * buf.getLineCount());
m_scrollbar->setVisible(m_scrollbar->getMin() != m_scrollbar->getMax());

if (update_size) {
const core::rect<s32> rect (m_screensize.X - getScrollbarSize(Environment), 0, m_screensize.X, m_height);
SmallJoker marked this conversation as resolved.
Show resolved Hide resolved
m_scrollbar->setRelativePosition(rect);
}
}
8 changes: 6 additions & 2 deletions src/gui/guiChatConsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#include "modalMenu.h"
#include "chat.h"
#include "config.h"
#include "irr_ptr.h"

class Client;
class GUIScrollBar;

class GUIChatConsole : public gui::IGUIElement
{
Expand All @@ -20,7 +22,6 @@ class GUIChatConsole : public gui::IGUIElement
ChatBackend* backend,
Client* client,
IMenuManager* menumgr);
virtual ~GUIChatConsole();

// Open the console (height = desired fraction of screen size)
// This doesn't open immediately but initiates an animation.
Expand Down Expand Up @@ -76,10 +77,13 @@ class GUIChatConsole : public gui::IGUIElement
// If the selected text changed, we need to update the (X11) primary selection.
void updatePrimarySelection();

void updateScrollbar(bool update_size = false);

private:
ChatBackend* m_chat_backend;
Client* m_client;
IMenuManager* m_menumgr;
irr_ptr<GUIScrollBar> m_scrollbar;

// current screen size
v2u32 m_screensize;
Expand Down Expand Up @@ -116,7 +120,7 @@ class GUIChatConsole : public gui::IGUIElement
video::SColor m_background_color = video::SColor(255, 0, 0, 0);

// font
gui::IGUIFont *m_font = nullptr;
irr_ptr<gui::IGUIFont> m_font;
v2u32 m_fontsize;

// Enable clickable chat weblinks
Expand Down
Loading