22-12-2014 01:07:51
- Magun
- Administrateurs

- Date d'inscription:
- Messages: 910
- IP: 92.136.29.112
- Courriel Site web
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__
/**
* Copyright (C) <2014> <Jehan-antoine vayssade>
* Ovan/Magun contact on irrlicht-fr.org or ovan@sleek-think.ovh
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#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;
};
}
}
#endifCode 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;
#define square(colorstart, sx, sy, sz, sw) \\
color = colorstart; \\
for(int y=sy; y<sw; ++y) \\
for(int x=sx; x<sz; ++x) \\
color.getData(&tmp[x + y*16], video::ECF_A8R8G8B8); \\
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;
#define interpolate(colorstart, colorend, start, end) \\
from = colorstart; \\
to = colorend; \\
\\
for(int y=start; y<end; ++y) \\
{ \\
video::SColor c = to.getInterpolated(from, (y-start)/25.f);\\
for(int x=0; x<15; ++x) \\
c.getData(&tmp[x + y*15], video::ECF_A8R8G8B8); \\
}
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)
{
// does not work since 1.7 (i think)
// probably need CGUIModalScreen if this module is add to the engine
//if(!AbsoluteRect.isPointInside(pos) && !isInside)
//{
// SEvent event;
// event.EventType = EET_GUI_EVENT;
// event.GUIEvent.Caller = this;
// event.GUIEvent.Element = 0;
// event.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
// Parent->OnEvent(event);
// remove();
// drop();
//}
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
});
// 2 draw because the interpolation in the diagonal is not well rendered
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/viewtopic.php?f=9&t=50473
ps: les balises Code=cpp et page suprimme les #define ...
Hors ligne
22-12-2014 17:39:06
- Magun
- Administrateurs

- Date d'inscription:
- Messages: 910
- IP: 92.136.29.112
- Courriel Site web
finalement il va remplacer IGUIColorSelectDialog d'irrlicht
donc disponible d'après cutealien sur la prochaine revision du svn (après le nouvelle ans)
Hors ligne
22-12-2014 18:34:01
- Copland
- Modérateurs
- Date d'inscription:
- Messages: 657
- IP: 109.223.166.117
- Courriel Site web
Ah purée jolie ! J'en avais codé un merdique sur mon tool, le tiens est pas mal du tout !
Merci pour se beau partage ![]()
Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.
Hors ligne
22-12-2014 19:23:30
- Magun
- Administrateurs

- Date d'inscription:
- Messages: 910
- IP: 92.136.29.112
- Courriel Site web
je me suis garder le droit d'avoir un version un peut plus élaborer
avec un petit boutton a droit qui permet d'étendre le contenue pour afficher ou pas les scrollbar![]()
Hors ligne



