Customizable scrollbar
This commit is contained in:
parent
a1e9311253
commit
b5672f20f6
@ -2478,7 +2478,7 @@ Elements
|
||||
* **Note**: If the new coordinate system is enabled, checkboxes are
|
||||
positioned from the center of the checkbox, not the top.
|
||||
|
||||
### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]`
|
||||
### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>;<bg.png,slider.png,arrow_up.png,arrow_down.png>]`
|
||||
|
||||
* Show a scrollbar using options defined by the previous `scrollbaroptions[]`
|
||||
* There are two ways to use it:
|
||||
|
@ -648,6 +648,10 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, const std::string &elemen
|
||||
std::vector<std::string> v_geom = split(parts[1],',');
|
||||
std::string name = parts[3];
|
||||
std::string value = parts[4];
|
||||
std::vector<std::string> textures;
|
||||
|
||||
if (parts.size() == 6)
|
||||
textures = split(parts[5], ',');
|
||||
|
||||
MY_CHECKPOS("scrollbar",0);
|
||||
MY_CHECKGEOM("scrollbar",1);
|
||||
@ -703,6 +707,15 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, const std::string &elemen
|
||||
|
||||
e->setPageSize(scrollbar_size * (max - min + 1) / data->scrollbar_options.thumb_size);
|
||||
|
||||
std::vector<video::ITexture *> itextures;
|
||||
|
||||
if (!textures.empty()) {
|
||||
for (u32 i = 0; i < textures.size(); ++i)
|
||||
itextures.push_back(m_tsrc->getTexture(textures[i]));
|
||||
|
||||
e->setTextures(itextures);
|
||||
}
|
||||
|
||||
m_scrollbars.emplace_back(spec,e);
|
||||
m_fields.push_back(spec);
|
||||
return;
|
||||
|
@ -12,7 +12,7 @@ the arrow buttons where there is insufficient space.
|
||||
|
||||
#include "guiScrollBar.h"
|
||||
#include <IGUIButton.h>
|
||||
#include <IGUISkin.h>
|
||||
#include <IGUIImage.h>
|
||||
|
||||
GUIScrollBar::GUIScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id,
|
||||
core::rect<s32> rectangle, bool horizontal, bool auto_scale) :
|
||||
@ -208,10 +208,25 @@ void GUIScrollBar::draw()
|
||||
refreshControls();
|
||||
|
||||
slider_rect = AbsoluteRect;
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), slider_rect,
|
||||
&AbsoluteClippingRect);
|
||||
|
||||
if (core::isnotzero(range())) {
|
||||
if (m_textures.size() >= 1) {
|
||||
s32 w = RelativeRect.getWidth();
|
||||
s32 h = RelativeRect.getHeight();
|
||||
core::rect<s32> rect{0, w, w, h - w};
|
||||
|
||||
if (is_horizontal)
|
||||
rect = {w, 0, h, w - h};
|
||||
|
||||
gui::IGUIImage *e = Environment->addImage(rect, this);
|
||||
e->setImage(m_textures[0]);
|
||||
e->setScaleImage(true);
|
||||
} else {
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR),
|
||||
slider_rect, &AbsoluteClippingRect);
|
||||
}
|
||||
|
||||
// Always show scrollbar thumb
|
||||
//if (core::isnotzero(range())) {
|
||||
if (is_horizontal) {
|
||||
slider_rect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X +
|
||||
draw_center - thumb_size / 2;
|
||||
@ -223,8 +238,23 @@ void GUIScrollBar::draw()
|
||||
slider_rect.LowerRightCorner.Y =
|
||||
slider_rect.UpperLeftCorner.Y + thumb_size;
|
||||
}
|
||||
skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect);
|
||||
}
|
||||
|
||||
if (m_textures.size() >= 2) {
|
||||
s32 w = slider_rect.getWidth();
|
||||
s32 h = slider_rect.getHeight();
|
||||
core::rect<s32> rect{0, draw_center - (h / 2), w, draw_center + h - (h / 2)};
|
||||
|
||||
if (is_horizontal)
|
||||
rect = {draw_center - (w / 2), 0, h, draw_center + w - (w / 2)};
|
||||
|
||||
gui::IGUIImage *e = Environment->addImage(core::rect<s32>(rect), this);
|
||||
e->setImage(m_textures[1]);
|
||||
e->setScaleImage(true);
|
||||
} else {
|
||||
skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect);
|
||||
}
|
||||
//}
|
||||
|
||||
IGUIElement::draw();
|
||||
}
|
||||
|
||||
@ -327,6 +357,12 @@ s32 GUIScrollBar::getPos() const
|
||||
return scroll_pos;
|
||||
}
|
||||
|
||||
void GUIScrollBar::setTextures(const std::vector<video::ITexture *> &textures)
|
||||
{
|
||||
m_textures = textures;
|
||||
refreshControls();
|
||||
};
|
||||
|
||||
void GUIScrollBar::refreshControls()
|
||||
{
|
||||
IGUISkin *skin = Environment->getSkin();
|
||||
@ -384,42 +420,55 @@ void GUIScrollBar::refreshControls()
|
||||
EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
} else {
|
||||
s32 w = RelativeRect.getWidth();
|
||||
border_size = RelativeRect.getHeight() < w * 4 ? 0 : w;
|
||||
s32 h = RelativeRect.getHeight();
|
||||
border_size = h < w * 4 ? 0 : w;
|
||||
|
||||
up_button = Environment->addButton(core::rect<s32>(0, 0, w, w), this);
|
||||
|
||||
if (m_textures.size() >= 3) {
|
||||
up_button->setImage(m_textures[2]);
|
||||
up_button->setScaleImage(true);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
if (sprites && m_textures.size() < 3) {
|
||||
up_button->setSpriteBank(sprites);
|
||||
up_button->setSprite(EGBS_BUTTON_UP,
|
||||
s32(skin->getIcon(EGDI_CURSOR_UP)),
|
||||
current_icon_color);
|
||||
s32(skin->getIcon(EGDI_CURSOR_UP)), current_icon_color);
|
||||
up_button->setSprite(EGBS_BUTTON_DOWN,
|
||||
s32(skin->getIcon(EGDI_CURSOR_UP)),
|
||||
current_icon_color);
|
||||
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);
|
||||
|
||||
down_button = Environment->addButton(core::rect<s32>(0, 0, w, w), this);
|
||||
|
||||
if (m_textures.size() >= 4) {
|
||||
down_button->setImage(m_textures[3]);
|
||||
down_button->setScaleImage(true);
|
||||
}
|
||||
if (sprites) {
|
||||
|
||||
if (!down_button) {
|
||||
if (!down_button) {
|
||||
down_button->setSubElement(true);
|
||||
down_button->setTabStop(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (sprites && m_textures.size() < 4) {
|
||||
down_button->setSpriteBank(sprites);
|
||||
down_button->setSprite(EGBS_BUTTON_UP,
|
||||
s32(skin->getIcon(EGDI_CURSOR_DOWN)),
|
||||
current_icon_color);
|
||||
s32(skin->getIcon(EGDI_CURSOR_DOWN)), current_icon_color);
|
||||
down_button->setSprite(EGBS_BUTTON_DOWN,
|
||||
s32(skin->getIcon(EGDI_CURSOR_DOWN)),
|
||||
current_icon_color);
|
||||
s32(skin->getIcon(EGDI_CURSOR_DOWN)), current_icon_color);
|
||||
}
|
||||
|
||||
down_button->setRelativePosition(
|
||||
core::rect<s32>(0, RelativeRect.getHeight() - w, w,
|
||||
RelativeRect.getHeight()));
|
||||
|
@ -13,6 +13,7 @@ the arrow buttons where there is insufficient space.
|
||||
#pragma once
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include <vector>
|
||||
|
||||
using namespace irr;
|
||||
using namespace gui;
|
||||
@ -47,6 +48,7 @@ public:
|
||||
void setPos(const s32 &pos);
|
||||
void setPageSize(const s32 &size);
|
||||
void setArrowsVisible(ArrowVisibility visible);
|
||||
void setTextures(const std::vector<video::ITexture *> &textures);
|
||||
|
||||
private:
|
||||
void refreshControls();
|
||||
@ -73,6 +75,8 @@ private:
|
||||
s32 page_size;
|
||||
s32 border_size;
|
||||
|
||||
std::vector<video::ITexture *> m_textures;
|
||||
|
||||
core::rect<s32> slider_rect;
|
||||
video::SColor current_icon_color;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user