Allow table and textarea scrollbars to be customised (#129)
This commit is contained in:
parent
28f62eccab
commit
eded502651
@ -2923,6 +2923,17 @@ Some types may inherit styles from parent types.
|
|||||||
* sound - a sound to be played when triggered.
|
* sound - a sound to be played when triggered.
|
||||||
* scrollbar
|
* scrollbar
|
||||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||||
|
* scrollbar, table, textarea
|
||||||
|
* scrollbar_bgimg - The background image of the scrollbar
|
||||||
|
* scrollbar_thumb_img - The thumb/slider image of the scrollbar.
|
||||||
|
If scrollbar_thumb_top_img and scrollbar_thumb_bottom_img are specified,
|
||||||
|
this should be middle texture.
|
||||||
|
* scrollbar_thumb_top_img - The top half of the thumb image
|
||||||
|
* scrollbar_thumb_bottom_img - The bottom half of the thumb image
|
||||||
|
* scrollbar_up_img - The up arrow image to use for the scrollbar
|
||||||
|
* scrollbar_down_img - The down arrow image to use for the scrollbar
|
||||||
|
* scrollbar_middle - The middle for all 9-sliced scrollbar textures
|
||||||
|
* NOTE: Scrollbar textures will only be applied if all scrollbar image properties are specified.
|
||||||
* tabheader
|
* tabheader
|
||||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||||
* sound - a sound to be played when a different tab is selected.
|
* sound - a sound to be played when a different tab is selected.
|
||||||
|
@ -59,6 +59,12 @@ public:
|
|||||||
SOUND,
|
SOUND,
|
||||||
SPACING,
|
SPACING,
|
||||||
SIZE,
|
SIZE,
|
||||||
|
SCROLLBAR_BGIMG,
|
||||||
|
SCROLLBAR_THUMB_IMG,
|
||||||
|
SCROLLBAR_UP_IMG,
|
||||||
|
SCROLLBAR_DOWN_IMG,
|
||||||
|
SCROLLBAR_THUMB_TOP_IMG,
|
||||||
|
SCROLLBAR_THUMB_BOTTOM_IMG,
|
||||||
NUM_PROPERTIES,
|
NUM_PROPERTIES,
|
||||||
NONE
|
NONE
|
||||||
};
|
};
|
||||||
@ -155,6 +161,18 @@ public:
|
|||||||
return SPACING;
|
return SPACING;
|
||||||
} else if (name == "size") {
|
} else if (name == "size") {
|
||||||
return SIZE;
|
return SIZE;
|
||||||
|
} else if (name == "scrollbar_bgimg") {
|
||||||
|
return SCROLLBAR_BGIMG;
|
||||||
|
} else if (name == "scrollbar_thumb_img") {
|
||||||
|
return SCROLLBAR_THUMB_IMG;
|
||||||
|
} else if (name == "scrollbar_up_img") {
|
||||||
|
return SCROLLBAR_UP_IMG;
|
||||||
|
} else if (name == "scrollbar_down_img") {
|
||||||
|
return SCROLLBAR_DOWN_IMG;
|
||||||
|
} else if (name == "scrollbar_thumb_top_img") {
|
||||||
|
return SCROLLBAR_THUMB_TOP_IMG;
|
||||||
|
} else if (name == "scrollbar_thumb_bottom_img") {
|
||||||
|
return SCROLLBAR_THUMB_BOTTOM_IMG;
|
||||||
} else {
|
} else {
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,13 @@ public:
|
|||||||
virtual void deserializeAttributes(
|
virtual void deserializeAttributes(
|
||||||
io::IAttributes *in, io::SAttributeReadWriteOptions *options);
|
io::IAttributes *in, io::SAttributeReadWriteOptions *options);
|
||||||
|
|
||||||
|
//! Sets the scrollbar texture
|
||||||
|
void setScrollbarStyle(const StyleSpec &style, ISimpleTextureSource *tsrc)
|
||||||
|
{
|
||||||
|
if (m_vscrollbar != nullptr)
|
||||||
|
m_vscrollbar->setStyle(style, tsrc);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void breakText() = 0;
|
virtual void breakText() = 0;
|
||||||
|
|
||||||
|
@ -739,7 +739,10 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, const std::string &elemen
|
|||||||
|
|
||||||
std::vector<video::ITexture *> itextures;
|
std::vector<video::ITexture *> itextures;
|
||||||
|
|
||||||
if (!textures.empty()) {
|
if (textures.empty()) {
|
||||||
|
// Fall back to the scrollbar textures specified in style[]
|
||||||
|
e->setStyle(style, m_tsrc);
|
||||||
|
} else {
|
||||||
for (u32 i = 0; i < textures.size(); ++i)
|
for (u32 i = 0; i < textures.size(); ++i)
|
||||||
itextures.push_back(m_tsrc->getTexture(textures[i]));
|
itextures.push_back(m_tsrc->getTexture(textures[i]));
|
||||||
|
|
||||||
@ -1304,8 +1307,7 @@ void GUIFormSpecMenu::parseTable(parserData* data, const std::string &element)
|
|||||||
e->setSelected(stoi(str_initial_selection));
|
e->setSelected(stoi(str_initial_selection));
|
||||||
|
|
||||||
auto style = getDefaultStyleForElement("table", name);
|
auto style = getDefaultStyleForElement("table", name);
|
||||||
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
|
e->setStyle(style);
|
||||||
e->setOverrideFont(style.getFont());
|
|
||||||
|
|
||||||
m_tables.emplace_back(spec, e);
|
m_tables.emplace_back(spec, e);
|
||||||
m_fields.push_back(spec);
|
m_fields.push_back(spec);
|
||||||
@ -1382,8 +1384,7 @@ void GUIFormSpecMenu::parseTextList(parserData* data, const std::string &element
|
|||||||
e->setSelected(stoi(str_initial_selection));
|
e->setSelected(stoi(str_initial_selection));
|
||||||
|
|
||||||
auto style = getDefaultStyleForElement("textlist", name);
|
auto style = getDefaultStyleForElement("textlist", name);
|
||||||
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
|
e->setStyle(style);
|
||||||
e->setOverrideFont(style.getFont());
|
|
||||||
|
|
||||||
m_tables.emplace_back(spec, e);
|
m_tables.emplace_back(spec, e);
|
||||||
m_fields.push_back(spec);
|
m_fields.push_back(spec);
|
||||||
@ -1605,15 +1606,18 @@ void GUIFormSpecMenu::createTextField(parserData *data, FieldSpec &spec,
|
|||||||
spec.flabel.swap(spec.fdefault);
|
spec.flabel.swap(spec.fdefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUIEditBox *box = nullptr;
|
||||||
gui::IGUIEditBox *e = nullptr;
|
gui::IGUIEditBox *e = nullptr;
|
||||||
|
|
||||||
#if USE_FREETYPE && IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9
|
#if USE_FREETYPE && IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9
|
||||||
e = new gui::intlGUIEditBox(spec.fdefault.c_str(), true, Environment,
|
box = new gui::intlGUIEditBox(spec.fdefault.c_str(), true, Environment,
|
||||||
data->current_parent, spec.fid, rect, is_editable, is_multiline);
|
data->current_parent, spec.fid, rect, is_editable, is_multiline);
|
||||||
|
e = box;
|
||||||
#else
|
#else
|
||||||
if (is_multiline) {
|
if (is_multiline) {
|
||||||
e = new GUIEditBoxWithScrollBar(spec.fdefault.c_str(), true, Environment,
|
box = new GUIEditBoxWithScrollBar(spec.fdefault.c_str(), true, Environment,
|
||||||
data->current_parent, spec.fid, rect, is_editable, !is_editable);
|
data->current_parent, spec.fid, rect, is_editable, !is_editable);
|
||||||
|
e = box;
|
||||||
} else if (is_editable) {
|
} else if (is_editable) {
|
||||||
e = Environment->addEditBox(spec.fdefault.c_str(), rect, true,
|
e = Environment->addEditBox(spec.fdefault.c_str(), rect, true,
|
||||||
data->current_parent, spec.fid);
|
data->current_parent, spec.fid);
|
||||||
@ -1649,6 +1653,8 @@ void GUIFormSpecMenu::createTextField(parserData *data, FieldSpec &spec,
|
|||||||
e->setDrawBackground(false);
|
e->setDrawBackground(false);
|
||||||
}
|
}
|
||||||
e->setOverrideFont(style.getFont());
|
e->setOverrideFont(style.getFont());
|
||||||
|
if (box != nullptr)
|
||||||
|
box->setScrollbarStyle(style, m_tsrc);
|
||||||
|
|
||||||
e->drop();
|
e->drop();
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ GUIScrollBar::GUIScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s3
|
|||||||
core::rect<s32> rectangle, bool horizontal, bool auto_scale) :
|
core::rect<s32> rectangle, bool horizontal, bool auto_scale) :
|
||||||
IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle),
|
IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle),
|
||||||
up_button(nullptr), down_button(nullptr), bg_image(nullptr),
|
up_button(nullptr), down_button(nullptr), bg_image(nullptr),
|
||||||
slider_image(nullptr), is_dragging(false), is_horizontal(horizontal),
|
slider_image(nullptr), slider_top_image(nullptr),
|
||||||
|
slider_bottom_image(nullptr), is_dragging(false), is_horizontal(horizontal),
|
||||||
is_auto_scaling(auto_scale), dragged_by_slider(false),
|
is_auto_scaling(auto_scale), dragged_by_slider(false),
|
||||||
tray_clicked(false), scroll_pos(0), draw_center(0), thumb_size(0),
|
tray_clicked(false), scroll_pos(0), draw_center(0), thumb_size(0),
|
||||||
min_pos(0), max_pos(100), small_step(10), large_step(50),
|
min_pos(0), max_pos(100), small_step(10), large_step(50),
|
||||||
@ -194,6 +195,14 @@ bool GUIScrollBar::OnEvent(const SEvent &event)
|
|||||||
return IGUIElement::OnEvent(event);
|
return IGUIElement::OnEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gui::IGUIImage* GUIScrollBar::addImage(const core::rect<s32> &rect, video::ITexture *texture)
|
||||||
|
{
|
||||||
|
gui::IGUIImage *e = Environment->addImage(rect, this);
|
||||||
|
e->setImage(texture);
|
||||||
|
e->setScaleImage(true);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
void GUIScrollBar::draw()
|
void GUIScrollBar::draw()
|
||||||
{
|
{
|
||||||
if (!IsVisible)
|
if (!IsVisible)
|
||||||
@ -218,13 +227,10 @@ void GUIScrollBar::draw()
|
|||||||
if (is_horizontal)
|
if (is_horizontal)
|
||||||
rect = {h, 0, w - h, h};
|
rect = {h, 0, w - h, h};
|
||||||
|
|
||||||
if (!bg_image) {
|
if (!bg_image)
|
||||||
bg_image = Environment->addImage(rect, this);
|
bg_image = addImage(rect, m_textures[0]);
|
||||||
bg_image->setImage(m_textures[0]);
|
else
|
||||||
bg_image->setScaleImage(true);
|
|
||||||
} else {
|
|
||||||
bg_image->setRelativePosition(rect);
|
bg_image->setRelativePosition(rect);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR),
|
skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR),
|
||||||
slider_rect, &AbsoluteClippingRect);
|
slider_rect, &AbsoluteClippingRect);
|
||||||
@ -252,12 +258,27 @@ void GUIScrollBar::draw()
|
|||||||
if (is_horizontal)
|
if (is_horizontal)
|
||||||
rect = {draw_center - (w / 2), 0, draw_center + w - (w / 2), h};
|
rect = {draw_center - (w / 2), 0, draw_center + w - (w / 2), h};
|
||||||
|
|
||||||
if (!slider_image) {
|
if (!slider_image)
|
||||||
slider_image = Environment->addImage(core::rect<s32>(rect), this);
|
slider_image = addImage(rect, m_textures[1]);
|
||||||
slider_image->setImage(m_textures[1]);
|
else
|
||||||
slider_image->setScaleImage(true);
|
|
||||||
} else {
|
|
||||||
slider_image->setRelativePosition(rect);
|
slider_image->setRelativePosition(rect);
|
||||||
|
|
||||||
|
// Add top and bottom images if required
|
||||||
|
// TODO: Horizontal scrollbars
|
||||||
|
if (m_textures.size() >= 6 && !is_horizontal) {
|
||||||
|
core::rect<s32> top_rect = rect;
|
||||||
|
top_rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + w / 2;
|
||||||
|
if (!slider_top_image)
|
||||||
|
slider_top_image = addImage(top_rect, m_textures[4]);
|
||||||
|
else
|
||||||
|
slider_top_image->setRelativePosition(top_rect);
|
||||||
|
|
||||||
|
core::rect<s32> bottom_rect = rect;
|
||||||
|
bottom_rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y - w / 2;
|
||||||
|
if (!slider_bottom_image)
|
||||||
|
slider_bottom_image = addImage(bottom_rect, m_textures[5]);
|
||||||
|
else
|
||||||
|
slider_bottom_image->setRelativePosition(bottom_rect);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect);
|
skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect);
|
||||||
@ -372,6 +393,28 @@ void GUIScrollBar::setTextures(const std::vector<video::ITexture *> &textures)
|
|||||||
refreshControls();
|
refreshControls();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void GUIScrollBar::setStyle(const StyleSpec &style, ISimpleTextureSource *tsrc)
|
||||||
|
{
|
||||||
|
if (style.isNotDefault(StyleSpec::SCROLLBAR_BGIMG) &&
|
||||||
|
style.isNotDefault(StyleSpec::SCROLLBAR_THUMB_IMG) &&
|
||||||
|
style.isNotDefault(StyleSpec::SCROLLBAR_UP_IMG) &&
|
||||||
|
style.isNotDefault(StyleSpec::SCROLLBAR_DOWN_IMG)) {
|
||||||
|
arrow_visibility = ArrowVisibility::SHOW;
|
||||||
|
std::vector<video::ITexture *> textures = {
|
||||||
|
style.getTexture(StyleSpec::SCROLLBAR_BGIMG, tsrc),
|
||||||
|
style.getTexture(StyleSpec::SCROLLBAR_THUMB_IMG, tsrc),
|
||||||
|
style.getTexture(StyleSpec::SCROLLBAR_UP_IMG, tsrc),
|
||||||
|
style.getTexture(StyleSpec::SCROLLBAR_DOWN_IMG, tsrc)
|
||||||
|
};
|
||||||
|
if (style.isNotDefault(StyleSpec::SCROLLBAR_THUMB_TOP_IMG) &&
|
||||||
|
style.isNotDefault(StyleSpec::SCROLLBAR_THUMB_BOTTOM_IMG)) {
|
||||||
|
textures.push_back(style.getTexture(StyleSpec::SCROLLBAR_THUMB_TOP_IMG, tsrc));
|
||||||
|
textures.push_back(style.getTexture(StyleSpec::SCROLLBAR_THUMB_BOTTOM_IMG, tsrc));
|
||||||
|
}
|
||||||
|
setTextures(textures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GUIScrollBar::refreshControls()
|
void GUIScrollBar::refreshControls()
|
||||||
{
|
{
|
||||||
IGUISkin *skin = Environment->getSkin();
|
IGUISkin *skin = Environment->getSkin();
|
||||||
|
@ -12,7 +12,9 @@ the arrow buttons where there is insufficient space.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "guiAnimatedImage.h"
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
|
#include "StyleSpec.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
@ -50,16 +52,20 @@ public:
|
|||||||
void setPageSize(const s32 &size);
|
void setPageSize(const s32 &size);
|
||||||
void setArrowsVisible(ArrowVisibility visible);
|
void setArrowsVisible(ArrowVisibility visible);
|
||||||
void setTextures(const std::vector<video::ITexture *> &textures);
|
void setTextures(const std::vector<video::ITexture *> &textures);
|
||||||
|
void setStyle(const StyleSpec &style, ISimpleTextureSource *tsrc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshControls();
|
void refreshControls();
|
||||||
s32 getPosFromMousePos(const core::position2di &p) const;
|
s32 getPosFromMousePos(const core::position2di &p) const;
|
||||||
f32 range() const { return f32(max_pos - min_pos); }
|
f32 range() const { return f32(max_pos - min_pos); }
|
||||||
|
gui::IGUIImage *addImage(const core::rect<s32> &rect, video::ITexture *texture);
|
||||||
|
|
||||||
IGUIButton *up_button;
|
IGUIButton *up_button;
|
||||||
IGUIButton *down_button;
|
IGUIButton *down_button;
|
||||||
gui::IGUIImage *bg_image;
|
gui::IGUIImage *bg_image;
|
||||||
gui::IGUIImage *slider_image;
|
gui::IGUIImage *slider_image;
|
||||||
|
gui::IGUIImage *slider_top_image;
|
||||||
|
gui::IGUIImage *slider_bottom_image;
|
||||||
ArrowVisibility arrow_visibility = DEFAULT;
|
ArrowVisibility arrow_visibility = DEFAULT;
|
||||||
bool is_dragging;
|
bool is_dragging;
|
||||||
bool is_horizontal;
|
bool is_horizontal;
|
||||||
@ -78,6 +84,7 @@ private:
|
|||||||
s32 border_size;
|
s32 border_size;
|
||||||
|
|
||||||
std::vector<video::ITexture *> m_textures;
|
std::vector<video::ITexture *> m_textures;
|
||||||
|
core::rect<s32> m_texture_middle;
|
||||||
|
|
||||||
core::rect<s32> slider_rect;
|
core::rect<s32> slider_rect;
|
||||||
video::SColor current_icon_color;
|
video::SColor current_icon_color;
|
||||||
|
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "guiScrollBar.h"
|
#include "guiScrollBar.h"
|
||||||
|
#include "StyleSpec.h"
|
||||||
|
|
||||||
class ISimpleTextureSource;
|
class ISimpleTextureSource;
|
||||||
|
|
||||||
@ -147,6 +148,14 @@ public:
|
|||||||
/* Irrlicht event handler */
|
/* Irrlicht event handler */
|
||||||
virtual bool OnEvent(const SEvent &event);
|
virtual bool OnEvent(const SEvent &event);
|
||||||
|
|
||||||
|
/* Set scrollbar texture */
|
||||||
|
void setStyle(const StyleSpec &style)
|
||||||
|
{
|
||||||
|
setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
|
||||||
|
setOverrideFont(style.getFont());
|
||||||
|
m_scrollbar->setStyle(style, m_tsrc);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum ColumnType {
|
enum ColumnType {
|
||||||
COLUMN_TYPE_TEXT,
|
COLUMN_TYPE_TEXT,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user