/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #ifndef COLORGRADIENT_H #define COLORGRADIENT_H #include "HexRegExpValidator.h" #include "IntegerValidator.h" #include "DoubleValidator.h" namespace nux { class HLayout; class EditTextBox; class ColorMarkGroup { public: class ColorMark { public: ColorMark (DOUBLE kX, Color color, bool selected = false, bool excluded = false) : m_IsSelected (selected) , m_IsExcluded (excluded) { x = kX; m_Color = color; } bool operator == (const ColorMark &knot) { return ( (x == knot.x) && (m_Color == knot.m_Color) ); } bool operator != (const ColorMark &knot) { return ( (x != knot.x) || (m_Color != knot.m_Color) ); } bool operator > (const ColorMark &knot) const { return (x > knot.x); } bool operator < (const ColorMark &knot) const { return (x < knot.x); } double GetX() const { return x; } Color GetColor() const { return m_Color; } void SetX (double d) { x = d; } void SetColor (Color color) { m_Color = color; } private: DOUBLE x; Color m_Color; bool m_IsSelected; bool m_IsExcluded; friend class ColorMarkGroup; }; public: ColorMarkGroup() { // There must always be at least two points for the spline interpolation to work // m_ColorMarkArray.push_back(ColorMark(0.0, 0.0)); // m_ColorMarkArray.push_back(ColorMark(1.0, 1.0)); } ColorMarkGroup (const ColorMarkGroup &Other) { m_ColorMarkArray = Other.m_ColorMarkArray; } ColorMarkGroup &operator = (const ColorMarkGroup &Other) { Reset(); m_ColorMarkArray = Other.m_ColorMarkArray; return *this; } // void operator = (const ColorMarkGroup* Other) // { // if(Other == 0) // return // Reset(); // m_ColorMarkArray = Other->m_ColorMarkArray; // //return *this; // } void AddColorMark (DOUBLE x, Color color, bool selected = false) { std::vector::iterator it; // Check if the exacte same knot is already in. it = std::find (m_ColorMarkArray.begin(), m_ColorMarkArray.end(), ColorMark (x, color) ); if (it != m_ColorMarkArray.end() ) { // already in return; } // Check if a knot is already in with the same x. for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++) { if ( (*it).x == x) { (*it).m_Color = color; (*it).m_IsSelected = selected; return; } } m_ColorMarkArray.push_back (ColorMark (x, color, selected) ); std::sort (m_ColorMarkArray.begin(), m_ColorMarkArray.end(), std::less() ); } bool isKnotSelected (int i) const { if (i >= GetNumColorMark() || i < 0) { return false; } return m_ColorMarkArray[i].m_IsSelected; } const ColorMark &operator [] (int i) const { return m_ColorMarkArray[i]; } ColorMark &operator [] (int i) { return m_ColorMarkArray[i]; } void EraseKnot (int i) { if (m_ColorMarkArray.size() <= 2) { // There must always be at least two points for the spline interpolation to work return; } if (i >= GetNumColorMark() || i < 0) { return; } std::vector::iterator it = m_ColorMarkArray.begin(); it += i; m_ColorMarkArray.erase (it); } void EraseSelectedKnot() { if (m_ColorMarkArray.size() <= 2) { // There must always be at least two points for the spline interpolation to work return; } // Traverse the array and erase selected knots. bool finish = false; do { // loop many times to avoid erasing iterators while traversing the array. This is not efficient! bool found = false; std::vector::iterator it; for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++) { if ( (*it).m_IsSelected) { m_ColorMarkArray.erase (it); found = TRUE; break; } } if (!found) finish = TRUE; } while ( (!finish) && (m_ColorMarkArray.size() > 2) ); } void SelectKnot (int i, bool b) { m_ColorMarkArray[i].m_IsSelected = b; } t_u32 GetNumSelectedKnot() { t_u32 n = 0; std::vector::iterator it; for (t_u32 i = 0; i < (t_u32) m_ColorMarkArray.size(); i++) { if (m_ColorMarkArray[i].m_IsSelected) n++; } return n; } void SelectAllKnot() { std::vector::iterator it; for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++) { (*it).m_IsSelected = TRUE; } } void UnSelectAllKnot() { std::vector::iterator it; for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++) { (*it).m_IsSelected = false; } } const std::vector GetXArray() { std::vector array; std::vector::iterator it; for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++) { if (! (*it).m_IsExcluded) array.push_back ( (*it).x); } return array; } const std::vector GetColorArray() { std::vector array; std::vector::iterator it; for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++) { if (! (*it).m_IsExcluded) array.push_back ( (*it).m_Color); } return array; } int GetNumColorMark() const { return (int) m_ColorMarkArray.size(); } ColorMark GetColorMark (int i) const { return m_ColorMarkArray[i]; } /*! Erase all knots. */ void Reset() { m_ColorMarkArray.clear(); // AddKnot(0,0); // AddKnot(1,1); } private: std::vector m_ColorMarkArray; }; class ColorGradient : public View //public ValuatorAbstraction { public: enum ColorMode { COLORMODE_GRADIENT = 0, COLORMODE_HUE }; ColorGradient (float Value = 0, float MinValue = 0.0f, float MaxValue = 1.0f, NUX_FILE_LINE_PROTO); virtual ~ColorGradient(); virtual long ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo); void DrawMarker (GraphicsEngine &GfxContext); virtual void Draw (GraphicsEngine &GfxContext, bool force_draw); virtual void DrawContent (GraphicsEngine &GfxContext, bool force_draw); virtual void PostDraw (GraphicsEngine &GfxContext, bool force_draw); ///////////////// // RECEIVERS // ///////////////// void SetRange (float min_value, float max_value); void SetValue (float value); float GetValue() const; float GetMinValue() const { return m_min; } float GetMaxValue() const { return m_max; } void SetBackgroundColor (const Color &color); const Color GetBackgroundColor() const; //////////////// // EMITTERS // //////////////// void OnReceiveMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnKeyboardFocus(); void OnLostKeyboardFocus(); void OnValidateKeyboardEntry (EditTextBox *textbox, const NString &text); bool IsCtrlKeyPressed() const { return (m_CTRL_KEY ? true : false); } // signals sigc::signal sigValueChanged; sigc::signal sigFloatChanged; sigc::signal sigMouseDown; sigc::signal sigMouseUp; sigc::signal sigMouseDrag; sigc::signal sigSetTypedValue; //sigc::signal sigValidateKeyboarEntry; void EmitFloatChangedSignal(); void Reset(); int GetNumColorMark() const { return (int) m_ColorMarkGroup.GetNumColorMark(); } ColorMarkGroup::ColorMark GetColorMark (int i) const { return m_ColorMarkGroup.GetColorMark (i); } void AddColorMark (DOUBLE x, Color color, bool selected = false); void SetColorFormat (Color::Format cf); protected: void InitializeWidgets(); void InitializeLayout(); void DestroyLayout(); protected: ColorMarkGroup m_ColorMarkGroup; HLayout *hlayout; EditTextBox *m_ValueString; CoreArea *m_Percentage; Color m_BackgroundColor; Color::Format m_color_format; long m_CTRL_KEY; float m_Value; float m_min, m_max; HexRegExpValidator m_HexRegExp; IntegerValidator m_IntRegExp; DoubleValidator m_DoubleRegExp; }; } #endif // COLORGRADIENT_H