forked from Mirrorlandia_minetest/minetest
Add IGUIScrollbar implementation with variable bar sizes (#8507)
This commit is contained in:
parent
a2848c9cde
commit
b917ea4723
@ -185,6 +185,7 @@ LOCAL_SRC_FILES := \
|
|||||||
jni/src/gui/guiKeyChangeMenu.cpp \
|
jni/src/gui/guiKeyChangeMenu.cpp \
|
||||||
jni/src/gui/guiPasswordChange.cpp \
|
jni/src/gui/guiPasswordChange.cpp \
|
||||||
jni/src/gui/guiPathSelectMenu.cpp \
|
jni/src/gui/guiPathSelectMenu.cpp \
|
||||||
|
jni/src/gui/guiScrollBar.cpp \
|
||||||
jni/src/gui/guiTable.cpp \
|
jni/src/gui/guiTable.cpp \
|
||||||
jni/src/gui/guiVolumeChange.cpp \
|
jni/src/gui/guiVolumeChange.cpp \
|
||||||
jni/src/gui/intlGUIEditBox.cpp \
|
jni/src/gui/intlGUIEditBox.cpp \
|
||||||
|
@ -7,6 +7,7 @@ set(gui_SRCS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiKeyChangeMenu.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiKeyChangeMenu.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiPasswordChange.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiPasswordChange.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiPathSelectMenu.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiPathSelectMenu.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/guiScrollBar.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/intlGUIEditBox.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/intlGUIEditBox.cpp
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "Keycodes.h"
|
#include "Keycodes.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
todo:
|
todo:
|
||||||
optional scrollbars [done]
|
optional scrollbars [done]
|
||||||
@ -76,7 +75,8 @@ GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar()
|
|||||||
if (m_operator)
|
if (m_operator)
|
||||||
m_operator->drop();
|
m_operator->drop();
|
||||||
|
|
||||||
m_vscrollbar->remove();
|
if (m_vscrollbar)
|
||||||
|
m_vscrollbar->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1400,7 +1400,9 @@ void GUIEditBoxWithScrollBar::createVScrollBar()
|
|||||||
|
|
||||||
irr::core::rect<s32> scrollbarrect = m_frame_rect;
|
irr::core::rect<s32> scrollbarrect = m_frame_rect;
|
||||||
scrollbarrect.UpperLeftCorner.X += m_frame_rect.getWidth() - m_scrollbar_width;
|
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->setVisible(false);
|
||||||
m_vscrollbar->setSmallStep(1);
|
m_vscrollbar->setSmallStep(1);
|
||||||
m_vscrollbar->setLargeStep(1);
|
m_vscrollbar->setLargeStep(1);
|
||||||
@ -1422,6 +1424,7 @@ void GUIEditBoxWithScrollBar::updateVScrollBar()
|
|||||||
if (scrollymax != m_vscrollbar->getMax()) {
|
if (scrollymax != m_vscrollbar->getMax()) {
|
||||||
// manage a newline or a deleted line
|
// manage a newline or a deleted line
|
||||||
m_vscrollbar->setMax(scrollymax);
|
m_vscrollbar->setMax(scrollymax);
|
||||||
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
calculateScrollPos();
|
calculateScrollPos();
|
||||||
} else {
|
} else {
|
||||||
// manage a newline or a deleted line
|
// manage a newline or a deleted line
|
||||||
@ -1436,6 +1439,7 @@ void GUIEditBoxWithScrollBar::updateVScrollBar()
|
|||||||
s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight();
|
s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight();
|
||||||
if (scrollymax != m_vscrollbar->getMax()) {
|
if (scrollymax != m_vscrollbar->getMax()) {
|
||||||
m_vscrollbar->setMax(scrollymax);
|
m_vscrollbar->setMax(scrollymax);
|
||||||
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_vscrollbar->isVisible()) {
|
if (!m_vscrollbar->isVisible()) {
|
||||||
@ -1448,10 +1452,10 @@ void GUIEditBoxWithScrollBar::updateVScrollBar()
|
|||||||
m_vscroll_pos = 0;
|
m_vscroll_pos = 0;
|
||||||
m_vscrollbar->setPos(0);
|
m_vscrollbar->setPos(0);
|
||||||
m_vscrollbar->setMax(1);
|
m_vscrollbar->setMax(1);
|
||||||
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! set true if this editbox is writable
|
//! set true if this editbox is writable
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "IGUIEditBox.h"
|
#include "IGUIEditBox.h"
|
||||||
#include "IOSOperator.h"
|
#include "IOSOperator.h"
|
||||||
#include "IGUIScrollBar.h"
|
#include "guiScrollBar.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
@ -187,7 +187,7 @@ protected:
|
|||||||
core::rect<s32> m_current_text_rect, m_frame_rect; // temporary values
|
core::rect<s32> m_current_text_rect, m_frame_rect; // temporary values
|
||||||
|
|
||||||
u32 m_scrollbar_width;
|
u32 m_scrollbar_width;
|
||||||
IGUIScrollBar *m_vscrollbar;
|
guiScrollBar *m_vscrollbar;
|
||||||
bool m_writable;
|
bool m_writable;
|
||||||
|
|
||||||
bool m_bg_color_used;
|
bool m_bg_color_used;
|
||||||
|
442
src/gui/guiScrollBar.cpp
Normal file
442
src/gui/guiScrollBar.cpp
Normal file
@ -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 <stujones111@gmail.com>
|
||||||
|
|
||||||
|
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 <IGUIButton.h>
|
||||||
|
#include <IGUISkin.h>
|
||||||
|
|
||||||
|
guiScrollBar::guiScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id,
|
||||||
|
core::rect<s32> 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<s32>(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<s32>(0, 0, h, h));
|
||||||
|
up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT,
|
||||||
|
EGUIA_LOWERRIGHT);
|
||||||
|
if (!down_button) {
|
||||||
|
down_button = Environment->addButton(
|
||||||
|
core::rect<s32>(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<s32>(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<s32>(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<s32>(0, 0, w, w));
|
||||||
|
up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT,
|
||||||
|
EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
|
||||||
|
if (!down_button) {
|
||||||
|
down_button = Environment->addButton(
|
||||||
|
core::rect<s32>(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<s32>(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);
|
||||||
|
}
|
71
src/gui/guiScrollBar.h
Normal file
71
src/gui/guiScrollBar.h
Normal file
@ -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 <stujones111@gmail.com>
|
||||||
|
|
||||||
|
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<s32> 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<s32> slider_rect;
|
||||||
|
video::SColor current_icon_color;
|
||||||
|
};
|
@ -25,7 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <IGUISkin.h>
|
#include <IGUISkin.h>
|
||||||
#include <IGUIFont.h>
|
#include <IGUIFont.h>
|
||||||
#include <IGUIScrollBar.h>
|
|
||||||
#include "client/renderingengine.h"
|
#include "client/renderingengine.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -62,12 +61,12 @@ GUITable::GUITable(gui::IGUIEnvironment *env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const s32 s = skin->getSize(gui::EGDS_SCROLLBAR_SIZE);
|
const s32 s = skin->getSize(gui::EGDS_SCROLLBAR_SIZE);
|
||||||
m_scrollbar = Environment->addScrollBar(false,
|
m_scrollbar = new guiScrollBar(Environment, this, -1,
|
||||||
core::rect<s32>(RelativeRect.getWidth() - s,
|
core::rect<s32>(RelativeRect.getWidth() - s,
|
||||||
0,
|
0,
|
||||||
RelativeRect.getWidth(),
|
RelativeRect.getWidth(),
|
||||||
RelativeRect.getHeight()),
|
RelativeRect.getHeight()),
|
||||||
this, -1);
|
false, true);
|
||||||
m_scrollbar->setSubElement(true);
|
m_scrollbar->setSubElement(true);
|
||||||
m_scrollbar->setTabStop(false);
|
m_scrollbar->setTabStop(false);
|
||||||
m_scrollbar->setAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_LOWERRIGHT,
|
m_scrollbar->setAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_LOWERRIGHT,
|
||||||
@ -99,7 +98,8 @@ GUITable::~GUITable()
|
|||||||
if (m_font)
|
if (m_font)
|
||||||
m_font->drop();
|
m_font->drop();
|
||||||
|
|
||||||
m_scrollbar->remove();
|
if (m_scrollbar)
|
||||||
|
m_scrollbar->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
GUITable::Option GUITable::splitOption(const std::string &str)
|
GUITable::Option GUITable::splitOption(const std::string &str)
|
||||||
@ -1075,6 +1075,7 @@ void GUITable::updateScrollBar()
|
|||||||
m_scrollbar->setMax(scrollmax);
|
m_scrollbar->setMax(scrollmax);
|
||||||
m_scrollbar->setSmallStep(m_rowheight);
|
m_scrollbar->setSmallStep(m_rowheight);
|
||||||
m_scrollbar->setLargeStep(2 * m_rowheight);
|
m_scrollbar->setLargeStep(2 * m_rowheight);
|
||||||
|
m_scrollbar->setPageSize(totalheight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUITable::sendTableEvent(s32 column, bool doubleclick)
|
void GUITable::sendTableEvent(s32 column, bool doubleclick)
|
||||||
|
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
|
#include "guiScrollBar.h"
|
||||||
|
|
||||||
class ISimpleTextureSource;
|
class ISimpleTextureSource;
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ protected:
|
|||||||
video::SColor m_highlight_text = video::SColor(255, 255, 255, 255);
|
video::SColor m_highlight_text = video::SColor(255, 255, 255, 255);
|
||||||
s32 m_rowheight = 1;
|
s32 m_rowheight = 1;
|
||||||
gui::IGUIFont *m_font = nullptr;
|
gui::IGUIFont *m_font = nullptr;
|
||||||
gui::IGUIScrollBar *m_scrollbar = nullptr;
|
guiScrollBar *m_scrollbar = nullptr;
|
||||||
|
|
||||||
// Allocated strings and images
|
// Allocated strings and images
|
||||||
std::vector<core::stringw> m_strings;
|
std::vector<core::stringw> m_strings;
|
||||||
|
@ -113,6 +113,9 @@ intlGUIEditBox::~intlGUIEditBox()
|
|||||||
|
|
||||||
if (Operator)
|
if (Operator)
|
||||||
Operator->drop();
|
Operator->drop();
|
||||||
|
|
||||||
|
if (m_vscrollbar)
|
||||||
|
m_vscrollbar->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1479,7 +1482,9 @@ void intlGUIEditBox::createVScrollBar()
|
|||||||
|
|
||||||
irr::core::rect<s32> scrollbarrect = FrameRect;
|
irr::core::rect<s32> scrollbarrect = FrameRect;
|
||||||
scrollbarrect.UpperLeftCorner.X += FrameRect.getWidth() - m_scrollbar_width;
|
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->setVisible(false);
|
||||||
m_vscrollbar->setSmallStep(3 * fontHeight);
|
m_vscrollbar->setSmallStep(3 * fontHeight);
|
||||||
m_vscrollbar->setLargeStep(10 * fontHeight);
|
m_vscrollbar->setLargeStep(10 * fontHeight);
|
||||||
@ -1501,6 +1506,7 @@ void intlGUIEditBox::updateVScrollBar()
|
|||||||
if (scrollymax != m_vscrollbar->getMax()) {
|
if (scrollymax != m_vscrollbar->getMax()) {
|
||||||
// manage a newline or a deleted line
|
// manage a newline or a deleted line
|
||||||
m_vscrollbar->setMax(scrollymax);
|
m_vscrollbar->setMax(scrollymax);
|
||||||
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
calculateScrollPos();
|
calculateScrollPos();
|
||||||
} else {
|
} else {
|
||||||
// manage a newline or a deleted line
|
// manage a newline or a deleted line
|
||||||
@ -1513,6 +1519,7 @@ void intlGUIEditBox::updateVScrollBar()
|
|||||||
s32 scrollymax = getTextDimension().Height - FrameRect.getHeight();
|
s32 scrollymax = getTextDimension().Height - FrameRect.getHeight();
|
||||||
if (scrollymax != m_vscrollbar->getMax()) {
|
if (scrollymax != m_vscrollbar->getMax()) {
|
||||||
m_vscrollbar->setMax(scrollymax);
|
m_vscrollbar->setMax(scrollymax);
|
||||||
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_vscrollbar->isVisible() && MultiLine) {
|
if (!m_vscrollbar->isVisible() && MultiLine) {
|
||||||
@ -1527,6 +1534,7 @@ void intlGUIEditBox::updateVScrollBar()
|
|||||||
VScrollPos = 0;
|
VScrollPos = 0;
|
||||||
m_vscrollbar->setPos(0);
|
m_vscrollbar->setPos(0);
|
||||||
m_vscrollbar->setMax(1);
|
m_vscrollbar->setMax(1);
|
||||||
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
m_vscrollbar->setVisible(false);
|
m_vscrollbar->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <IGUIEditBox.h>
|
#include <IGUIEditBox.h>
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
#include "IOSOperator.h"
|
#include "IOSOperator.h"
|
||||||
#include "IGUIScrollBar.h"
|
#include "guiScrollBar.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -198,7 +198,7 @@ namespace gui
|
|||||||
core::rect<s32> CurrentTextRect = core::rect<s32>(0,0,1,1);
|
core::rect<s32> CurrentTextRect = core::rect<s32>(0,0,1,1);
|
||||||
core::rect<s32> FrameRect; // temporary values
|
core::rect<s32> FrameRect; // temporary values
|
||||||
u32 m_scrollbar_width;
|
u32 m_scrollbar_width;
|
||||||
IGUIScrollBar *m_vscrollbar;
|
guiScrollBar *m_vscrollbar;
|
||||||
bool m_writable;
|
bool m_writable;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user