nux-0.9.46

Nux/ColorGradient.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #ifndef COLORGRADIENT_H
00024 #define COLORGRADIENT_H
00025 
00026 #include "HexRegExpValidator.h"
00027 #include "IntegerValidator.h"
00028 #include "DoubleValidator.h"
00029 
00030 namespace nux
00031 {
00032 
00033   class HLayout;
00034   class EditTextBox;
00035 
00036   class ColorMarkGroup
00037   {
00038   public:
00039     class ColorMark
00040     {
00041     public:
00042       ColorMark (DOUBLE kX, Color color, bool selected = false, bool excluded = false)
00043         :   m_IsSelected (selected)
00044         ,   m_IsExcluded (excluded)
00045       {
00046         x = kX;
00047         m_Color = color;
00048       }
00049 
00050       bool operator == (const ColorMark &knot)
00051       {
00052         return ( (x == knot.x) && (m_Color == knot.m_Color) );
00053       }
00054 
00055       bool operator != (const ColorMark &knot)
00056       {
00057         return ( (x != knot.x) || (m_Color != knot.m_Color) );
00058       }
00059 
00060       bool operator > (const ColorMark &knot) const
00061       {
00062         return (x > knot.x);
00063       }
00064 
00065       bool operator < (const ColorMark &knot) const
00066       {
00067         return (x < knot.x);
00068       }
00069 
00070       double GetX() const
00071       {
00072         return x;
00073       }
00074       Color GetColor() const
00075       {
00076         return m_Color;
00077       }
00078       void SetX (double d)
00079       {
00080         x = d;
00081       }
00082       void SetColor (Color color)
00083       {
00084         m_Color = color;
00085       }
00086     private:
00087       DOUBLE x;
00088       Color m_Color;
00089       bool m_IsSelected;
00090       bool m_IsExcluded;
00091 
00092       friend class ColorMarkGroup;
00093     };
00094 
00095   public:
00096 
00097     ColorMarkGroup()
00098     {
00099       // There must always be at least two points for the spline interpolation to work
00100       //        m_ColorMarkArray.push_back(ColorMark(0.0, 0.0));
00101       //        m_ColorMarkArray.push_back(ColorMark(1.0, 1.0));
00102     }
00103 
00104     ColorMarkGroup (const ColorMarkGroup &Other)
00105     {
00106       m_ColorMarkArray = Other.m_ColorMarkArray;
00107     }
00108 
00109     ColorMarkGroup &operator = (const ColorMarkGroup &Other)
00110     {
00111       Reset();
00112       m_ColorMarkArray = Other.m_ColorMarkArray;
00113       return *this;
00114     }
00115 
00116     //    void operator = (const ColorMarkGroup* Other)
00117     //    {
00118     //        if(Other == 0)
00119     //            return
00120     //        Reset();
00121     //        m_ColorMarkArray = Other->m_ColorMarkArray;
00122     //        //return *this;
00123     //    }
00124 
00125     void AddColorMark (DOUBLE x, Color color, bool selected = false)
00126     {
00127       std::vector<ColorMark>::iterator it;
00128 
00129       // Check if the exacte same knot is already in.
00130       it = std::find (m_ColorMarkArray.begin(), m_ColorMarkArray.end(), ColorMark (x, color) );
00131 
00132       if (it != m_ColorMarkArray.end() )
00133       {
00134         // already in
00135         return;
00136       }
00137 
00138       // Check if a knot is already in with the same x.
00139       for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++)
00140       {
00141         if ( (*it).x == x)
00142         {
00143           (*it).m_Color = color;
00144           (*it).m_IsSelected = selected;
00145           return;
00146         }
00147       }
00148 
00149       m_ColorMarkArray.push_back (ColorMark (x, color, selected) );
00150       std::sort (m_ColorMarkArray.begin(), m_ColorMarkArray.end(), std::less<ColorMarkGroup::ColorMark>() );
00151     }
00152 
00153     bool isKnotSelected (int i) const
00154     {
00155       if (i >= GetNumColorMark() || i < 0)
00156       {
00157         return false;
00158       }
00159 
00160       return m_ColorMarkArray[i].m_IsSelected;
00161     }
00162 
00163     const ColorMark &operator [] (int i) const
00164     {
00165       return m_ColorMarkArray[i];
00166     }
00167 
00168     ColorMark &operator [] (int i)
00169     {
00170       return m_ColorMarkArray[i];
00171     }
00172 
00173     void EraseKnot (int i)
00174     {
00175       if (m_ColorMarkArray.size() <= 2)
00176       {
00177         // There must always be at least two points for the spline interpolation to work
00178         return;
00179       }
00180 
00181       if (i >= GetNumColorMark() || i < 0)
00182       {
00183         return;
00184       }
00185 
00186       std::vector<ColorMark>::iterator it = m_ColorMarkArray.begin();
00187       it += i;
00188       m_ColorMarkArray.erase (it);
00189     }
00190 
00191     void EraseSelectedKnot()
00192     {
00193       if (m_ColorMarkArray.size() <= 2)
00194       {
00195         // There must always be at least two points for the spline interpolation to work
00196         return;
00197       }
00198 
00199       // Traverse the array and erase selected knots.
00200       bool finish = false;
00201 
00202       do
00203       {
00204         // loop many times to avoid erasing iterators while traversing the array. This is not efficient!
00205         bool found = false;
00206         std::vector<ColorMark>::iterator it;
00207 
00208         for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++)
00209         {
00210           if ( (*it).m_IsSelected)
00211           {
00212             m_ColorMarkArray.erase (it);
00213             found = TRUE;
00214             break;
00215           }
00216         }
00217 
00218         if (!found)
00219           finish = TRUE;
00220       }
00221       while ( (!finish) && (m_ColorMarkArray.size() > 2) );
00222     }
00223 
00224     void SelectKnot (int i, bool b)
00225     {
00226       m_ColorMarkArray[i].m_IsSelected = b;
00227     }
00228 
00229     t_u32 GetNumSelectedKnot()
00230     {
00231       t_u32 n = 0;
00232       std::vector<ColorMark>::iterator it;
00233 
00234       for (t_u32 i = 0; i < (t_u32) m_ColorMarkArray.size(); i++)
00235       {
00236         if (m_ColorMarkArray[i].m_IsSelected)
00237           n++;
00238       }
00239 
00240       return n;
00241     }
00242 
00243     void SelectAllKnot()
00244     {
00245       std::vector<ColorMark>::iterator it;
00246 
00247       for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++)
00248       {
00249         (*it).m_IsSelected = TRUE;
00250       }
00251     }
00252 
00253     void UnSelectAllKnot()
00254     {
00255       std::vector<ColorMark>::iterator it;
00256 
00257       for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++)
00258       {
00259         (*it).m_IsSelected = false;
00260       }
00261     }
00262 
00263     const std::vector<double> GetXArray()
00264     {
00265       std::vector<double> array;
00266       std::vector<ColorMark>::iterator it;
00267 
00268       for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++)
00269       {
00270         if (! (*it).m_IsExcluded)
00271           array.push_back ( (*it).x);
00272       }
00273 
00274       return array;
00275     }
00276 
00277 
00278     const std::vector<Color> GetColorArray()
00279     {
00280       std::vector<Color> array;
00281       std::vector<ColorMark>::iterator it;
00282 
00283       for (it = m_ColorMarkArray.begin(); it != m_ColorMarkArray.end(); it++)
00284       {
00285         if (! (*it).m_IsExcluded)
00286           array.push_back ( (*it).m_Color);
00287       }
00288 
00289       return array;
00290     }
00291 
00292     int GetNumColorMark() const
00293     {
00294       return (int) m_ColorMarkArray.size();
00295     }
00296     ColorMark GetColorMark (int i) const
00297     {
00298       return m_ColorMarkArray[i];
00299     }
00300 
00304     void Reset()
00305     {
00306       m_ColorMarkArray.clear();
00307       //        AddKnot(0,0);
00308       //        AddKnot(1,1);
00309     }
00310   private:
00311     std::vector<ColorMark> m_ColorMarkArray;
00312   };
00313 
00314 
00315   class ColorGradient : public View //public ValuatorAbstraction
00316   {
00317   public:
00318     enum ColorMode
00319     {
00320       COLORMODE_GRADIENT = 0,
00321       COLORMODE_HUE
00322     };
00323 
00324     ColorGradient (float Value = 0, float MinValue = 0.0f, float MaxValue = 1.0f, NUX_FILE_LINE_PROTO);
00325     virtual ~ColorGradient();
00326 
00327     virtual long ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo);
00328     void DrawMarker (GraphicsEngine &GfxContext);
00329     virtual void Draw (GraphicsEngine &GfxContext, bool force_draw);
00330     virtual void DrawContent (GraphicsEngine &GfxContext, bool force_draw);
00331     virtual void PostDraw (GraphicsEngine &GfxContext, bool force_draw);
00332 
00334     //  RECEIVERS  //
00336     void SetRange (float min_value, float max_value);
00337     void SetValue (float value);
00338     float GetValue() const;
00339     float GetMinValue() const
00340     {
00341       return m_min;
00342     }
00343     float GetMaxValue() const
00344     {
00345       return m_max;
00346     }
00347 
00348     void SetBackgroundColor (const Color &color);
00349     const Color GetBackgroundColor() const;
00350 
00352     //  EMITTERS  //
00354     void OnReceiveMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags);
00355     void OnReceiveMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags);
00356     void OnReceiveMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
00357     void OnKeyboardFocus();
00358     void OnLostKeyboardFocus();
00359     void OnValidateKeyboardEntry (EditTextBox *textbox, const NString &text);
00360 
00361     bool IsCtrlKeyPressed() const
00362     {
00363       return (m_CTRL_KEY ? true : false);
00364     }
00365 
00366     // signals
00367     sigc::signal<void, ColorGradient *> sigValueChanged;
00368     sigc::signal<void, float> sigFloatChanged;
00369     sigc::signal<void, float> sigMouseDown;
00370     sigc::signal<void, float> sigMouseUp;
00371     sigc::signal<void, float> sigMouseDrag;
00372     sigc::signal<void, float> sigSetTypedValue;
00373     //sigc::signal<void, const char*> sigValidateKeyboarEntry;
00374 
00375     void EmitFloatChangedSignal();
00376 
00377     void Reset();
00378 
00379     int GetNumColorMark() const
00380     {
00381       return (int) m_ColorMarkGroup.GetNumColorMark();
00382     }
00383     ColorMarkGroup::ColorMark GetColorMark (int i) const
00384     {
00385       return m_ColorMarkGroup.GetColorMark (i);
00386     }
00387     void AddColorMark (DOUBLE x, Color color, bool selected = false);
00388 
00389     void SetColorFormat (Color::Format cf);
00390 
00391   protected:
00392     void InitializeWidgets();
00393     void InitializeLayout();
00394     void DestroyLayout();
00395 
00396   protected:
00397 
00398     ColorMarkGroup m_ColorMarkGroup;
00399 
00400     HLayout        *hlayout;
00401     EditTextBox    *m_ValueString;
00402     InputArea       *m_Percentage;
00403     Color m_BackgroundColor;
00404 
00405     Color::Format m_color_format;
00406 
00407     long m_CTRL_KEY;
00408 
00409     float m_Value;
00410     float m_min, m_max;
00411     HexRegExpValidator m_HexRegExp;
00412     IntegerValidator m_IntRegExp;
00413     DoubleValidator m_DoubleRegExp;
00414   };
00415 
00416 }
00417 
00418 #endif // COLORGRADIENT_H