#0 

22-12-2014 02:07:51

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
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 [email protected]
*
* 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;
        };
    }
}

#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)
                {
                    // 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.}, white);
                Environment->getVideoDriver()->draw2DLine({vstart.X+1,   vstart.Y}, {vend.X+1, vend.}, 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" roll

post sur le forum officiel:
http://irrlicht.sourceforge.net/forum/v … mp;t=50473

ps: les balises Code=cpp et page suprimme les #define ...

Hors ligne


#1 

22-12-2014 18:39:06

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
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


#2 

22-12-2014 19:34:01

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
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 smile


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#3 

22-12-2014 20:23:30

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
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
smile

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
882 membres
1429 sujets
11119 messages
Dernier membre inscrit: LiseBuisson96
63 invités en ligne
Aucun membre connecté
RSS Feed