plop je savais pas trop quoi faire aujourd'hui du coup comme j'en avais plus ou moin besoin (quand même plus pratique que 4scroll bar et une image)
et vue que celui d'irrlicht est vraiment pourris
du coups j'ai coder le mien, pour une fois je vais partager un code
pas de dépendance, minimalist, propre
Code c++ :
#ifndef __C_GUI_COLOR_PICKER_HEADER__
#define __C_GUI_COLOR_PICKER_HEADER__
#include <irrlicht/IGUIElement.h>
#include <irrlicht/S3DVertex.h>
namespace irr{ namespace gui { class IGUIButton
; class IGUIStaticText
; class IGUIScrollBar
; class CGUIColorPicker
: public IGUIElement
{ public: CGUIColorPicker
(IGUIEnvironment
*environment
, IGUIElement
*parent
, s32 id
= 0) noexcept
; ~CGUIColorPicker
() noexcept
; virtual void setRelativePosition
(const core::recti
&r
); virtual bool OnEvent
(const SEvent&) noexcept
; virtual void updateAbsolutePosition
(); virtual void setPickedColor
(const video::SColor&) noexcept
; virtual const
video::SColor& getPickedColor
() const noexcept
; virtual void setBackgroundColor
(const video::SColor&) noexcept
; virtual const
video::SColor& getBackgroundColor
() const noexcept
; virtual void draw
(); protected: bool isGradient
, isColor
, isInside
; virtual void recalculatePickedColor
() noexcept
; virtual void createAlphaTexture
() noexcept
; virtual void createGradientTexture
() noexcept
; protected: IGUIButton
*close
; IGUIScrollBar
*scroll
; video::ITexture *img
[2]; protected: video::SColor pickcolor
, color
; video::SColor background
, white
, black
, alpha
; core::recti box
, pickbox
, gradient
; core::vector2di pickpos
; int colorpos
; }; }}#endif
Code c++ :
#include "CGUIColorPicker.h"
#include <irrlicht/IGUIEnvironment.h>
#include <irrlicht/IGUIButton.h>
#include <irrlicht/IGUIScrollBar.h>
#include <irrlicht/IVideoDriver.h>
#include <irrlicht/irrMath.h>
#include <irrlicht/SColor.h>
namespace irr{ inline core::vector3df RGBftoHSV
(video::SColorf rgb
) { core::vector3df hsv
; f32 M
= core::max_
(rgb
.getRed
(), rgb
.getGreen
(), rgb
.getBlue
()); f32 m
= core::min_
(rgb
.getRed
(), rgb
.getGreen
(), rgb
.getBlue
()); f32 C
= M
- m
; if(C
== 0) hsv
.X
= 0; else if(M
<= rgb
.getRed
()) hsv
.X
=((rgb
.getGreen
() - rgb
.getBlue
()) / C
); else if(M
<= rgb
.getGreen
()) hsv
.X
=((rgb
.getBlue
() - rgb
.getRed
()) / C
) + 2; else if(M
<= rgb
.getBlue
()) hsv
.X
=((rgb
.getRed
() - rgb
.getGreen
()) / C
) + 4; hsv
.X
*= 60; if(hsv
.X
< 0) hsv
.X
+= 360; hsv
.Y
= M
; if(hsv
.Y
== 0) hsv
.Z
= 0; else hsv
.Z
= C
/ hsv
.Y
; return hsv
; } namespace gui { CGUIColorPicker
::CGUIColorPicker
(IGUIEnvironment
*environment
, IGUIElement
*parent
, s32 id
) noexcept
: IGUIElement
(EGUIET_COLOR_SELECT_DIALOG
, environment
, parent
, id
, {200, 200, 310, 360}), background
{64, 255, 255, 255}, white
{255, 255, 255, 255}, black
{255, 0, 0, 0}, colorpos
(0), isGradient
(false), isColor
(false) { close
= Environment
->addButton
({5, 140, 85, 156}, this, 0, L
"take this color"); scroll
= Environment
->addScrollBar
(true, {5, 125, 85, 135}, this); scroll
->setMin
(0); scroll
->setMax
(255); scroll
->setPos
(255); createAlphaTexture
(); createGradientTexture
(); setPickedColor
({255, 64, 64, 128}); updateAbsolutePosition
(); } CGUIColorPicker
::~CGUIColorPicker
() noexcept
{ close
->drop
(); scroll
->drop
(); img
[0]->drop
(); img
[1]->drop
(); } void CGUIColorPicker
::createAlphaTexture
() noexcept
{ img
[0] = Environment
->getVideoDriver
()->addTexture
({16, 16}, "alpha", video::ECF_A8R8G8B8
); u32
*tmp
= (u32
*) img
[0]->lock
(); video::SColor color
; square
(video::SColor(255, 153, 153, 153), 0, 0, 8, 8); square
(video::SColor(255, 153, 153, 153), 8, 8, 16, 16); square
(video::SColor(255, 102, 102, 102), 8, 0, 16, 8); square
(video::SColor(255, 102, 102, 102), 0, 8, 8, 16); img
[0]->unlock
(); } void CGUIColorPicker
::createGradientTexture
() noexcept
{ img
[1] = Environment
->getVideoDriver
()->addTexture
({15, 151}, "gradient", video::ECF_A8R8G8B8
); u32
*tmp
= (u32
*) img
[1]->lock
(); video::SColor from
; video::SColor to
; } interpolate
(video::SColor(255, 255, 0, 0), video::SColor(255, 255, 0, 255), 0, 25); interpolate
(video::SColor(255, 255, 0, 255), video::SColor(255, 0, 0, 255), 25, 50); interpolate
(video::SColor(255, 0, 0, 255), video::SColor(255, 0, 255, 255), 50, 75); interpolate
(video::SColor(255, 0, 255, 255), video::SColor(255, 0, 255, 0), 75, 100); interpolate
(video::SColor(255, 0, 255, 0), video::SColor(255, 255, 255, 0), 100, 125); interpolate
(video::SColor(255, 255, 255, 0), video::SColor(255, 255, 0, 0), 125, 151); img
[1]->unlock
(); } void CGUIColorPicker
::setRelativePosition
(const core::recti
&r
) { RelativeRect
.UpperLeftCorner
= r
.UpperLeftCorner
; RelativeRect
.LowerRightCorner
.X
= r
.UpperLeftCorner
.X
+ 110; RelativeRect
.LowerRightCorner
.Y
= r
.UpperLeftCorner
.X
+ 160; } bool CGUIColorPicker
::OnEvent
(const SEvent &event
) noexcept
{ if(event
.EventType
== EET_MOUSE_INPUT_EVENT
) { core::vector2di pos
(event
.MouseInput
.X
, event
.MouseInput
.Y
); if(event
.MouseInput
.Event
== EMIE_LMOUSE_PRESSED_DOWN
) { isGradient
= gradient
.isPointInside
(pos
); isColor
= box
.isPointInside
(pos
); isInside
= AbsoluteRect
.isPointInside
(pos
); } if(event
.MouseInput
.Event
== EMIE_LMOUSE_LEFT_UP
) { isGradient
= isColor
= false; } if(isGradient
) { if(pos
.X
< gradient
.UpperLeftCorner
.X
) pos
.X
= gradient
.UpperLeftCorner
.X
; if(pos
.Y
< gradient
.UpperLeftCorner
.Y
) pos
.Y
= gradient
.UpperLeftCorner
.Y
; if(pos
.X
> gradient
.LowerRightCorner
.X
) pos
.X
= gradient
.LowerRightCorner
.X
; if(pos
.Y
> gradient
.LowerRightCorner
.Y
) pos
.Y
= gradient
.LowerRightCorner
.Y
; colorpos
= pos
.Y
- gradient
.UpperLeftCorner
.Y
; u32
*tmp
=(u32
*)img
[1]->lock
(); color
.set
(tmp
[colorpos
*img
[1]->getOriginalSize
().Width
]); img
[1]->unlock
(); recalculatePickedColor
(); } if(isColor
) { if(pos
.X
< box
.UpperLeftCorner
.X
) pos
.X
= box
.UpperLeftCorner
.X
; if(pos
.Y
< box
.UpperLeftCorner
.Y
) pos
.Y
= box
.UpperLeftCorner
.Y
; if(pos
.X
> box
.LowerRightCorner
.X
) pos
.X
= box
.LowerRightCorner
.X
; if(pos
.Y
> box
.LowerRightCorner
.Y
) pos
.Y
= box
.LowerRightCorner
.Y
; pickpos
.X
= pos
.X
- box
.UpperLeftCorner
.X
; pickpos
.Y
= pos
.Y
- box
.UpperLeftCorner
.Y
; recalculatePickedColor
(); } if(isGradient || isColor
) return true; } if(event
.EventType
== EET_GUI_EVENT
) { switch(event
.GUIEvent
.EventType
) { case EGET_BUTTON_CLICKED
: SEvent event
; event
.EventType
= EET_GUI_EVENT
; event
.GUIEvent
.Caller
= this; event
.GUIEvent
.Element
= 0; event
.GUIEvent
.EventType
= EGET_FILE_SELECTED
; Parent
->OnEvent
(event
); break; case EGET_SCROLL_BAR_CHANGED
: recalculatePickedColor
(); return true; break; } } return IGUIElement
::OnEvent
(event
); } void CGUIColorPicker
::recalculatePickedColor
() noexcept
{ video::SColor hcolor
= color
.getInterpolated
(white
, pickpos
.X
/80.f
); pickcolor
= black
.getInterpolated
(hcolor
, pickpos
.Y
/80.f
); pickcolor
.setAlpha
(scroll
->getPos
()); alpha
= color
; alpha
.setAlpha
(0); } void CGUIColorPicker
::setPickedColor
(const video::SColor &c
) noexcept
{ pickcolor
= c
; core::vector3df hsv
= RGBftoHSV
({ c
.getRed
()/255.f
, c
.getGreen
()/255.f
, c
.getBlue
()/255.f
, c
.getAlpha
()/255.f
}); colorpos
= 150-hsv
.X
/360.f
*150.f
; pickpos
.X
= hsv
.Y
*80.f
; pickpos
.Y
= 80-(hsv
.Z
)*80.f
; u32
*tmp
=(u32
*)img
[1]->lock
(); color
.set
(tmp
[colorpos
*img
[1]->getOriginalSize
().Width
]); img
[1]->unlock
(); alpha
= color
; alpha
.setAlpha
(0); } const video::SColor& CGUIColorPicker
::getPickedColor
() const noexcept
{ return pickcolor
; } void CGUIColorPicker
::setBackgroundColor
(const video::SColor &b
) noexcept
{ background
= b
; } const video::SColor& CGUIColorPicker
::getBackgroundColor
() const noexcept
{ return background
; } void CGUIColorPicker
::updateAbsolutePosition
() { IGUIElement
::updateAbsolutePosition
(); box
.UpperLeftCorner
= AbsoluteRect
.UpperLeftCorner
; box
.LowerRightCorner
= AbsoluteRect
.UpperLeftCorner
; box
.UpperLeftCorner
.X
+= 5; box
.UpperLeftCorner
.Y
+= 5; box
.LowerRightCorner
.X
+= 85; box
.LowerRightCorner
.Y
+= 85; gradient
.UpperLeftCorner
= AbsoluteRect
.UpperLeftCorner
; gradient
.LowerRightCorner
= AbsoluteRect
.UpperLeftCorner
; gradient
.UpperLeftCorner
.X
+= 90; gradient
.UpperLeftCorner
.Y
+= 5; gradient
.LowerRightCorner
.X
+= 105; gradient
.LowerRightCorner
.Y
+= 155; pickbox
.UpperLeftCorner
= AbsoluteRect
.UpperLeftCorner
; pickbox
.LowerRightCorner
= AbsoluteRect
.UpperLeftCorner
; pickbox
.UpperLeftCorner
.X
+= 5; pickbox
.UpperLeftCorner
.Y
+= 90; pickbox
.LowerRightCorner
.X
+= 85; pickbox
.LowerRightCorner
.Y
+= 120; } void CGUIColorPicker
::draw
() { Environment
->getSkin
()->draw3DSunkenPane
( this, background
, false, true, AbsoluteRect
, &AbsoluteClippingRect
); IGUIElement
::draw
(); Environment
->getVideoDriver
()->draw2DImage
(img
[1], { AbsoluteRect
.UpperLeftCorner
.X
+90, AbsoluteRect
.UpperLeftCorner
.Y
+5 }); Environment
->getVideoDriver
()->draw2DRectangle
(black
, box
, &AbsoluteClippingRect
); Environment
->getVideoDriver
()->draw2DRectangle
(box
, white
, color
, alpha
, alpha
, &AbsoluteClippingRect
); { const core::vector2di start
= {AbsoluteRect
.UpperLeftCorner
.X
+90, AbsoluteRect
.UpperLeftCorner
.Y
+5+colorpos
}; const core::vector2di end
= {AbsoluteRect
.UpperLeftCorner
.X
+105, AbsoluteRect
.UpperLeftCorner
.Y
+5+colorpos
}; const core::vector2di hstart
= {box
.UpperLeftCorner
.X
, box
.UpperLeftCorner
.Y
+pickpos
.Y
}; const core::vector2di hend
= {box
.LowerRightCorner
.X
, box
.UpperLeftCorner
.Y
+pickpos
.Y
}; const core::vector2di vstart
= {box
.UpperLeftCorner
.X
+pickpos
.X
, box
.UpperLeftCorner
.Y
}; const core::vector2di vend
= {box
.UpperLeftCorner
.X
+pickpos
.X
, box
.LowerRightCorner
.Y
}; Environment
->getVideoDriver
()->draw2DLine
({ start
.X
, start
.Y
-1}, { end
.X
, end
.Y
-1}, white
); Environment
->getVideoDriver
()->draw2DLine
({ start
.X
, start
.Y
+1}, { end
.X
, end
.Y
+1}, white
); Environment
->getVideoDriver
()->draw2DLine
({hstart
.X
, hstart
.Y
-1}, {hend
.X
, hend
.Y
-1}, white
); Environment
->getVideoDriver
()->draw2DLine
({hstart
.X
, hstart
.Y
+1}, {hend
.X
, hend
.Y
+1}, white
); Environment
->getVideoDriver
()->draw2DLine
({vstart
.X
-1, vstart
.Y
}, {vend
.X
-1, vend
.Y
}, white
); Environment
->getVideoDriver
()->draw2DLine
({vstart
.X
+1, vstart
.Y
}, {vend
.X
+1, vend
.Y
}, white
); Environment
->getVideoDriver
()->draw2DLine
(start
, end
, black
); Environment
->getVideoDriver
()->draw2DLine
(hstart
, hend
, black
); Environment
->getVideoDriver
()->draw2DLine
(vstart
, vend
, black
); } Environment
->getVideoDriver
()->draw2DImage
(img
[0], pickbox
, pickbox
); Environment
->getVideoDriver
()->draw2DRectangle
( pickcolor
, pickbox
, &AbsoluteClippingRect
); } }}
conformement a celui d'irrlicht EGET_FILE_SELECTED est retourner l'orsque "take this color" est cliquer
voila voila "joyeux noel"
post sur le forum officiel:
http://irrlicht.sourceforge.net/forum/v … mp;t=50473
ps: les balises Code=cpp et page suprimme les #define ...