User

Difference between revisions of "Sascha"

From Guiliani

Line 25: Line 25:
  
 
----------------
 
----------------
 +
 +
/*
 +
* Copyright (C) TES Electronic Solutions GmbH,
 +
* All Rights Reserved.
 +
* Contact: info@guiliani.de
 +
*
 +
* This file is part of the Guiliani HMI framework
 +
* for the development of graphical user interfaces on embedded systems.
 +
*/
 +
 +
#if !defined(EXAMPLE_CONTROL_H)
 +
#define EXAMPLE_CONTROL_H
 +
 +
#include "GUIAbstractBar.h"
 +
#include "GUIRange.h"
 +
#include "GUINinePatch.h"
 +
 +
#include "GUIImageResource.h"
 +
 +
/** An example CGUIObject implementation that draws a rectangle with
 +
    configureable border width and configurable colors.
 +
  */
 +
class ExampleControl : public CGUIAbstractBar
 +
{
 +
public:
 +
    /** Constructor.
 +
        @param pParent Pointer to the designated parent object.
 +
        @param vX X-position relative to its parent object, i.e. the x-offset from the left border of the parent object
 +
        @param vY Y-position relative to its parent object, i.e. the y-offset from the upper border of the parent object
 +
        @param vWidth Width of the object
 +
        @param vHeight Height of the object
 +
        @param uiInnerColor Color to be used for drawing this control's center
 +
              rectangle (everything except the border) in ARGB format.
 +
        @param uiBorderColor Color to be used for drawing this control's frame
 +
              in ARGB format.
 +
        @param vBorderWidth The width of the border in pixels.
 +
        @param eID Object identifier of this object (choose NO_HANDLE if none is required).
 +
    */
 +
    ExampleControl(
 +
        CGUICompositeObject *const pParent,
 +
        const eC_Value &vX, const eC_Value &vY,
 +
        const eC_Value &vWidth, const eC_Value &vHeight,
 +
        eC_UInt uiInnerColor, eC_UInt uiBorderColor,
 +
        eC_Value vBorderWidth = eC_FromInt(1),
 +
        const ObjectHandle_t &eID = NO_HANDLE);
 +
 +
    /// Default constructor to be used by the factory.
 +
    ExampleControl();
 +
 +
    void Init();
 +
 +
    virtual void SetWidth(const eC_Value& vX);
 +
 +
    virtual void SetHeight(const eC_Value& vY);
 +
 +
    virtual eC_Bool DoButtonDown(const eC_Value &vAbsX, const eC_Value &vAbsY);
 +
 +
    virtual eC_Bool DoDrag(const eC_Value &vDeltaX, const eC_Value &vDeltaY, const eC_Value &vAbsX, const eC_Value &vAbsY);
 +
 +
    virtual eC_Bool DoDragEnd(const eC_Value &vAbsX, const eC_Value &vAbsY);
 +
 +
    virtual eC_Bool DoClick(const eC_Value &vAbsX, const eC_Value &vAbsY);
 +
 +
#if defined(GUILIANI_STREAM_GUI)
 +
    /** Reads all object attributes from streaming file.
 +
        This method is called by CGUIFactoryManager after one of the registered
 +
        factories has created an instance of this class.
 +
    */
 +
    virtual void ReadFromStream();
 +
#endif
 +
 +
#if defined(GUILIANI_WRITE_GUI)
 +
    /** Writes all object attributes to the streaming file. A CGUIStreamWriter
 +
        has to be initialized first.
 +
        @param bWriteClassID This flag is used to select if writing of ControlID,
 +
              leading and trailing tags is performed.
 +
    */
 +
    virtual void WriteToStream(const eC_Bool bWriteClassID=false);
 +
#endif
 +
 +
protected:
 +
    /// Called by the Guiliani framework when this control should paint itself.
 +
    eC_Bool DoDraw();
 +
 +
private:
 +
    void CalculateValues();
 +
    void CalculateHandle();
 +
 +
    ImageResource_t m_eBackground;
 +
    CGUINinePatch m_kBackground;
 +
 +
    ImageResource_t m_eRange;
 +
    CGUINinePatch m_kRange;
 +
 +
    ImageResource_t m_eHandle1;
 +
    ImageResource_t m_eHandle2;
 +
 +
    eC_Value m_vMarginX;
 +
    eC_Value m_vMarginY;
 +
 +
    eC_UByte m_ubMovingHandle;
 +
 +
    CGUIRect m_kHandle1;
 +
    CGUIRect m_kHandle2;
 +
 +
    eC_Value m_vHandleWidth;
 +
    eC_Value m_vHandleHeight;
 +
 +
    eC_Value m_vBackgroundWidth;
 +
    eC_Value m_vBackgroundHeight;
 +
    eC_Value m_vBackgroundPosX;
 +
    eC_Value m_vBackgroundPosY;
 +
 +
    CGUIRect m_kRangeRect;
 +
    eC_Value m_vRangeHeight;
 +
 +
    eC_Value m_vLowerValue;
 +
    eC_Value m_vUpperValue;
 +
};
 +
 +
#endif // EXAMPLE_CONTROL_H
 +
 +
-------------------------------
 +
 +
#include "ExampleControl.h"
 +
#include "GfxWrap.h"
 +
#include "GUIStreamReader.h"
 +
#include "GUIStreamWriter.h"
 +
#include "GUIStreamingException.h"
 +
#include "GUIControlResource.h"
 +
 +
#include "GUIResourceManager.h"
 +
 +
#include "GUIMemLeakWatcher.h" // <-- has to be the last include
 +
 +
#define EXAMPLE_CONTROL_CLASS_VERSION 2
 +
// The minimal class version allowed.
 +
#define EXAMPLE_CONTROL_CLASS_MIN_VERSION 1
 +
 +
ExampleControl::ExampleControl(
 +
    CGUICompositeObject *const pParent,
 +
    const eC_Value &vX, const eC_Value &vY,
 +
    const eC_Value &vWidth, const eC_Value &vHeight,
 +
    eC_UInt uiInnerColor, eC_UInt uiBorderColor,
 +
    eC_Value vBorderWidth,
 +
    const ObjectHandle_t &eID) :
 +
    CGUIAbstractBar(pParent, vX, vY, vWidth, vHeight)
 +
{
 +
    Init();
 +
}
 +
 +
ExampleControl::ExampleControl() :
 +
    CGUIAbstractBar()
 +
{
 +
    Init();
 +
}
 +
 +
void ExampleControl::Init()
 +
{
 +
    m_eBackground = IMG_STDCTRL_SLD_BG;
 +
    GETRESMANAGER.RequestImageResource(m_eBackground);
 +
    m_kBackground.Assign(0, 0, 0, 0);
 +
 +
    m_eHandle1 = IMG_STDCTRL_SLD_KNOB_NORMAL;
 +
    GETRESMANAGER.RequestImageResource(m_eHandle1);
 +
 +
    m_eHandle2 = IMG_STDCTRL_SLD_KNOB_HIGHLIGHTED;
 +
    GETRESMANAGER.RequestImageResource(m_eHandle2);
 +
 +
    m_eRange = IMG_STDCTRL_IMGBTN_FOCUSED ;
 +
    GETRESMANAGER.RequestImageResource(m_eRange);
 +
    m_kRange.Assign(0, 0, 0, 0);
 +
 +
    m_vMarginX = eC_FromInt(0);
 +
    m_vMarginY = eC_FromInt(0);
 +
 +
    SetLevel(0);
 +
    SetMinValue(0);
 +
    SetMaxValue(100);
 +
    SetStepSize(1);
 +
 +
    SetXMLTag("ExampleControl");
 +
 +
    m_vHandleWidth = GETGFX.GetImgWidth(m_eHandle1);
 +
    m_vHandleHeight = GETGFX.GetImgHeight(m_eHandle1);
 +
    m_vRangeHeight = GETGFX.GetImgHeight(m_eRange);
 +
 +
    CalculateValues();
 +
}
 +
 +
void ExampleControl::CalculateValues()
 +
{
 +
    m_vBackgroundWidth = GetWidth();
 +
    m_vBackgroundHeight = GETGFX.GetImgHeight(m_eBackground);
 +
 +
    m_vBackgroundPosX = eC_FromInt(0);
 +
    m_vBackgroundPosY = eC_Div(GetHeight() - m_vBackgroundHeight, 2);
 +
 +
    eC_Value vValue1 = GetRange().GetMinValue() + eC_Mul(eC_Div(GetRange().GetMaxValue(), GetWidth() - m_vHandleWidth), m_kHandle1.GetX1() - GetAbsXPos());
 +
    eC_Value vValue2 = GetRange().GetMinValue() + eC_Mul(eC_Div(GetRange().GetMaxValue(), GetWidth() - m_vHandleWidth), m_kHandle2.GetX1() - GetAbsXPos());
 +
 +
    if (vValue1 < vValue2)
 +
    {
 +
        m_vLowerValue = vValue1;
 +
        m_vUpperValue = vValue2;
 +
    }
 +
    else
 +
    {
 +
        m_vLowerValue = vValue2;
 +
        m_vUpperValue = vValue1;
 +
    }
 +
}
 +
 +
void ExampleControl::CalculateHandle()
 +
{
 +
    m_kHandle1.Assign(
 +
        eC_FromInt(0), eC_Div(GetHeight() - m_vHandleHeight, 2),
 +
        m_vHandleWidth, eC_Div(GetHeight() - m_vHandleHeight, 2) + m_vHandleHeight);
 +
    m_kHandle1.Move(GetAbsXPos(), GetAbsYPos());
 +
    m_kHandle2.Assign(
 +
        eC_FromInt(0), eC_Div(GetHeight() - m_vHandleHeight, 2),
 +
        m_vHandleWidth, eC_Div(GetHeight() - m_vHandleHeight, 2) + m_vHandleHeight);
 +
    m_kHandle2.Move(GetAbsXPos(), GetAbsYPos());
 +
}
 +
void ExampleControl::SetWidth(const eC_Value& vX)
 +
{
 +
    CGUIAbstractBar::SetWidth(vX);
 +
 +
    CalculateValues();
 +
    CalculateHandle();
 +
}
 +
 +
void ExampleControl::SetHeight(const eC_Value& vY)
 +
{
 +
    CGUIAbstractBar::SetHeight(vY);
 +
 +
    CalculateValues();
 +
    CalculateHandle();
 +
}
 +
 +
eC_Bool ExampleControl::DoButtonDown(const eC_Value &vAbsX, const eC_Value &vAbsY)
 +
{
 +
    // check handle for position
 +
    if (m_kHandle1.IsInside(vAbsX, vAbsY))
 +
    {
 +
        m_ubMovingHandle = 1;
 +
    }
 +
    else if (m_kHandle2.IsInside(vAbsX, vAbsY))
 +
    {
 +
        m_ubMovingHandle = 2;
 +
    }
 +
    else
 +
    {
 +
        return false;
 +
    }
 +
 +
    CalculateValues();
 +
 +
    InvalidateArea();
 +
 +
    return true;
 +
}
 +
 +
eC_Bool ExampleControl::DoDrag(const eC_Value &vDeltaX, const eC_Value &vDeltaY, const eC_Value &vAbsX, const eC_Value &vAbsY)
 +
{
 +
    if (m_ubMovingHandle == 0)
 +
        return false;
 +
 +
    eC_Value vPosX = vAbsX;
 +
    if (vPosX > GetAbsXPosREdge() - m_vHandleWidth)
 +
        vPosX = GetAbsXPosREdge() - m_vHandleWidth;
 +
    else if (vPosX < GetAbsXPos())
 +
        vPosX = GetAbsXPos();
 +
 +
    if (m_ubMovingHandle == 1)
 +
    {
 +
        m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
 +
    }
 +
    else if (m_ubMovingHandle == 2)
 +
    {
 +
        m_kHandle2.MoveTo(vPosX, m_kHandle2.GetY1());
 +
    }
 +
 +
    CalculateValues();
 +
 +
    InvalidateArea();
 +
 +
    return true;
 +
}
 +
 +
eC_Bool ExampleControl::DoDragEnd(const eC_Value &vAbsX, const eC_Value &vAbsY)
 +
{
 +
    if (m_ubMovingHandle == 0)
 +
        return false;
 +
 +
    eC_Value vPosX = vAbsX;
 +
    if (vPosX > GetAbsXPosREdge() - m_vHandleWidth)
 +
        vPosX = GetAbsXPosREdge() - m_vHandleWidth;
 +
    else if (vPosX < GetAbsXPos())
 +
        vPosX = GetAbsXPos();
 +
 +
    if (m_ubMovingHandle == 1)
 +
    {
 +
        m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
 +
    }
 +
    else if (m_ubMovingHandle == 2)
 +
    {
 +
        m_kHandle2.MoveTo(vPosX, m_kHandle1.GetY1());
 +
    }
 +
 +
    m_ubMovingHandle = 0;
 +
 +
    CalculateValues();
 +
 +
    InvalidateArea();
 +
 +
    return true;
 +
}
 +
 +
eC_Bool ExampleControl::DoClick(const eC_Value &vAbsX, const eC_Value &vAbsY)
 +
{
 +
    if (m_ubMovingHandle != 0)
 +
        return false;
 +
 +
    eC_Value vPosX = vAbsX;
 +
    if (vPosX > GetAbsXPosREdge() - m_vHandleWidth)
 +
        vPosX = GetAbsXPosREdge() - m_vHandleWidth;
 +
    else if (vPosX < GetAbsXPos())
 +
        vPosX = GetAbsXPos();
 +
 +
    if (m_kHandle1.GetX1() < m_kHandle2.GetX1())
 +
    {
 +
        // click only left of handle1 or right or handle2 allowed
 +
        if (vAbsX <= m_kHandle1.GetX2())
 +
        {
 +
            m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
 +
        }
 +
        else if (vAbsX >= m_kHandle2.GetX1())
 +
        {
 +
            m_kHandle2.MoveTo(vPosX, m_kHandle2.GetY1());
 +
        }
 +
    }
 +
    else
 +
    {
 +
        // click only left of handle1 or right or handle2 allowed
 +
        if (vAbsX <= m_kHandle2.GetX2())
 +
        {
 +
            m_kHandle2.MoveTo(vPosX, m_kHandle2.GetY1());
 +
        }
 +
        else if (vAbsX >= m_kHandle1.GetX1())
 +
        {
 +
            m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
 +
        }
 +
    }
 +
 +
    CalculateValues();
 +
 +
    InvalidateArea();
 +
 +
    return true;
 +
}
 +
 +
eC_Bool ExampleControl::DoDraw()
 +
{
 +
    CGUIRect kBackgroundRect(m_vMarginX, m_vMarginY, m_vMarginX + m_vBackgroundWidth, m_vMarginX + m_vBackgroundHeight);
 +
    kBackgroundRect.Move(GetAbsXPos() + m_vMarginX + m_vBackgroundPosX, GetAbsYPos() + m_vMarginY + m_vBackgroundPosY);
 +
 +
    if (m_kHandle1.GetX1() < m_kHandle2.GetX1())
 +
        m_kRangeRect.Assign(m_kHandle1.GetX1(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2), m_kHandle2.GetX2(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2) + m_vRangeHeight);
 +
    else
 +
        m_kRangeRect.Assign(m_kHandle2.GetX1(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2), m_kHandle1.GetX2(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2) + m_vRangeHeight);
 +
 +
    GETGFX.BlitImgExt(m_eBackground, kBackgroundRect);
 +
    GETGFX.BlitImgExt(m_eRange, m_kRangeRect);
 +
    GETGFX.BlitImg(m_eHandle1, m_kHandle1.GetX1(), m_kHandle1.GetY1());
 +
    GETGFX.BlitImg(m_eHandle2, m_kHandle2.GetX1(), m_kHandle2.GetY1());
 +
 +
    return true;
 +
}
 +
 +
#if defined(GUILIANI_STREAM_GUI)
 +
void ExampleControl::ReadFromStream()
 +
{
 +
    const eC_UInt cuiVersion = ReadStreamingHeader(EXAMPLE_CONTROL_CLASS_VERSION, EXAMPLE_CONTROL_CLASS_MIN_VERSION);
 +
 +
    // always base-class first
 +
    CGUIAbstractBar::ReadFromStream();
 +
 +
#if 0
 +
    // remove grouping
 +
    GETINPUTSTREAM.DELETE_COMMENT_TAG("ExampleControl");
 +
 +
    // remove grouping
 +
    GETINPUTSTREAM.DELETE_COMMENT_TAG("/ExampleControl");
 +
#endif
 +
 +
    CalculateValues();
 +
    CalculateHandle();
 +
}
 +
#endif
 +
 +
#if defined(GUILIANI_WRITE_GUI)
 +
void ExampleControl::WriteToStream(const eC_Bool bWriteClassID)
 +
{
 +
    WriteStreamingHeader(bWriteClassID, XMLTAG_CONTROLCLASSID, CTL_EXAMPLE, EXAMPLE_CONTROL_CLASS_VERSION);
 +
 +
    CGUIAbstractBar::WriteToStream();
 +
 +
#if 0
 +
    GETOUTPUTSTREAM.WriteCommentTag("ExampleControl");
 +
 +
    // write attribute-group end
 +
    GETOUTPUTSTREAM.WriteCommentTag("/ExampleControl");
 +
#endif
 +
 +
    WriteStreamingFooter(bWriteClassID);
 +
}
 +
#endif
 +
 +
----------------------------
  
 
https://welovewp.com/how-to-audit-your-user-interface-design/
 
https://welovewp.com/how-to-audit-your-user-interface-design/

Revision as of 19:44, 26 July 2018

    CGfxWrapeGML* pkWrap = dynamic_cast<CGfxWrapeGML*>(&GETGFX);
    if (NULL != pkWrap)
    {
        eGML_Screen* pkScreen = pkWrap->GetScreen();
        unsigned short* memory = (unsigned short*)pkScreen->Lock();

        eC_UInt uiWidth = pkScreen->GetWidth();
        eC_UInt uiHeight = pkScreen->GetHeight();

        memset(memory, 0xf1, uiWidth * uiHeight);
        for (eC_UInt y = 0; y < uiHeight; ++y)
        {
            for (eC_UInt x = 0; x < uiWidth; ++x)
            {
                unsigned short val = memory[y * uiWidth + x];
                memory[y * uiWidth + x] = (val + (x * y)) & 0xffff;
            }
        }

        pkScreen->Unlock();

//        pkScreen->DrawLine(eGML_Vector2(0, 0), eGML_Vector2(10, 10), 0xff004400, 0, 1, 1);
    }

----------------

/*
* Copyright (C) TES Electronic Solutions GmbH,
* All Rights Reserved.
* Contact: info@guiliani.de
*
* This file is part of the Guiliani HMI framework
* for the development of graphical user interfaces on embedded systems.
*/

#if !defined(EXAMPLE_CONTROL_H)
#define EXAMPLE_CONTROL_H

#include "GUIAbstractBar.h"
#include "GUIRange.h"
#include "GUINinePatch.h"

#include "GUIImageResource.h"

/** An example CGUIObject implementation that draws a rectangle with
    configureable border width and configurable colors.
  */
class ExampleControl : public CGUIAbstractBar
{
public:
    /** Constructor.
        @param pParent Pointer to the designated parent object.
        @param vX X-position relative to its parent object, i.e. the x-offset from the left border of the parent object
        @param vY Y-position relative to its parent object, i.e. the y-offset from the upper border of the parent object
        @param vWidth Width of the object
        @param vHeight Height of the object
        @param uiInnerColor Color to be used for drawing this control's center
               rectangle (everything except the border) in ARGB format.
        @param uiBorderColor Color to be used for drawing this control's frame
               in ARGB format.
        @param vBorderWidth The width of the border in pixels.
        @param eID Object identifier of this object (choose NO_HANDLE if none is required).
    */
    ExampleControl(
        CGUICompositeObject *const pParent,
        const eC_Value &vX, const eC_Value &vY,
        const eC_Value &vWidth, const eC_Value &vHeight,
        eC_UInt uiInnerColor, eC_UInt uiBorderColor,
        eC_Value vBorderWidth = eC_FromInt(1),
        const ObjectHandle_t &eID = NO_HANDLE);

    /// Default constructor to be used by the factory.
    ExampleControl();

    void Init();

    virtual void SetWidth(const eC_Value& vX);

    virtual void SetHeight(const eC_Value& vY);

    virtual eC_Bool DoButtonDown(const eC_Value &vAbsX, const eC_Value &vAbsY);

    virtual eC_Bool DoDrag(const eC_Value &vDeltaX, const eC_Value &vDeltaY, const eC_Value &vAbsX, const eC_Value &vAbsY);

    virtual eC_Bool DoDragEnd(const eC_Value &vAbsX, const eC_Value &vAbsY);

    virtual eC_Bool DoClick(const eC_Value &vAbsX, const eC_Value &vAbsY);

#if defined(GUILIANI_STREAM_GUI)
    /** Reads all object attributes from streaming file.
        This method is called by CGUIFactoryManager after one of the registered
        factories has created an instance of this class.
    */
    virtual void ReadFromStream();
#endif

#if defined(GUILIANI_WRITE_GUI)
    /** Writes all object attributes to the streaming file. A CGUIStreamWriter
        has to be initialized first.
        @param bWriteClassID This flag is used to select if writing of ControlID,
               leading and trailing tags is performed.
    */
    virtual void WriteToStream(const eC_Bool bWriteClassID=false);
#endif

protected:
    /// Called by the Guiliani framework when this control should paint itself.
    eC_Bool DoDraw();

private:
    void CalculateValues();
    void CalculateHandle();

    ImageResource_t m_eBackground;
    CGUINinePatch m_kBackground;

    ImageResource_t m_eRange;
    CGUINinePatch m_kRange;

    ImageResource_t m_eHandle1;
    ImageResource_t m_eHandle2;

    eC_Value m_vMarginX;
    eC_Value m_vMarginY;

    eC_UByte m_ubMovingHandle;

    CGUIRect m_kHandle1;
    CGUIRect m_kHandle2;

    eC_Value m_vHandleWidth;
    eC_Value m_vHandleHeight;

    eC_Value m_vBackgroundWidth;
    eC_Value m_vBackgroundHeight;
    eC_Value m_vBackgroundPosX;
    eC_Value m_vBackgroundPosY;

    CGUIRect m_kRangeRect;
    eC_Value m_vRangeHeight;

    eC_Value m_vLowerValue;
    eC_Value m_vUpperValue;
};

#endif // EXAMPLE_CONTROL_H

-------------------------------

#include "ExampleControl.h"
#include "GfxWrap.h"
#include "GUIStreamReader.h"
#include "GUIStreamWriter.h"
#include "GUIStreamingException.h"
#include "GUIControlResource.h"

#include "GUIResourceManager.h"

#include "GUIMemLeakWatcher.h" // <-- has to be the last include

#define EXAMPLE_CONTROL_CLASS_VERSION 2
// The minimal class version allowed.
#define EXAMPLE_CONTROL_CLASS_MIN_VERSION 1

ExampleControl::ExampleControl(
    CGUICompositeObject *const pParent,
    const eC_Value &vX, const eC_Value &vY,
    const eC_Value &vWidth, const eC_Value &vHeight,
    eC_UInt uiInnerColor, eC_UInt uiBorderColor,
    eC_Value vBorderWidth,
    const ObjectHandle_t &eID) :
    CGUIAbstractBar(pParent, vX, vY, vWidth, vHeight)
{
    Init();
}

ExampleControl::ExampleControl() :
    CGUIAbstractBar()
{
    Init();
}

void ExampleControl::Init()
{
    m_eBackground = IMG_STDCTRL_SLD_BG;
    GETRESMANAGER.RequestImageResource(m_eBackground);
    m_kBackground.Assign(0, 0, 0, 0);

    m_eHandle1 = IMG_STDCTRL_SLD_KNOB_NORMAL;
    GETRESMANAGER.RequestImageResource(m_eHandle1);

    m_eHandle2 = IMG_STDCTRL_SLD_KNOB_HIGHLIGHTED;
    GETRESMANAGER.RequestImageResource(m_eHandle2);

    m_eRange = IMG_STDCTRL_IMGBTN_FOCUSED ;
    GETRESMANAGER.RequestImageResource(m_eRange);
    m_kRange.Assign(0, 0, 0, 0);

    m_vMarginX = eC_FromInt(0);
    m_vMarginY = eC_FromInt(0);

    SetLevel(0);
    SetMinValue(0);
    SetMaxValue(100);
    SetStepSize(1);

    SetXMLTag("ExampleControl");

    m_vHandleWidth = GETGFX.GetImgWidth(m_eHandle1);
    m_vHandleHeight = GETGFX.GetImgHeight(m_eHandle1);
    m_vRangeHeight = GETGFX.GetImgHeight(m_eRange);

    CalculateValues();
}

void ExampleControl::CalculateValues()
{
    m_vBackgroundWidth = GetWidth();
    m_vBackgroundHeight = GETGFX.GetImgHeight(m_eBackground);

    m_vBackgroundPosX = eC_FromInt(0);
    m_vBackgroundPosY = eC_Div(GetHeight() - m_vBackgroundHeight, 2);

    eC_Value vValue1 = GetRange().GetMinValue() + eC_Mul(eC_Div(GetRange().GetMaxValue(), GetWidth() - m_vHandleWidth), m_kHandle1.GetX1() - GetAbsXPos());
    eC_Value vValue2 = GetRange().GetMinValue() + eC_Mul(eC_Div(GetRange().GetMaxValue(), GetWidth() - m_vHandleWidth), m_kHandle2.GetX1() - GetAbsXPos());

    if (vValue1 < vValue2)
    {
        m_vLowerValue = vValue1;
        m_vUpperValue = vValue2;
    }
    else
    {
        m_vLowerValue = vValue2;
        m_vUpperValue = vValue1;
    }
}

void ExampleControl::CalculateHandle()
{
    m_kHandle1.Assign(
        eC_FromInt(0), eC_Div(GetHeight() - m_vHandleHeight, 2),
        m_vHandleWidth, eC_Div(GetHeight() - m_vHandleHeight, 2) + m_vHandleHeight);
    m_kHandle1.Move(GetAbsXPos(), GetAbsYPos());
    m_kHandle2.Assign(
        eC_FromInt(0), eC_Div(GetHeight() - m_vHandleHeight, 2),
        m_vHandleWidth, eC_Div(GetHeight() - m_vHandleHeight, 2) + m_vHandleHeight);
    m_kHandle2.Move(GetAbsXPos(), GetAbsYPos());
}
void ExampleControl::SetWidth(const eC_Value& vX)
{
    CGUIAbstractBar::SetWidth(vX);

    CalculateValues();
    CalculateHandle();
}

void ExampleControl::SetHeight(const eC_Value& vY)
{
    CGUIAbstractBar::SetHeight(vY);

    CalculateValues();
    CalculateHandle();
}

eC_Bool ExampleControl::DoButtonDown(const eC_Value &vAbsX, const eC_Value &vAbsY)
{
    // check handle for position
    if (m_kHandle1.IsInside(vAbsX, vAbsY))
    {
        m_ubMovingHandle = 1;
    }
    else if (m_kHandle2.IsInside(vAbsX, vAbsY))
    {
        m_ubMovingHandle = 2;
    }
    else
    {
        return false;
    }

    CalculateValues();

    InvalidateArea();

    return true;
}

eC_Bool ExampleControl::DoDrag(const eC_Value &vDeltaX, const eC_Value &vDeltaY, const eC_Value &vAbsX, const eC_Value &vAbsY)
{
    if (m_ubMovingHandle == 0)
        return false;

    eC_Value vPosX = vAbsX;
    if (vPosX > GetAbsXPosREdge() - m_vHandleWidth)
        vPosX = GetAbsXPosREdge() - m_vHandleWidth;
    else if (vPosX < GetAbsXPos())
        vPosX = GetAbsXPos();

    if (m_ubMovingHandle == 1)
    {
        m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
    }
    else if (m_ubMovingHandle == 2)
    {
        m_kHandle2.MoveTo(vPosX, m_kHandle2.GetY1());
    }

    CalculateValues();

    InvalidateArea();

    return true;
}

eC_Bool ExampleControl::DoDragEnd(const eC_Value &vAbsX, const eC_Value &vAbsY)
{
    if (m_ubMovingHandle == 0)
        return false;

    eC_Value vPosX = vAbsX;
    if (vPosX > GetAbsXPosREdge() - m_vHandleWidth)
        vPosX = GetAbsXPosREdge() - m_vHandleWidth;
    else if (vPosX < GetAbsXPos())
        vPosX = GetAbsXPos();

    if (m_ubMovingHandle == 1)
    {
        m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
    }
    else if (m_ubMovingHandle == 2)
    {
        m_kHandle2.MoveTo(vPosX, m_kHandle1.GetY1());
    }

    m_ubMovingHandle = 0;

    CalculateValues();

    InvalidateArea();

    return true;
}

eC_Bool ExampleControl::DoClick(const eC_Value &vAbsX, const eC_Value &vAbsY)
{
    if (m_ubMovingHandle != 0)
        return false;

    eC_Value vPosX = vAbsX;
    if (vPosX > GetAbsXPosREdge() - m_vHandleWidth)
        vPosX = GetAbsXPosREdge() - m_vHandleWidth;
    else if (vPosX < GetAbsXPos())
        vPosX = GetAbsXPos();

    if (m_kHandle1.GetX1() < m_kHandle2.GetX1())
    {
        // click only left of handle1 or right or handle2 allowed
        if (vAbsX <= m_kHandle1.GetX2())
        {
            m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
        }
        else if (vAbsX >= m_kHandle2.GetX1())
        {
            m_kHandle2.MoveTo(vPosX, m_kHandle2.GetY1());
        }
    }
    else
    {
        // click only left of handle1 or right or handle2 allowed
        if (vAbsX <= m_kHandle2.GetX2())
        {
            m_kHandle2.MoveTo(vPosX, m_kHandle2.GetY1());
        }
        else if (vAbsX >= m_kHandle1.GetX1())
        {
            m_kHandle1.MoveTo(vPosX, m_kHandle1.GetY1());
        }
    }

    CalculateValues();

    InvalidateArea();

    return true;
}

eC_Bool ExampleControl::DoDraw()
{
    CGUIRect kBackgroundRect(m_vMarginX, m_vMarginY, m_vMarginX + m_vBackgroundWidth, m_vMarginX + m_vBackgroundHeight);
    kBackgroundRect.Move(GetAbsXPos() + m_vMarginX + m_vBackgroundPosX, GetAbsYPos() + m_vMarginY + m_vBackgroundPosY);

    if (m_kHandle1.GetX1() < m_kHandle2.GetX1())
        m_kRangeRect.Assign(m_kHandle1.GetX1(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2), m_kHandle2.GetX2(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2) + m_vRangeHeight);
    else
        m_kRangeRect.Assign(m_kHandle2.GetX1(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2), m_kHandle1.GetX2(), GetAbsYPos() + eC_Div(GetHeight() - m_vRangeHeight, 2) + m_vRangeHeight);

    GETGFX.BlitImgExt(m_eBackground, kBackgroundRect);
    GETGFX.BlitImgExt(m_eRange, m_kRangeRect);
    GETGFX.BlitImg(m_eHandle1, m_kHandle1.GetX1(), m_kHandle1.GetY1());
    GETGFX.BlitImg(m_eHandle2, m_kHandle2.GetX1(), m_kHandle2.GetY1());

    return true;
}

#if defined(GUILIANI_STREAM_GUI)
void ExampleControl::ReadFromStream()
{
    const eC_UInt cuiVersion = ReadStreamingHeader(EXAMPLE_CONTROL_CLASS_VERSION, EXAMPLE_CONTROL_CLASS_MIN_VERSION);

    // always base-class first
    CGUIAbstractBar::ReadFromStream();

#if 0
    // remove grouping
    GETINPUTSTREAM.DELETE_COMMENT_TAG("ExampleControl");

    // remove grouping
    GETINPUTSTREAM.DELETE_COMMENT_TAG("/ExampleControl");
#endif

    CalculateValues();
    CalculateHandle();
}
#endif

#if defined(GUILIANI_WRITE_GUI)
void ExampleControl::WriteToStream(const eC_Bool bWriteClassID)
{
    WriteStreamingHeader(bWriteClassID, XMLTAG_CONTROLCLASSID, CTL_EXAMPLE, EXAMPLE_CONTROL_CLASS_VERSION);

    CGUIAbstractBar::WriteToStream();

#if 0
    GETOUTPUTSTREAM.WriteCommentTag("ExampleControl");

    // write attribute-group end
    GETOUTPUTSTREAM.WriteCommentTag("/ExampleControl");
#endif

    WriteStreamingFooter(bWriteClassID);
}
#endif

----------------------------

https://welovewp.com/how-to-audit-your-user-interface-design/
https://www.webdesignerdepot.com/2015/02/the-best-free-ui-kits-february-2015/
https://visual.ly/community/infographic/other/10-commandments-user-interface-design
https://www.componentsource.com/news/feature-releases/2015/10/28/gui-design-studio

https://www.appcues.com/blog/30-awesome-free-ui-vector-kits-for-your-mockups-and-wireframes
designmodo.github.io/Flat-UI/
https://mashable.com/2013/07/29/flat-design-ui-kits/?europe=true

- auto-stretch for text
- invalidate layout after resizing
- calendar-widget
- rating-slider (bargraph)
- multiedge-slider