Color picker gui

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Color picker gui

Post by CuteAlien »

Getter and setter member-functions always refer to class-members. As long as you think that way it's never confusing. I thought that's pretty standard, at least I can't remember ever working with code that used a get/set to refer to the passed variable instead - that would be something which would really confuse me.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Color picker gui

Post by hendu »

I have seen both, which is why that is confusing. Projects whose getters are just the noun ("data()") occasionally would use getData(void *) to get data from the ptr.
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: Color picker gui

Post by Ovan »

bad idea and not conform of standard coding (CuteAlien as true)
but in all case getter function should be const and here is not, for me it's the single way to misinterpreting (for your thinking)
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Color picker gui

Post by hendu »

You don't see the const when reading code like the color picker. I agree it should be const though.
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Color picker gui

Post by CuteAlien »

I wouldn't care if it were called getDataInto instead of getData, but not going to change it now as the only thing worse than a bad name is a changing interface. But you are right with the const thing... changed that now in svn trunk.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Color picker gui

Post by hendu »

That's why I asked if it was in a release yet?
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Color picker gui

Post by CuteAlien »

Yeah, seems it got added in 1.8.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
chronologicaldot
Competition winner
Posts: 684
Joined: Mon Sep 10, 2012 8:51 am

Re: Color picker gui

Post by chronologicaldot »

Hey! While we're on the topic, can we do something about the useless IColorSelectDialog interface?

Code: Select all

 
    //! Standard color chooser dialog.
    class IGUIColorSelectDialog : public IGUIElement
    {
    public:
 
        //! constructor
        IGUIColorSelectDialog(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
            : IGUIElement(EGUIET_COLOR_SELECT_DIALOG, environment, parent, id, rectangle) {}
    };
 
It should have a "SColor getSelectedColor()" function or something at the very least, and that way when something is added via IGUIEnvironment::addColorSelectDialog, you don't have to know beforehand what it is.

Nice work, Ovan!!

I've also created a color selector, but mine uses getColor() rather than getSelectedColor() or getPickedColor(). I like those names better. hm...
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: Color picker gui

Post by Ovan »

thank ;)

actually I use a different version
Image

but splitting the picked color render box into picked/selected would be nice
thanks for the idea

yes for the interface but with my new color picker i think that the interface will be reworked
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Color picker gui

Post by CuteAlien »

@chronologicaldot: Well, my hope is we can replace it maybe by this. The original one never was functional as far as I know. I don't know why it was checked in before actually being usable. It was in the engine before I started with Irrlicht. And I didn't dare adding to an interface for something that never worked as I always expected this to be replaced some day.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
chronologicaldot
Competition winner
Posts: 684
Joined: Mon Sep 10, 2012 8:51 am

Re: Color picker gui

Post by chronologicaldot »

@CuteAlien - Agreed. I'm inclined to think someone probably started it and forgot to finish. I certainly approve of Ovan's being a replacement, though, with a slight mod as I mention below.

@Ovan - You're welcome.
I notice you are calling IGUIElement::draw() before finishing drawing. I think you're doing this for the scroll bar and button, right? It looks like you could safely call it at the end, and then if someone perhaps had some reason to add a child to the element (such as a pop-up window), it wouldn't be drawn over by the rest of the GUI element.
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: Color picker gui

Post by Ovan »

yeah IGUIElement::draw can be placed at the end for adding element over the interface
if you want my revision ? (including selected color and scroll bar)
the right button can be hidden by constructor and the content cannot extend (for scroll bar)

but I'm not sure, selected color & picked color is always the same when the select button is clicked
I think it need to restore the picked color with the selected when the user click on the selected color render box (maybe not easy to understand in the first use ?)
and add an event when the picked color change his value, in this way irr::gui::EGUI_EVENT_TYPE need to add EGET_COLOR_CHANGED / EGET_COLOR_SELECTED

can be useful if user want to dynamically see the change in the environment
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Color picker gui

Post by CuteAlien »

Finally found some time to take a look at this. Looks really nice on first check. I think we can use this as it is (minor changes aside) and also replace the existing code in CGUIColorSelectDialog to use this element. Then we'd have it once as simple element and once as dialog.

Changes are just minor stuff. Irrlicht uses upper-case for class-variables, no c++11 yet and I think we might already have some functions for hlsl somewhere. My version can as usual be found at https://code.google.com/p/irr-playgroun ... ce/browse/ (thought not much longer probably as stupid, stupid, stupid google is closing down the service, I really have to stop depending on products of a company that cares so little about their users).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: Color picker gui

Post by Ovan »

ok cool :)

just if you want my revision (last screen) but not really necessary for all user, the extended elements (scrollbar) can be show/hidden by the right button
user can disable this functionality on the constructor or via setAdvenced, and hide the button if necessary

Code: Select all

 
#ifndef __C_GUI_COLOR_PICKER_HEADER__
#define __C_GUI_COLOR_PICKER_HEADER__
 
#include <irrlicht/IGUIElement.h>
#include <irrlicht/S3DVertex.h>
 
// Copyright (C) <2014> <Jehan-antoine vayssade>
// Ovan/Magun contact on irrlicht-fr.org or ovan@sleek-think.ovh
// Code is under the zlib license (same as Irrlicht)
// For conditions of distribution and use, see copyright notice in irrlicht.h
 
namespace irr
{
    namespace gui
    {
        class IGUIButton;
        class IGUIStaticText;
        class IGUIScrollBar;
        
        class IGUIColorPicker : public IGUIElement
        {
            public:
                IGUIColorPicker(IGUIEnvironment *environment, IGUIElement *parent, s32 id = 0, bool useAdvenced = true) noexcept;
                ~IGUIColorPicker() noexcept;
 
                virtual void setEnabled(bool);
                virtual void setRelativePosition(const core::recti &r);
 
                virtual bool OnEvent(const SEvent&) noexcept;
                virtual void updateAbsolutePosition();
 
                virtual void setAdvenced(bool) noexcept;
                virtual bool getAdvenced() const noexcept;
 
                virtual void setPickedColor(const video::SColor&) noexcept;
                virtual const video::SColor& getPickedColor() const noexcept;
 
                virtual void setSelectedColor(const video::SColor&) noexcept;
                virtual const video::SColor& getSelectedColor() const noexcept;
 
                virtual void setBackgroundColor(const video::SColor&) noexcept;
                virtual const video::SColor& getBackgroundColor() const noexcept;
 
                IGUIButton *getCloseButton() const noexcept;
                IGUIButton *getExtendButton() const noexcept;
 
                virtual void draw();
            protected:
                virtual void setScrollValueHSV(bool set, int h, int s, int v) noexcept;
                virtual void setScrollValueRGB(bool set, int r, int g, int b) noexcept;
                virtual void updateFromScroll(bool HsvOrRgb) noexcept;
 
                virtual void recalculateAdvenced() noexcept;
                virtual void recalculatePickedColor() noexcept;
 
                virtual void createAlphaTexture() noexcept;
                virtual void createGradientTexture() noexcept;
            protected:
                bool isGradient, isColor, isInside,
                     isExtended, useAdvenced;
 
                int colorpos;
                core::vector2di  pickpos;
 
                video::SColor pickcolor, selectcolor, color;
                video::SColor background, white, black, alpha;
                core::recti   box, selectbox, pickbox, gradient;
 
                IGUIButton      *close, *extend;
                IGUIScrollBar   *scroll;
                IGUIScrollBar   *sb[6];
                IGUIStaticText  *tx[6][2];
                video::ITexture *img[2];
        };
    }
}
 
#endif
 
sorry to frangment the second file, bug with the forum

Code: Select all

 
#include "IGUIColorPicker.h"
 
#include <irrlicht/IGUIEnvironment.h>
#include <irrlicht/IGUIButton.h>
#include <irrlicht/IGUIScrollBar.h>
#include <irrlicht/IGUIStaticText.h>
#include <irrlicht/IVideoDriver.h>
#include <irrlicht/irrMath.h>
#include <irrlicht/SColor.h>
 
// Copyright (C) <2014> <Jehan-antoine vayssade>
// Ovan/Magun contact on irrlicht-fr.org or ovan@sleek-think.ovh
// Code is under the zlib license (same as Irrlicht)
// For conditions of distribution and use, see copyright notice in irrlicht.h
 
namespace irr
{
    inline core::vector3df RGBftoHSV(const 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
    {
        IGUIColorPicker::IGUIColorPicker(IGUIEnvironment *environment, IGUIElement *parent, s32 id, bool uad) noexcept
            : IGUIElement(EGUIET_COLOR_SELECT_DIALOG , environment, parent, id, {0, 0, 110 + uad*15, 160}),
              background{255, 255, 255, 255}, white{255, 255, 255, 255}, black{255, 0, 0, 0}, alpha(0, 0, 0, 0),
              colorpos(0), isGradient(false), isColor(false), isExtended(false), useAdvenced(uad)
        {
            setNotClipped(false);
            close = Environment->addButton({5, 140, 85, 156}, this, 0, L"take this color");
 
            IGUISkin *skin = Environment->getSkin();
 
            extend = Environment->addButton({110, 5, 120, 156}, this);
            extend->setVisible(useAdvenced);
            extend->setSpriteBank(skin->getSpriteBank());
            extend->setSprite(EGBS_BUTTON_UP,   skin->getIcon(EGDI_CURSOR_RIGHT), video::SColor(255,0,0,0));
            extend->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), video::SColor(255,255,255,255));
 
            scroll = Environment->addScrollBar(true, {5, 125, 85, 135}, this);
            scroll->setMin(0);
            scroll->setMax(255);
            scroll->setPos(255);
 
            #define implement_scrollbar(i, text, x, max) \
                tx[i][0] = Environment->addStaticText(text, {125, x, 150, x+10}, false, true, this, -1, true); \
                tx[i][1] = Environment->addStaticText(L"",  {150, x, 270, x+10}, false, true, this, -1, true); \
                tx[i][0]->setVisible(false); \
                tx[i][1]->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); \
                sb[i] = Environment->addScrollBar(true, {125, x+10, 270, x+20}, this); \
                sb[i]->setMin(0); \
                sb[i]->setMax(max); \
                sb[i]->setPos(max); \
                sb[i]->setVisible(false);
 
            implement_scrollbar(0, L"H",  5, 359);
            implement_scrollbar(1, L"S", 27, 100);
            implement_scrollbar(2, L"V", 49, 100);
 
            implement_scrollbar(3, L"R",  89, 255);
            implement_scrollbar(4, L"G", 112, 255);
            implement_scrollbar(5, L"B", 135, 255);
 
            #undef implement_scrollbar
 
            createAlphaTexture();
            createGradientTexture();
 
            setPickedColor({255, 64, 64, 128});
            setSelectedColor({255, 64, 64, 128});
            updateAbsolutePosition();
        }
        IGUIColorPicker::~IGUIColorPicker() noexcept
        {
            close->drop();
            extend->drop();
            scroll->drop();
            img[0]->drop();
            img[1]->drop();
 
            for(int i = 0; i< 6; ++i)
            {
                tx[i][0]->drop();
                tx[i][1]->drop();
                sb[i]->drop();
            }
        }
        void IGUIColorPicker::setEnabled(bool c)
        {
            close->setEnabled(c);
            scroll->setEnabled(c);
            for(int i = 0; i< 6; ++i)
            {
                tx[i][0]->setEnabled(c);
                tx[i][1]->setEnabled(c);
                sb[i]->setEnabled(c);
            }
            IGUIElement::setEnabled(c);
        }
        IGUIButton *IGUIColorPicker::getCloseButton() const noexcept
        {
            return close;
        }
 

Code: Select all

 
        IGUIButton *IGUIColorPicker::getExtendButton() const noexcept
        {
            return extend;
        }
        void IGUIColorPicker::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);
 
            #undef square
 
            img[0]->unlock();
        }
        void IGUIColorPicker::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);
 
            #undef interpolate
 
            img[1]->unlock();
        }
        void IGUIColorPicker::setRelativePosition(const core::recti &r)
        {
            RelativeRect.UpperLeftCorner = r.UpperLeftCorner;
            RelativeRect.LowerRightCorner.X = r.UpperLeftCorner.X + 110 + useAdvenced*15;
            RelativeRect.LowerRightCorner.Y = r.UpperLeftCorner.Y + 160;
 
            if(isExtended)
                RelativeRect.LowerRightCorner.X += 150;
 
            IGUIElement::setRelativePosition(RelativeRect);
        }
        void IGUIColorPicker::setAdvenced(bool i) noexcept
        {
            IGUISkin *skin = Environment->getSkin();
            isExtended = i;
 
            for(int j = 0; j<6; ++j)
            {
                tx[j][0]->setVisible(isExtended);
                tx[j][1]->setVisible(isExtended);
                sb[j]->setVisible(isExtended);
            }
 
            if(isExtended)
            {
                extend->setSprite(EGBS_BUTTON_UP,   skin->getIcon(EGDI_CURSOR_LEFT), video::SColor(255,0,0,0));
                extend->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), video::SColor(255,255,255,255));
                recalculatePickedColor();
                recalculateAdvenced();
            }
            else
            {
                extend->setSprite(EGBS_BUTTON_UP,   skin->getIcon(EGDI_CURSOR_RIGHT), video::SColor(255,0,0,0));
                extend->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), video::SColor(255,255,255,255));
            }
 
            setRelativePosition(RelativeRect);
        }
        bool IGUIColorPicker::getAdvenced() const noexcept
        {
            return isExtended;
        }
        bool IGUIColorPicker::OnEvent(const SEvent &event) noexcept
        {
            if(!isEnabled())
                return IGUIElement::OnEvent(event);
 
            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)
                    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();
                    }
                    if(isInside && !isGradient && !isColor && selectbox.isPointInside(pos))
                    {
                        setPickedColor(getSelectedColor());
                    }
                    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;
                    recalculatePickedColor();
                    recalculateAdvenced();
                }
 
                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();
                    recalculateAdvenced();
                }
 
                if(isGradient || isColor)
                    return true;
            }
 
            if(event.EventType == EET_GUI_EVENT)
            {
                switch(event.GUIEvent.EventType)
                {
                    case EGET_BUTTON_CLICKED:
                        if(event.GUIEvent.Caller == close)
                        {
                            setSelectedColor(pickcolor);
                            SEvent event;
                            event.EventType = EET_GUI_EVENT;
                            event.GUIEvent.Caller = this;
                            event.GUIEvent.Element = 0;
                            event.GUIEvent.EventType = EGET_FILE_SELECTED;
                            Parent->OnEvent(event);
                        }
                        else
                        {
                            isExtended = !isExtended;
                            setAdvenced(isExtended);
                        }
                    break;
                    case EGET_SCROLL_BAR_CHANGED:
                    {
                        if(event.GUIEvent.Caller == scroll)
                            recalculatePickedColor();
                        else
                        {
                            updateFromScroll(
                                event.GUIEvent.Caller == sb[0] ||
                                event.GUIEvent.Caller == sb[1] ||
                                event.GUIEvent.Caller == sb[2]
                            );
                        }
                        return true;
                    }
                    break;
                }
            }
 
            return IGUIElement::OnEvent(event);
        }
        void IGUIColorPicker::setScrollValueHSV(bool set, int h, int s, int v) noexcept
        {
            core::stringw value;
 
            #define set(i, v) \
                value = L""; \
                value += v; \
                tx[i][1]->setText(value.c_str()); \
                if(set) sb[i]->setPos(v); \

            set(0, h);
            set(1, s);
            set(2, v);
 
            #undef set
        }
        void IGUIColorPicker::setScrollValueRGB(bool set, int r, int g, int b) noexcept
        {
            core::stringw value;
 
            #define set(i, v) \
                value = L""; \
                value += v; \
                tx[i][1]->setText(value.c_str()); \
                if(set) sb[i]->setPos(v); \

            set(3, r);
            set(4, g);
            set(5, b);
 
            #undef set
        }
        void IGUIColorPicker::updateFromScroll(bool HsvOrRgb) noexcept
        {
            if(HsvOrRgb)
            {
                colorpos = 150-sb[0]->getPos()/360.f*150.f;
                pickpos.X = sb[1]->getPos()*0.8f;
                pickpos.Y = 80-sb[2]->getPos()*0.8f;
                recalculatePickedColor();
                setScrollValueHSV(false, sb[0]->getPos(), sb[1]->getPos(), sb[2]->getPos());
                setScrollValueRGB(true, pickcolor.getRed(), pickcolor.getGreen(), pickcolor.getBlue());
            }
            else
            {
                setPickedColor({
                    (u32)scroll->getPos(),
                    (u32)sb[3]->getPos(),
                    (u32)sb[4]->getPos(),
                    (u32)sb[5]->getPos()
                });
            }
        }
        void IGUIColorPicker::recalculateAdvenced() noexcept
        {
            if(!isExtended)
                return;
 
            core::stringw value;
 
            core::vector3df hsv = RGBftoHSV({
                pickcolor.getRed()/255.f,
                pickcolor.getGreen()/255.f,
                pickcolor.getBlue()/255.f,
                pickcolor.getAlpha()/255.f
            });
 
            setScrollValueHSV(true, hsv.X, hsv.Z*100.f, hsv.Y*100.f);
            setScrollValueRGB(true, pickcolor.getRed(), pickcolor.getGreen(), pickcolor.getBlue());
        }
        void IGUIColorPicker::recalculatePickedColor() noexcept
        {
            u32 *tmp =(u32*)img[1]->lock();
            color.set(tmp[colorpos*img[1]->getOriginalSize().Width]);
            img[1]->unlock();
 
            alpha = color;
            alpha.setAlpha(0);
 
            video::SColor hcolor = color.getInterpolated(white, pickpos.X/80.f);
            pickcolor = black.getInterpolated(hcolor, pickpos.Y/80.f);
            pickcolor.setAlpha(scroll->getPos());
        }
        void IGUIColorPicker::setPickedColor(const video::SColor &c) noexcept
        {
            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.Z*80.f;
            pickpos.Y = 80-hsv.Y*80.f;
 
            scroll->setPos(c.getAlpha());
            recalculatePickedColor();
 
            setScrollValueHSV(true, hsv.X, hsv.Z*100, hsv.Y*100);
            setScrollValueRGB(true, c.getRed(), c.getGreen(), c.getBlue());
        }
        const video::SColor& IGUIColorPicker::getPickedColor() const noexcept
        {
            return pickcolor;
        }
        void IGUIColorPicker::setSelectedColor(const video::SColor &b) noexcept
        {
            selectcolor = b;
        }
        const video::SColor& IGUIColorPicker::getSelectedColor() const noexcept
        {
            return selectcolor;
        }
        void IGUIColorPicker::setBackgroundColor(const video::SColor &b) noexcept
        {
            background = b;
        }
        const video::SColor& IGUIColorPicker::getBackgroundColor() const noexcept
        {
            return background;
        }
        void IGUIColorPicker::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 += 105;
 
            selectbox.UpperLeftCorner = AbsoluteRect.UpperLeftCorner;
            selectbox.LowerRightCorner = AbsoluteRect.UpperLeftCorner;
            selectbox.UpperLeftCorner.X += 5;
            selectbox.UpperLeftCorner.Y += 105;
            selectbox.LowerRightCorner.X += 85;
            selectbox.LowerRightCorner.Y += 120;
        }
        void IGUIColorPicker::draw()
        {
            if(!isVisible())
                return;
 
            Environment->getSkin()->draw3DSunkenPane(
                this, background,
                false, true,
                AbsoluteRect,
                &AbsoluteClippingRect
            );
 
            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
            );
            Environment->getVideoDriver()->draw2DImage(img[0], selectbox, selectbox);
            Environment->getVideoDriver()->draw2DRectangle(
                selectcolor, selectbox,
                &AbsoluteClippingRect
            );
 
            IGUIElement::draw();
        }
    }
}
 
well, I see your revision nice to comment some parts, so I give you some explain ^^"
setRelativePosition, yes I didn't see that is not virtual, but why all function in IGUIElement is not virtual ? my gall is to restrain the size of this element or if you have the time to do it
setDrawBackground, yes maybe :)

SomeColor is the picked color from the gradient image
Alpha is equal to SomeColor but alpha=0 is used from the rendering (get a bad interpolation else)
PickColor is a calculated color from hsv position inside Box

Box upper left rectangle (PickColor)
Gradient right rectangle (SomeColor)
PickBox lower left rectangle (rendered color)

if you need some other explain, I'm here
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Color picker gui

Post by CuteAlien »

Thanks for the info. I've put it a little down an my todo again as I noticed I'll have to rework some more there before I can apply this.
And sorry, can't merge with your version again as I already rewrote too much to fit it to Irrlicht (no c++11, variable naming and some minor changes). I hope I get back to that within next weeks. Probably as first step I just use parts of it to replace the color-selection in the Irrlicht color selection dialog. But also wondering about Irrlicht dialogs in general - they should unify their layout some more. Also I liked in your solution that you can use it without dialog - which maybe also could be done generally. Have to think some more about this.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply