From b917ea4723fb0fe976486602a456c8dd41eab7ef Mon Sep 17 00:00:00 2001 From: stujones11 Date: Fri, 24 May 2019 16:42:05 +0100 Subject: [PATCH] Add IGUIScrollbar implementation with variable bar sizes (#8507) --- build/android/jni/Android.mk | 1 + src/gui/CMakeLists.txt | 1 + src/gui/guiEditBoxWithScrollbar.cpp | 12 +- src/gui/guiEditBoxWithScrollbar.h | 4 +- src/gui/guiScrollBar.cpp | 442 ++++++++++++++++++++++++++++ src/gui/guiScrollBar.h | 71 +++++ src/gui/guiTable.cpp | 9 +- src/gui/guiTable.h | 3 +- src/gui/intlGUIEditBox.cpp | 10 +- src/gui/intlGUIEditBox.h | 4 +- 10 files changed, 543 insertions(+), 14 deletions(-) create mode 100644 src/gui/guiScrollBar.cpp create mode 100644 src/gui/guiScrollBar.h diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index a8e017510..f35067968 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -185,6 +185,7 @@ LOCAL_SRC_FILES := \ jni/src/gui/guiKeyChangeMenu.cpp \ jni/src/gui/guiPasswordChange.cpp \ jni/src/gui/guiPathSelectMenu.cpp \ + jni/src/gui/guiScrollBar.cpp \ jni/src/gui/guiTable.cpp \ jni/src/gui/guiVolumeChange.cpp \ jni/src/gui/intlGUIEditBox.cpp \ diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 4bc451825..48ba3fa8c 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -7,6 +7,7 @@ set(gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/guiKeyChangeMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiPasswordChange.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiPathSelectMenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiScrollBar.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp ${CMAKE_CURRENT_SOURCE_DIR}/intlGUIEditBox.cpp diff --git a/src/gui/guiEditBoxWithScrollbar.cpp b/src/gui/guiEditBoxWithScrollbar.cpp index 4a821c7b4..b7192b37b 100644 --- a/src/gui/guiEditBoxWithScrollbar.cpp +++ b/src/gui/guiEditBoxWithScrollbar.cpp @@ -13,7 +13,6 @@ #include "porting.h" #include "Keycodes.h" - /* todo: optional scrollbars [done] @@ -76,7 +75,8 @@ GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar() if (m_operator) m_operator->drop(); - m_vscrollbar->remove(); + if (m_vscrollbar) + m_vscrollbar->drop(); } @@ -1400,7 +1400,9 @@ void GUIEditBoxWithScrollBar::createVScrollBar() irr::core::rect scrollbarrect = m_frame_rect; scrollbarrect.UpperLeftCorner.X += m_frame_rect.getWidth() - m_scrollbar_width; - m_vscrollbar = Environment->addScrollBar(false, scrollbarrect, getParent(), getID()); + m_vscrollbar = new guiScrollBar(Environment, getParent(), -1, + scrollbarrect, false, true); + m_vscrollbar->setVisible(false); m_vscrollbar->setSmallStep(1); m_vscrollbar->setLargeStep(1); @@ -1422,6 +1424,7 @@ void GUIEditBoxWithScrollBar::updateVScrollBar() if (scrollymax != m_vscrollbar->getMax()) { // manage a newline or a deleted line m_vscrollbar->setMax(scrollymax); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); calculateScrollPos(); } else { // manage a newline or a deleted line @@ -1436,6 +1439,7 @@ void GUIEditBoxWithScrollBar::updateVScrollBar() s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight(); if (scrollymax != m_vscrollbar->getMax()) { m_vscrollbar->setMax(scrollymax); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); } if (!m_vscrollbar->isVisible()) { @@ -1448,10 +1452,10 @@ void GUIEditBoxWithScrollBar::updateVScrollBar() m_vscroll_pos = 0; m_vscrollbar->setPos(0); m_vscrollbar->setMax(1); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); } } - } //! set true if this editbox is writable diff --git a/src/gui/guiEditBoxWithScrollbar.h b/src/gui/guiEditBoxWithScrollbar.h index cedffd82f..b872d7e36 100644 --- a/src/gui/guiEditBoxWithScrollbar.h +++ b/src/gui/guiEditBoxWithScrollbar.h @@ -7,7 +7,7 @@ #include "IGUIEditBox.h" #include "IOSOperator.h" -#include "IGUIScrollBar.h" +#include "guiScrollBar.h" #include using namespace irr; @@ -187,7 +187,7 @@ protected: core::rect m_current_text_rect, m_frame_rect; // temporary values u32 m_scrollbar_width; - IGUIScrollBar *m_vscrollbar; + guiScrollBar *m_vscrollbar; bool m_writable; bool m_bg_color_used; diff --git a/src/gui/guiScrollBar.cpp b/src/gui/guiScrollBar.cpp new file mode 100644 index 000000000..40c15d639 --- /dev/null +++ b/src/gui/guiScrollBar.cpp @@ -0,0 +1,442 @@ +/* +Copyright (C) 2002-2013 Nikolaus Gebhardt +This file is part of the "Irrlicht Engine". +For conditions of distribution and use, see copyright notice in irrlicht.h + +Modified 2019.05.01 by stujones11, Stuart Jones + +This is a heavily modified copy of the Irrlicht CGUIScrollBar class +which includes automatic scaling of the thumb slider and hiding of +the arrow buttons where there is insufficient space. +*/ + +#include "guiScrollBar.h" +#include +#include + +guiScrollBar::guiScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id, + core::rect rectangle, bool horizontal, bool auto_scale) : + IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle), + up_button(nullptr), down_button(nullptr), is_dragging(false), + is_horizontal(horizontal), is_auto_scaling(auto_scale), + dragged_by_slider(false), tray_clicked(false), scroll_pos(0), + draw_center(0), thumb_size(0), min_pos(0), max_pos(100), small_step(10), + large_step(50), desired_pos(0), last_change(0), drag_offset(0), + page_size(100), border_size(0) +{ + refreshControls(); + setNotClipped(false); + setTabStop(true); + setTabOrder(-1); + setPos(0); +} + +bool guiScrollBar::OnEvent(const SEvent &event) +{ + if (isEnabled()) { + switch (event.EventType) { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown) { + const s32 old_pos = scroll_pos; + bool absorb = true; + switch (event.KeyInput.Key) { + case KEY_LEFT: + case KEY_UP: + setPos(scroll_pos - small_step); + break; + case KEY_RIGHT: + case KEY_DOWN: + setPos(scroll_pos + small_step); + break; + case KEY_HOME: + setPos(min_pos); + break; + case KEY_PRIOR: + setPos(scroll_pos - large_step); + break; + case KEY_END: + setPos(max_pos); + break; + case KEY_NEXT: + setPos(scroll_pos + large_step); + break; + default: + absorb = false; + } + if (scroll_pos != old_pos) { + 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); + } + if (absorb) + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) { + if (event.GUIEvent.Caller == up_button) + setPos(scroll_pos - small_step); + else if (event.GUIEvent.Caller == down_button) + setPos(scroll_pos + small_step); + + 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 true; + } else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + if (event.GUIEvent.Caller == this) + is_dragging = false; + break; + case EET_MOUSE_INPUT_EVENT: { + const core::position2di p(event.MouseInput.X, event.MouseInput.Y); + bool is_inside = isPointInside(p); + switch (event.MouseInput.Event) { + case EMIE_MOUSE_WHEEL: + if (Environment->hasFocus(this)) { + s8 d = event.MouseInput.Wheel < 0 ? -1 : 1; + s8 h = is_horizontal ? 1 : -1; + setPos(getPos() + (d * small_step * h)); + + 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 true; + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: { + if (is_inside) { + is_dragging = true; + dragged_by_slider = slider_rect.isPointInside(p); + core::vector2di corner = + slider_rect.UpperLeftCorner; + drag_offset = is_horizontal ? p.X - corner.X + : p.Y - corner.Y; + tray_clicked = !dragged_by_slider; + desired_pos = getPosFromMousePos(p); + Environment->setFocus(this); + return true; + } + break; + } + case EMIE_LMOUSE_LEFT_UP: + case EMIE_MOUSE_MOVED: { + if (!event.MouseInput.isLeftPressed()) + is_dragging = false; + + if (!is_dragging) { + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + break; + return is_inside; + } + + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + is_dragging = false; + + // clang-format off + if (!dragged_by_slider) { + if (is_inside) { + dragged_by_slider = slider_rect.isPointInside(p); + tray_clicked = !dragged_by_slider; + } + if (!dragged_by_slider) { + tray_clicked = false; + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + return is_inside; + } + } + // clang-format on + + const s32 new_pos = getPosFromMousePos(p); + const s32 old_pos = scroll_pos; + + if (dragged_by_slider) + setPos(new_pos); + else + desired_pos = 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: + break; + } + } break; + default: + break; + } + } + return IGUIElement::OnEvent(event); +} + +void guiScrollBar::OnPostRender(u32 timeMs) +{ + if (is_dragging && !dragged_by_slider && tray_clicked && + timeMs > last_change + 200) { + last_change = timeMs; + const s32 old_pos = scroll_pos; + + if (desired_pos >= scroll_pos + large_step) + setPos(scroll_pos + large_step); + else if (desired_pos <= scroll_pos - large_step) + setPos(scroll_pos - large_step); + else if (desired_pos >= scroll_pos - large_step && + desired_pos <= scroll_pos + large_step) + setPos(desired_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::draw() +{ + if (!IsVisible) + return; + + IGUISkin *skin = Environment->getSkin(); + if (!skin) + return; + + video::SColor icon_color = skin->getColor( + isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + if (icon_color != current_icon_color) + refreshControls(); + + slider_rect = AbsoluteRect; + skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), slider_rect, + &AbsoluteClippingRect); + + if (core::isnotzero(range())) { + if (is_horizontal) { + slider_rect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + + draw_center - thumb_size / 2; + slider_rect.LowerRightCorner.X = + slider_rect.UpperLeftCorner.X + thumb_size; + } else { + slider_rect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + + draw_center - thumb_size / 2; + slider_rect.LowerRightCorner.Y = + slider_rect.UpperLeftCorner.Y + thumb_size; + } + skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect); + } + IGUIElement::draw(); +} + +void guiScrollBar::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + refreshControls(); + setPos(scroll_pos); +} + +s32 guiScrollBar::getPosFromMousePos(const core::position2di &pos) const +{ + s32 w, p; + s32 offset = dragged_by_slider ? drag_offset : thumb_size / 2; + + if (is_horizontal) { + w = RelativeRect.getWidth() - border_size * 2 - thumb_size; + p = pos.X - AbsoluteRect.UpperLeftCorner.X - border_size - offset; + } else { + w = RelativeRect.getHeight() - border_size * 2 - thumb_size; + p = pos.Y - AbsoluteRect.UpperLeftCorner.Y - border_size - offset; + } + return core::isnotzero(range()) ? s32(f32(p) / f32(w) * range()) + min_pos : 0; +} + +void guiScrollBar::setPos(const s32 &pos) +{ + s32 thumb_area = 0; + s32 thumb_min = 0; + + if (is_horizontal) { + thumb_min = RelativeRect.getHeight(); + thumb_area = RelativeRect.getWidth() - border_size * 2; + } else { + thumb_min = RelativeRect.getWidth(); + thumb_area = RelativeRect.getHeight() - border_size * 2; + } + + if (is_auto_scaling) + thumb_size = s32(thumb_area / + (f32(page_size) / f32(thumb_area + border_size * 2))); + + thumb_size = core::s32_clamp(thumb_size, thumb_min, thumb_area); + scroll_pos = core::s32_clamp(pos, min_pos, max_pos); + + f32 f = core::isnotzero(range()) ? (f32(thumb_area) - f32(thumb_size)) / range() + : 1.0f; + draw_center = s32((f32(scroll_pos) * f) + (f32(thumb_size) * 0.5f)) + border_size; +} + +void guiScrollBar::setSmallStep(const s32 &step) +{ + small_step = step > 0 ? step : 10; +} + +void guiScrollBar::setLargeStep(const s32 &step) +{ + large_step = step > 0 ? step : 50; +} + +void guiScrollBar::setMax(const s32 &max) +{ + max_pos = max; + if (min_pos > max_pos) + min_pos = max_pos; + + bool enable = core::isnotzero(range()); + up_button->setEnabled(enable); + down_button->setEnabled(enable); + setPos(scroll_pos); +} + +void guiScrollBar::setMin(const s32 &min) +{ + min_pos = min; + if (max_pos < min_pos) + max_pos = min_pos; + + bool enable = core::isnotzero(range()); + up_button->setEnabled(enable); + down_button->setEnabled(enable); + setPos(scroll_pos); +} + +void guiScrollBar::setPageSize(const s32 &size) +{ + page_size = size; + setPos(scroll_pos); +} + +s32 guiScrollBar::getPos() const +{ + return scroll_pos; +} + +void guiScrollBar::refreshControls() +{ + IGUISkin *skin = Environment->getSkin(); + IGUISpriteBank *sprites = nullptr; + current_icon_color = video::SColor(255, 255, 255, 255); + + if (skin) { + sprites = skin->getSpriteBank(); + current_icon_color = + skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL + : EGDC_GRAY_WINDOW_SYMBOL); + } + if (is_horizontal) { + s32 h = RelativeRect.getHeight(); + border_size = RelativeRect.getWidth() < h * 4 ? 0 : h; + if (!up_button) { + up_button = Environment->addButton( + core::rect(0, 0, h, h), this); + up_button->setSubElement(true); + up_button->setTabStop(false); + } + if (sprites) { + up_button->setSpriteBank(sprites); + up_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_LEFT)), + current_icon_color); + up_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_LEFT)), + current_icon_color); + } + up_button->setRelativePosition(core::rect(0, 0, h, h)); + up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, + EGUIA_LOWERRIGHT); + if (!down_button) { + down_button = Environment->addButton( + core::rect(RelativeRect.getWidth() - h, 0, + RelativeRect.getWidth(), h), + this); + down_button->setSubElement(true); + down_button->setTabStop(false); + } + if (sprites) { + down_button->setSpriteBank(sprites); + down_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_RIGHT)), + current_icon_color); + down_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_RIGHT)), + current_icon_color); + } + down_button->setRelativePosition( + core::rect(RelativeRect.getWidth() - h, 0, + RelativeRect.getWidth(), h)); + down_button->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, + EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + } else { + s32 w = RelativeRect.getWidth(); + border_size = RelativeRect.getHeight() < w * 4 ? 0 : w; + if (!up_button) { + up_button = Environment->addButton( + core::rect(0, 0, w, w), this); + up_button->setSubElement(true); + up_button->setTabStop(false); + } + if (sprites) { + up_button->setSpriteBank(sprites); + up_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_UP)), + current_icon_color); + up_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_UP)), + current_icon_color); + } + up_button->setRelativePosition(core::rect(0, 0, w, w)); + up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, + EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (!down_button) { + down_button = Environment->addButton( + core::rect(0, RelativeRect.getHeight() - w, + w, RelativeRect.getHeight()), + this); + down_button->setSubElement(true); + down_button->setTabStop(false); + } + if (sprites) { + down_button->setSpriteBank(sprites); + down_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_DOWN)), + current_icon_color); + down_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_DOWN)), + current_icon_color); + } + down_button->setRelativePosition( + core::rect(0, RelativeRect.getHeight() - w, w, + RelativeRect.getHeight())); + down_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, + EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); + } + bool visible = (border_size != 0); + up_button->setVisible(visible); + down_button->setVisible(visible); +} \ No newline at end of file diff --git a/src/gui/guiScrollBar.h b/src/gui/guiScrollBar.h new file mode 100644 index 000000000..be392bc00 --- /dev/null +++ b/src/gui/guiScrollBar.h @@ -0,0 +1,71 @@ +/* +Copyright (C) 2002-2013 Nikolaus Gebhardt +This file is part of the "Irrlicht Engine". +For conditions of distribution and use, see copyright notice in irrlicht.h + +Modified 2019.05.01 by stujones11, Stuart Jones + +This is a heavily modified copy of the Irrlicht CGUIScrollBar class +which includes automatic scaling of the thumb slider and hiding of +the arrow buttons where there is insufficient space. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" + +using namespace irr; +using namespace gui; + +class guiScrollBar : public IGUIElement +{ +public: + guiScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id, + core::rect rectangle, bool horizontal, bool auto_scale); + + virtual void draw(); + virtual void updateAbsolutePosition(); + virtual bool OnEvent(const SEvent &event); + virtual void OnPostRender(u32 timeMs); + + s32 getMax() const { return max_pos; } + s32 getMin() const { return min_pos; } + s32 getLargeStep() const { return large_step; } + s32 getSmallStep() const { return small_step; } + s32 getPos() const; + + void setMax(const s32 &max); + void setMin(const s32 &min); + void setSmallStep(const s32 &step); + void setLargeStep(const s32 &step); + void setPos(const s32 &pos); + void setPageSize(const s32 &size); + +private: + void refreshControls(); + s32 getPosFromMousePos(const core::position2di &p) const; + f32 range() const { return f32(max_pos - min_pos); } + + IGUIButton *up_button; + IGUIButton *down_button; + bool is_dragging; + bool is_horizontal; + bool is_auto_scaling; + bool dragged_by_slider; + bool tray_clicked; + s32 scroll_pos; + s32 draw_center; + s32 thumb_size; + s32 min_pos; + s32 max_pos; + s32 small_step; + s32 large_step; + s32 desired_pos; + u32 last_change; + s32 drag_offset; + s32 page_size; + s32 border_size; + + core::rect slider_rect; + video::SColor current_icon_color; +}; \ No newline at end of file diff --git a/src/gui/guiTable.cpp b/src/gui/guiTable.cpp index a123bdd6d..371e7ab6c 100644 --- a/src/gui/guiTable.cpp +++ b/src/gui/guiTable.cpp @@ -25,7 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#include #include "client/renderingengine.h" #include "debug.h" #include "log.h" @@ -62,12 +61,12 @@ GUITable::GUITable(gui::IGUIEnvironment *env, } const s32 s = skin->getSize(gui::EGDS_SCROLLBAR_SIZE); - m_scrollbar = Environment->addScrollBar(false, + m_scrollbar = new guiScrollBar(Environment, this, -1, core::rect(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), - this, -1); + false, true); m_scrollbar->setSubElement(true); m_scrollbar->setTabStop(false); m_scrollbar->setAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_LOWERRIGHT, @@ -99,7 +98,8 @@ GUITable::~GUITable() if (m_font) m_font->drop(); - m_scrollbar->remove(); + if (m_scrollbar) + m_scrollbar->drop(); } GUITable::Option GUITable::splitOption(const std::string &str) @@ -1075,6 +1075,7 @@ void GUITable::updateScrollBar() m_scrollbar->setMax(scrollmax); m_scrollbar->setSmallStep(m_rowheight); m_scrollbar->setLargeStep(2 * m_rowheight); + m_scrollbar->setPageSize(totalheight); } void GUITable::sendTableEvent(s32 column, bool doubleclick) diff --git a/src/gui/guiTable.h b/src/gui/guiTable.h index f9337ff6d..1893be5c3 100644 --- a/src/gui/guiTable.h +++ b/src/gui/guiTable.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "irrlichttypes_extrabloated.h" +#include "guiScrollBar.h" class ISimpleTextureSource; @@ -198,7 +199,7 @@ protected: video::SColor m_highlight_text = video::SColor(255, 255, 255, 255); s32 m_rowheight = 1; gui::IGUIFont *m_font = nullptr; - gui::IGUIScrollBar *m_scrollbar = nullptr; + guiScrollBar *m_scrollbar = nullptr; // Allocated strings and images std::vector m_strings; diff --git a/src/gui/intlGUIEditBox.cpp b/src/gui/intlGUIEditBox.cpp index fd3caa0f7..1f1c85ad5 100644 --- a/src/gui/intlGUIEditBox.cpp +++ b/src/gui/intlGUIEditBox.cpp @@ -113,6 +113,9 @@ intlGUIEditBox::~intlGUIEditBox() if (Operator) Operator->drop(); + + if (m_vscrollbar) + m_vscrollbar->drop(); } @@ -1479,7 +1482,9 @@ void intlGUIEditBox::createVScrollBar() irr::core::rect scrollbarrect = FrameRect; scrollbarrect.UpperLeftCorner.X += FrameRect.getWidth() - m_scrollbar_width; - m_vscrollbar = Environment->addScrollBar(false, scrollbarrect, getParent(), getID()); + m_vscrollbar = new guiScrollBar(Environment, getParent(), -1, + scrollbarrect, false, true); + m_vscrollbar->setVisible(false); m_vscrollbar->setSmallStep(3 * fontHeight); m_vscrollbar->setLargeStep(10 * fontHeight); @@ -1501,6 +1506,7 @@ void intlGUIEditBox::updateVScrollBar() if (scrollymax != m_vscrollbar->getMax()) { // manage a newline or a deleted line m_vscrollbar->setMax(scrollymax); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); calculateScrollPos(); } else { // manage a newline or a deleted line @@ -1513,6 +1519,7 @@ void intlGUIEditBox::updateVScrollBar() s32 scrollymax = getTextDimension().Height - FrameRect.getHeight(); if (scrollymax != m_vscrollbar->getMax()) { m_vscrollbar->setMax(scrollymax); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); } if (!m_vscrollbar->isVisible() && MultiLine) { @@ -1527,6 +1534,7 @@ void intlGUIEditBox::updateVScrollBar() VScrollPos = 0; m_vscrollbar->setPos(0); m_vscrollbar->setMax(1); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); m_vscrollbar->setVisible(false); } } diff --git a/src/gui/intlGUIEditBox.h b/src/gui/intlGUIEditBox.h index 3aa4f00b4..476f7f5de 100644 --- a/src/gui/intlGUIEditBox.h +++ b/src/gui/intlGUIEditBox.h @@ -10,7 +10,7 @@ #include #include "irrArray.h" #include "IOSOperator.h" -#include "IGUIScrollBar.h" +#include "guiScrollBar.h" namespace irr { @@ -198,7 +198,7 @@ namespace gui core::rect CurrentTextRect = core::rect(0,0,1,1); core::rect FrameRect; // temporary values u32 m_scrollbar_width; - IGUIScrollBar *m_vscrollbar; + guiScrollBar *m_vscrollbar; bool m_writable; };