mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Make button sprites (scrollbar arrows) DPI-aware (#14772)
This commit is contained in:
		@@ -200,7 +200,7 @@ public:
 | 
			
		||||
	\param loop: True if the animation should loop, false if not
 | 
			
		||||
	\param scale: True if the sprite should scale to button size, false if not	*/
 | 
			
		||||
	virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
 | 
			
		||||
			video::SColor color = video::SColor(255, 255, 255, 255), bool loop = false, bool scale = false) = 0;
 | 
			
		||||
			video::SColor color = video::SColor(255, 255, 255, 255), bool loop = false) = 0;
 | 
			
		||||
 | 
			
		||||
	//! Get the sprite-index for the given state or -1 when no sprite is set
 | 
			
		||||
	virtual s32 getSpriteIndex(EGUI_BUTTON_STATE state) const = 0;
 | 
			
		||||
@@ -211,9 +211,6 @@ public:
 | 
			
		||||
	//! Returns if the sprite in the given state does loop
 | 
			
		||||
	virtual bool getSpriteLoop(EGUI_BUTTON_STATE state) const = 0;
 | 
			
		||||
 | 
			
		||||
	//! Returns if the sprite in the given state is scaled
 | 
			
		||||
	virtual bool getSpriteScale(EGUI_BUTTON_STATE state) const = 0;
 | 
			
		||||
 | 
			
		||||
	//! Sets if the button should behave like a push button.
 | 
			
		||||
	/** Which means it can be in two states: Normal or Pressed. With a click on the button,
 | 
			
		||||
	the user can change the state of the button. */
 | 
			
		||||
 
 | 
			
		||||
@@ -374,6 +374,12 @@ const c8 *const GUISkinFontNames[EGDF_COUNT + 1] = {
 | 
			
		||||
class IGUISkin : virtual public IReferenceCounted
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//! returns display density scaling factor
 | 
			
		||||
	virtual float getScale() const = 0;
 | 
			
		||||
 | 
			
		||||
	//! sets display density scaling factor
 | 
			
		||||
	virtual void setScale(float scale) = 0;
 | 
			
		||||
 | 
			
		||||
	//! returns default color
 | 
			
		||||
	virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const = 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -75,12 +75,11 @@ void CGUIButton::setSpriteBank(IGUISpriteBank *sprites)
 | 
			
		||||
	SpriteBank = sprites;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CGUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop, bool scale)
 | 
			
		||||
void CGUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop)
 | 
			
		||||
{
 | 
			
		||||
	ButtonSprites[(u32)state].Index = index;
 | 
			
		||||
	ButtonSprites[(u32)state].Color = color;
 | 
			
		||||
	ButtonSprites[(u32)state].Loop = loop;
 | 
			
		||||
	ButtonSprites[(u32)state].Scale = scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Get the sprite-index for the given state or -1 when no sprite is set
 | 
			
		||||
@@ -101,12 +100,6 @@ bool CGUIButton::getSpriteLoop(EGUI_BUTTON_STATE state) const
 | 
			
		||||
	return ButtonSprites[(u32)state].Loop;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Returns if the sprite in the given state is scaled
 | 
			
		||||
bool CGUIButton::getSpriteScale(EGUI_BUTTON_STATE state) const
 | 
			
		||||
{
 | 
			
		||||
	return ButtonSprites[(u32)state].Scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! called if an event happened.
 | 
			
		||||
bool CGUIButton::OnEvent(const SEvent &event)
 | 
			
		||||
{
 | 
			
		||||
@@ -294,19 +287,26 @@ void CGUIButton::draw()
 | 
			
		||||
void CGUIButton::drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di ¢er)
 | 
			
		||||
{
 | 
			
		||||
	u32 stateIdx = (u32)state;
 | 
			
		||||
	s32 spriteIdx = ButtonSprites[stateIdx].Index;
 | 
			
		||||
	if (spriteIdx == -1)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (ButtonSprites[stateIdx].Index != -1) {
 | 
			
		||||
		if (ButtonSprites[stateIdx].Scale) {
 | 
			
		||||
			const video::SColor colors[] = {ButtonSprites[stateIdx].Color, ButtonSprites[stateIdx].Color, ButtonSprites[stateIdx].Color, ButtonSprites[stateIdx].Color};
 | 
			
		||||
			SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, AbsoluteRect,
 | 
			
		||||
					&AbsoluteClippingRect, colors,
 | 
			
		||||
					os::Timer::getTime() - startTime, ButtonSprites[stateIdx].Loop);
 | 
			
		||||
		} else {
 | 
			
		||||
			SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, center,
 | 
			
		||||
					&AbsoluteClippingRect, ButtonSprites[stateIdx].Color, startTime, os::Timer::getTime(),
 | 
			
		||||
					ButtonSprites[stateIdx].Loop, true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	u32 rectIdx = SpriteBank->getSprites()[spriteIdx].Frames[0].rectNumber;
 | 
			
		||||
	core::rect<s32> srcRect = SpriteBank->getPositions()[rectIdx];
 | 
			
		||||
 | 
			
		||||
	IGUISkin *skin = Environment->getSkin();
 | 
			
		||||
	s32 scale = std::max(std::floor(skin->getScale()), 1.0f);
 | 
			
		||||
	core::rect<s32> rect(center, srcRect.getSize() * scale);
 | 
			
		||||
	rect -= rect.getSize() / 2;
 | 
			
		||||
 | 
			
		||||
	const video::SColor colors[] = {
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
	};
 | 
			
		||||
	SpriteBank->draw2DSprite(spriteIdx, rect, &AbsoluteClippingRect, colors,
 | 
			
		||||
			os::Timer::getTime() - startTime, ButtonSprites[stateIdx].Loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EGUI_BUTTON_IMAGE_STATE CGUIButton::getImageState(bool pressed) const
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,7 @@ public:
 | 
			
		||||
	*/
 | 
			
		||||
	virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
 | 
			
		||||
			video::SColor color = video::SColor(255, 255, 255, 255),
 | 
			
		||||
			bool loop = false, bool scale = false) override;
 | 
			
		||||
			bool loop = false) override;
 | 
			
		||||
 | 
			
		||||
	//! Get the sprite-index for the given state or -1 when no sprite is set
 | 
			
		||||
	s32 getSpriteIndex(EGUI_BUTTON_STATE state) const override;
 | 
			
		||||
@@ -103,9 +103,6 @@ public:
 | 
			
		||||
	//! Returns if the sprite in the given state does loop
 | 
			
		||||
	bool getSpriteLoop(EGUI_BUTTON_STATE state) const override;
 | 
			
		||||
 | 
			
		||||
	//! Returns if the sprite in the given state is scaled
 | 
			
		||||
	bool getSpriteScale(EGUI_BUTTON_STATE state) const override;
 | 
			
		||||
 | 
			
		||||
	//! Sets if the button should behave like a push button. Which means it
 | 
			
		||||
	//! can be in two states: Normal or Pressed. With a click on the button,
 | 
			
		||||
	//! the user can change the state of the button.
 | 
			
		||||
@@ -158,19 +155,18 @@ private:
 | 
			
		||||
	struct ButtonSprite
 | 
			
		||||
	{
 | 
			
		||||
		ButtonSprite() :
 | 
			
		||||
				Index(-1), Loop(false), Scale(false)
 | 
			
		||||
				Index(-1), Loop(false)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator==(const ButtonSprite &other) const
 | 
			
		||||
		{
 | 
			
		||||
			return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
 | 
			
		||||
			return Index == other.Index && Color == other.Color && Loop == other.Loop;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s32 Index;
 | 
			
		||||
		video::SColor Color;
 | 
			
		||||
		bool Loop;
 | 
			
		||||
		bool Scale;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ButtonSprite ButtonSprites[EGBS_COUNT];
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,12 @@ public:
 | 
			
		||||
	//! destructor
 | 
			
		||||
	virtual ~CGUISkin();
 | 
			
		||||
 | 
			
		||||
	//! returns display density scaling factor
 | 
			
		||||
	virtual float getScale() const override { return Scale; }
 | 
			
		||||
 | 
			
		||||
	//! sets display density scaling factor
 | 
			
		||||
	virtual void setScale(float scale) override { Scale = scale; }
 | 
			
		||||
 | 
			
		||||
	//! returns default color
 | 
			
		||||
	video::SColor getColor(EGUI_DEFAULT_COLOR color) const override;
 | 
			
		||||
 | 
			
		||||
@@ -210,6 +216,7 @@ public:
 | 
			
		||||
	EGUI_SKIN_TYPE getType() const override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	float Scale = 1.0f;
 | 
			
		||||
	video::SColor Colors[EGDC_COUNT];
 | 
			
		||||
	s32 Sizes[EGDS_COUNT];
 | 
			
		||||
	u32 Icons[EGDI_COUNT];
 | 
			
		||||
 
 | 
			
		||||
@@ -352,6 +352,7 @@ void ClientLauncher::config_guienv()
 | 
			
		||||
 | 
			
		||||
	float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5f, 20) *
 | 
			
		||||
		RenderingEngine::getDisplayDensity();
 | 
			
		||||
	skin->setScale(density);
 | 
			
		||||
	skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
 | 
			
		||||
	skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(21.0f * density));
 | 
			
		||||
	skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
 | 
			
		||||
 
 | 
			
		||||
@@ -89,12 +89,11 @@ void GUIButton::setSpriteBank(IGUISpriteBank* sprites)
 | 
			
		||||
	SpriteBank = sprites;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop, bool scale)
 | 
			
		||||
void GUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop)
 | 
			
		||||
{
 | 
			
		||||
	ButtonSprites[(u32)state].Index	= index;
 | 
			
		||||
	ButtonSprites[(u32)state].Color	= color;
 | 
			
		||||
	ButtonSprites[(u32)state].Loop	= loop;
 | 
			
		||||
	ButtonSprites[(u32)state].Scale = scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Get the sprite-index for the given state or -1 when no sprite is set
 | 
			
		||||
@@ -115,12 +114,6 @@ bool GUIButton::getSpriteLoop(EGUI_BUTTON_STATE state) const
 | 
			
		||||
	return ButtonSprites[(u32)state].Loop;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Returns if the sprite in the given state is scaled
 | 
			
		||||
bool GUIButton::getSpriteScale(EGUI_BUTTON_STATE state) const
 | 
			
		||||
{
 | 
			
		||||
	return ButtonSprites[(u32)state].Scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! called if an event happened.
 | 
			
		||||
bool GUIButton::OnEvent(const SEvent& event)
 | 
			
		||||
{
 | 
			
		||||
@@ -354,23 +347,26 @@ void GUIButton::draw()
 | 
			
		||||
void GUIButton::drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center)
 | 
			
		||||
{
 | 
			
		||||
	u32 stateIdx = (u32)state;
 | 
			
		||||
	s32 spriteIdx = ButtonSprites[stateIdx].Index;
 | 
			
		||||
	if (spriteIdx == -1)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (ButtonSprites[stateIdx].Index != -1)
 | 
			
		||||
	{
 | 
			
		||||
		if ( ButtonSprites[stateIdx].Scale )
 | 
			
		||||
		{
 | 
			
		||||
			const video::SColor colors[] = {ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color};
 | 
			
		||||
			SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, AbsoluteRect.UpperLeftCorner,
 | 
			
		||||
					&AbsoluteClippingRect, colors[0], // FIXME: remove [0]
 | 
			
		||||
					porting::getTimeMs()-startTime, ButtonSprites[stateIdx].Loop);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, center,
 | 
			
		||||
				&AbsoluteClippingRect, ButtonSprites[stateIdx].Color, startTime, porting::getTimeMs(),
 | 
			
		||||
				ButtonSprites[stateIdx].Loop, true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	u32 rectIdx = SpriteBank->getSprites()[spriteIdx].Frames[0].rectNumber;
 | 
			
		||||
	core::rect<s32> srcRect = SpriteBank->getPositions()[rectIdx];
 | 
			
		||||
 | 
			
		||||
	IGUISkin *skin = Environment->getSkin();
 | 
			
		||||
	s32 scale = std::max(std::floor(skin->getScale()), 1.0f);
 | 
			
		||||
	core::rect<s32> rect(center, srcRect.getSize() * scale);
 | 
			
		||||
	rect -= rect.getSize() / 2;
 | 
			
		||||
 | 
			
		||||
	const video::SColor colors[] = {
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
		ButtonSprites[stateIdx].Color,
 | 
			
		||||
	};
 | 
			
		||||
	SpriteBank->draw2DSprite(spriteIdx, rect, &AbsoluteClippingRect, colors,
 | 
			
		||||
			porting::getTimeMs() - startTime, ButtonSprites[stateIdx].Loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,7 @@ public:
 | 
			
		||||
	*/
 | 
			
		||||
	virtual void setSprite(gui::EGUI_BUTTON_STATE state, s32 index,
 | 
			
		||||
						   video::SColor color=video::SColor(255,255,255,255),
 | 
			
		||||
						   bool loop=false, bool scale=false) override;
 | 
			
		||||
						   bool loop=false) override;
 | 
			
		||||
 | 
			
		||||
	//! Get the sprite-index for the given state or -1 when no sprite is set
 | 
			
		||||
	virtual s32 getSpriteIndex(gui::EGUI_BUTTON_STATE state) const override;
 | 
			
		||||
@@ -103,9 +103,6 @@ public:
 | 
			
		||||
	//! Returns if the sprite in the given state does loop
 | 
			
		||||
	virtual bool getSpriteLoop(gui::EGUI_BUTTON_STATE state) const override;
 | 
			
		||||
 | 
			
		||||
	//! Returns if the sprite in the given state is scaled
 | 
			
		||||
	virtual bool getSpriteScale(gui::EGUI_BUTTON_STATE state) const override;
 | 
			
		||||
 | 
			
		||||
	//! Sets if the button should behave like a push button. Which means it
 | 
			
		||||
	//! can be in two states: Normal or Pressed. With a click on the button,
 | 
			
		||||
	//! the user can change the state of the button.
 | 
			
		||||
@@ -230,13 +227,12 @@ private:
 | 
			
		||||
	{
 | 
			
		||||
		bool operator==(const ButtonSprite &other) const
 | 
			
		||||
		{
 | 
			
		||||
			return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
 | 
			
		||||
			return Index == other.Index && Color == other.Color && Loop == other.Loop;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s32 Index = -1;
 | 
			
		||||
		video::SColor Color;
 | 
			
		||||
		bool Loop = false;
 | 
			
		||||
		bool Scale = false;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ButtonSprite ButtonSprites[gui::EGBS_COUNT];
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,12 @@ namespace gui
 | 
			
		||||
		//! destructor
 | 
			
		||||
		virtual ~GUISkin();
 | 
			
		||||
 | 
			
		||||
		//! returns display density scaling factor
 | 
			
		||||
		virtual float getScale() const { return Scale; }
 | 
			
		||||
 | 
			
		||||
		//! sets display density scaling factor
 | 
			
		||||
		virtual void setScale(float scale) { Scale = scale; }
 | 
			
		||||
 | 
			
		||||
		//! returns default color
 | 
			
		||||
		virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const;
 | 
			
		||||
 | 
			
		||||
@@ -292,6 +298,7 @@ namespace gui
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		float Scale = 1.0f;
 | 
			
		||||
		video::SColor Colors[EGDC_COUNT];
 | 
			
		||||
		s32 Sizes[EGDS_COUNT];
 | 
			
		||||
		u32 Icons[EGDI_COUNT];
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user