diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index eb7eda0d7..8828fc1df 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -694,6 +694,9 @@ language (Language) enum ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,i # edge pixels when images are scaled by non-integer sizes. gui_scaling (GUI scaling) float 1.0 0.5 20 +# Enables smooth scrolling. +smooth_scrolling (Smooth scrolling) bool true + # Enables animation of inventory items. inventory_items_animations (Inventory items animations) bool false diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 5fce1b0a8..f8cfd18b4 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -299,6 +299,7 @@ void set_default_settings() settings->setDefault("gui_scaling", "1.0"); settings->setDefault("gui_scaling_filter", "false"); settings->setDefault("gui_scaling_filter_txr2img", "true"); + settings->setDefault("smooth_scrolling", "true"); settings->setDefault("desynchronize_mapblock_texture_animation", "false"); settings->setDefault("hud_hotbar_max_width", "1.0"); settings->setDefault("enable_local_map_saving", "false"); diff --git a/src/gui/guiScrollBar.cpp b/src/gui/guiScrollBar.cpp index 8e8935b2d..01a7af8c9 100644 --- a/src/gui/guiScrollBar.cpp +++ b/src/gui/guiScrollBar.cpp @@ -13,6 +13,7 @@ the arrow buttons where there is insufficient space. #include "guiScrollBar.h" #include "guiButton.h" #include "porting.h" +#include "settings.h" #include GUIScrollBar::GUIScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id, @@ -101,19 +102,9 @@ bool GUIScrollBar::OnEvent(const SEvent &event) tray_clicked = !dragged_by_slider; if (tray_clicked) { const s32 new_pos = getPosFromMousePos(p); - const s32 old_pos = scroll_pos; - setPos(new_pos); + setPosAndSend(new_pos); // drag in the middle drag_offset = thumb_size / 2; - // report the scroll event - if (scroll_pos != old_pos && Parent) { - SEvent e; - e.EventType = EET_GUI_EVENT; - e.GUIEvent.Caller = this; - e.GUIEvent.Element = nullptr; - e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; - Parent->OnEvent(e); - } } Environment->setFocus(this); return true; @@ -147,18 +138,8 @@ bool GUIScrollBar::OnEvent(const SEvent &event) } const s32 new_pos = getPosFromMousePos(p); - const s32 old_pos = scroll_pos; + setPosAndSend(new_pos); - setPos(new_pos); - - if (scroll_pos != old_pos && Parent) { - SEvent e; - e.EventType = EET_GUI_EVENT; - e.GUIEvent.Caller = this; - e.GUIEvent.Element = nullptr; - e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; - Parent->OnEvent(e); - } return is_inside; } default: @@ -300,8 +281,27 @@ void GUIScrollBar::setPos(const s32 &pos) target_pos = std::nullopt; } +void GUIScrollBar::setPosAndSend(const s32 &pos) +{ + const s32 old_pos = scroll_pos; + setPos(pos); + if (scroll_pos != old_pos && Parent) { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(e); + } +} + void GUIScrollBar::setPosInterpolated(const s32 &pos) { + if (!g_settings->getBool("smooth_scrolling")) { + setPosAndSend(pos); + return; + } + s32 clamped = core::s32_clamp(pos, min_pos, max_pos); if (scroll_pos != clamped) { target_pos = clamped; diff --git a/src/gui/guiScrollBar.h b/src/gui/guiScrollBar.h index a976d1a59..05e195aed 100644 --- a/src/gui/guiScrollBar.h +++ b/src/gui/guiScrollBar.h @@ -53,6 +53,8 @@ public: //! Sets a position immediately, aborting any ongoing interpolation. // setPos does not send EGET_SCROLL_BAR_CHANGED events for you. void setPos(const s32 &pos); + //! The same as setPos, but it takes care of sending EGET_SCROLL_BAR_CHANGED events. + void setPosAndSend(const s32 &pos); //! Sets a target position for interpolation. // If you want to do an interpolated addition, use // setPosInterpolated(getTargetPos() + x).