nux-1.16.0
RGBAProperty.cpp
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 #include "Nux.h"
00024 #include "PropertyList.h"
00025 #include "ColorGradientPropertyItem.h"
00026 #include "RGBAProperty.h"
00027 
00028 namespace nux
00029 {
00030 
00031   RGBAPropertyItem::RGBAPropertyItem (const TCHAR *name, float red /* = 1.0f*/, float green /* = 1.0f*/, float blue /* = 1.0f*/, float alpha /* = 1.0f*/)
00032     : SectionProperty(name, NODE_TYPE_RGBA)
00033     , color_(red, green, blue, alpha)
00034     , color_model_(color::RGB)
00035     , color_format_(color::FLOAT)
00036   {
00037     m_red = new ColorGradientPropertyItem (TEXT ("Red") );
00038     m_green = new ColorGradientPropertyItem (TEXT ("Green") );
00039     m_blue = new ColorGradientPropertyItem (TEXT ("Blue") );
00040     m_alpha = new ColorGradientPropertyItem (TEXT ("Alpha") );
00041 
00042     m_ColorModel = new ToggleButton ("RGB", NUX_TRACKER_LOCATION);
00043     m_ColorModel->SetMinMaxSize (32, 14);
00044     m_ColorModel->SetFont (GetSysBoldFont () );
00045     m_ColorFormat = new ToggleButton ("float", NUX_TRACKER_LOCATION);
00046     m_ColorFormat->SetMinMaxSize (32, 14);
00047     m_ColorFormat->SetFont (GetSysBoldFont () );
00048 
00049     PushChildBack (m_red);
00050     PushChildBack (m_green);
00051     PushChildBack (m_blue);
00052     PushChildBack (m_alpha);
00053 
00054     float r = Clamp (red,   0.0f, 1.0f);
00055     float g = Clamp (green, 0.0f, 1.0f);
00056     float b = Clamp (blue,  0.0f, 1.0f);
00057     float a = Clamp (alpha, 0.0f, 1.0f);
00058 
00059     m_red->SetColorFormat (color_format_);
00060     m_green->SetColorFormat (color_format_);
00061     m_blue->SetColorFormat (color_format_);
00062     m_alpha->SetColorFormat (color_format_);
00063 
00064     m_red->SetRange (0.0f, 1.0f);
00065     m_red->SetValue (r);
00066     m_green->SetRange (0.0f, 1.0f);
00067     m_green->SetValue (g);
00068     m_blue->SetRange (0.0f, 1.0f);
00069     m_blue->SetValue (b);
00070     m_alpha->SetRange (0.0f, 1.0f);
00071     m_alpha->SetValue (a);
00072 
00073     m_red->AddColorMark (0, Color (0.0f, g, b), false);
00074     m_red->AddColorMark (1, Color (1.0f, g, b), false);
00075     m_green->AddColorMark (0, Color (r, 0.0f, b), false);
00076     m_green->AddColorMark (1, Color (r, 1.0f, b), false);
00077     m_blue->AddColorMark (0, Color (r, g, 0.0f), false);
00078     m_blue->AddColorMark (1, Color (r, g, 1.0f), false);
00079     m_alpha->AddColorMark (0, Color (0xFF000000), false);
00080     m_alpha->AddColorMark (1, Color (0xFFFFFFFF), false);
00081 
00082     UpdateStartToEndColors();
00083 
00084     m_red->sigValueChanged.connect ( sigc::mem_fun (this, &RGBAPropertyItem::RedChange) );
00085     m_green->sigValueChanged.connect ( sigc::mem_fun (this, &RGBAPropertyItem::GreenChange) );
00086     m_blue->sigValueChanged.connect ( sigc::mem_fun (this, &RGBAPropertyItem::BlueChange) );
00087     m_alpha->sigValueChanged.connect ( sigc::mem_fun (this, &RGBAPropertyItem::AlphaChange) );
00088 
00089     //FIXME - m_ColorModel->sigClick.connect (sigc::mem_fun (this, &RGBAPropertyItem::OnChangeColorModel) );
00090     //FIXME - m_ColorFormat->sigClick.connect (sigc::mem_fun (this, &RGBAPropertyItem::OnChangeColorFormat) );
00091 
00092     NODE_SIG_CONNECT (m_red->sigValueChanged, RGBAPropertyItem, RecvPropertyChange);
00093     NODE_SIG_CONNECT (m_green->sigValueChanged, RGBAPropertyItem, RecvPropertyChange);
00094     NODE_SIG_CONNECT (m_blue->sigValueChanged, RGBAPropertyItem, RecvPropertyChange);
00095     NODE_SIG_CONNECT (m_alpha->sigValueChanged, RGBAPropertyItem, RecvPropertyChange);
00096   }
00097 
00098   RGBAPropertyItem::~RGBAPropertyItem()
00099   {
00100     m_ColorModel->Dispose();
00101     m_ColorFormat->Dispose();
00102     delete m_red;
00103     delete m_green;
00104     delete m_blue;
00105     delete m_alpha;
00106   }
00107 
00108   long RGBAPropertyItem::ProcessPropertyEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
00109   {
00110     long ret = TraverseInfo;
00111 
00112 //     ret = m_ColorModel->BaseProcessEvent (ievent, ret, ProcessEventInfo);
00113 //     ret = m_ColorFormat->BaseProcessEvent (ievent, ret, ProcessEventInfo);
00114     return ret;
00115   }
00116 
00117   void RGBAPropertyItem::ComputePropertyLayout (int x, int y, RowHeader *row, const std::vector<ColumnHeader>& column_vector)
00118   {
00119     if (m_ItemGeometryVector.size() >= 2)
00120     {
00121       Geometry geo;
00122       geo = m_ItemGeometryVector[1];
00123       geo = geo.GetExpand (-PROPERTY_BORDER_X, -PROPERTY_BORDER_Y);
00124 
00125       m_ColorModel->SetBaseX (geo.x + geo.GetWidth() - PROPERTY_BORDER_X - m_ColorModel->GetBaseWidth() - 2 - m_ColorModel->GetBaseWidth() );
00126       m_ColorModel->SetBaseY (geo.y);
00127 
00128       m_ColorFormat->SetBaseX (geo.x + geo.GetWidth() - PROPERTY_BORDER_X - m_ColorModel->GetBaseWidth() );
00129       m_ColorFormat->SetBaseY (geo.y);
00130     }
00131 
00132   }
00133 
00134   int RGBAPropertyItem::GetItemBestHeight()
00135   {
00136     int sz = 16; //m_ColorModel->GetBaseHeight();
00137     return sz + 2 * PROPERTY_BORDER_Y;
00138   }
00139 
00140   void RGBAPropertyItem::RedChange (ColorGradient *slider)
00141   {
00142     if (slider->IsCtrlKeyPressed() )
00143     {
00144       m_green->SetValue (slider->GetValue() );
00145       m_blue->SetValue (slider->GetValue() );
00146     }
00147 
00148     UpdateStartToEndColors();
00149     m_green->QueueDraw();
00150     m_blue->QueueDraw();
00151     m_alpha->QueueDraw();
00152   }
00153 
00154   void RGBAPropertyItem::GreenChange (ColorGradient *slider)
00155   {
00156     if (slider->IsCtrlKeyPressed() )
00157     {
00158       m_red->SetValue (slider->GetValue() );
00159       m_blue->SetValue (slider->GetValue() );
00160     }
00161 
00162     UpdateStartToEndColors();
00163     m_red->QueueDraw();
00164     m_blue->QueueDraw();
00165     m_alpha->QueueDraw();
00166   }
00167 
00168   void RGBAPropertyItem::BlueChange (ColorGradient *slider)
00169   {
00170     if (slider->IsCtrlKeyPressed() )
00171     {
00172       m_red->SetValue (slider->GetValue() );
00173       m_green->SetValue (slider->GetValue() );
00174     }
00175 
00176     UpdateStartToEndColors();
00177     m_red->QueueDraw();
00178     m_green->QueueDraw();
00179     m_alpha->QueueDraw();
00180   }
00181 
00182   void RGBAPropertyItem::AlphaChange (ColorGradient *slider)
00183   {
00184     UpdateStartToEndColors();
00185 
00186     m_red->QueueDraw();
00187     m_green->QueueDraw();
00188     m_blue->QueueDraw();
00189     m_alpha->QueueDraw();
00190   }
00191 
00192   void RGBAPropertyItem::DrawProperty (GraphicsEngine &GfxContext, TableCtrl *table, bool force_draw, Geometry geo, const BasePainter &Painter,
00193                                        RowHeader *row, const std::vector<ColumnHeader>& column_vector, Color ItemBackgroundColor)
00194   {
00195     if (isDirtyItem() ||
00196         m_red->IsRedrawNeeded() ||
00197         m_green->IsRedrawNeeded() ||
00198         m_blue->IsRedrawNeeded() ||
00199         m_alpha->IsRedrawNeeded() )
00200     {
00201       t_u32 nBackground = table->PushItemBackground (GfxContext, this);
00202       Painter.PaintTextLineStatic (GfxContext, GetSysBoldFont() /*GetFont ()*/, m_FirstColumnUsableGeometry, row->_table_item->GetName(), GetItemTextColor() );
00203 
00204       if (m_ItemGeometryVector.size() >= 2)
00205       {
00206         Geometry prop_geo = m_ItemGeometryVector[1];
00207         prop_geo = prop_geo.GetExpand (-PROPERTY_BORDER_X,
00208                                        -2 * PROPERTY_BORDER_Y);
00209         prop_geo.OffsetSize ( - 2 - m_ColorFormat->GetBaseWidth() - 2 - m_ColorModel->GetBaseWidth() - 2, 0);
00210 
00211         // Draw the resulting color
00212         Painter.Paint2DQuadColor (GfxContext, prop_geo, MakeOpaque(color_));
00213         // Draw black border around the color
00214         Painter.Paint2DQuadWireframe (GfxContext, prop_geo, color::Black);
00215         m_ColorModel->ProcessDraw (GfxContext, true);
00216         m_ColorFormat->ProcessDraw (GfxContext, true);
00217       }
00218 
00219       table->PopItemBackground (GfxContext, nBackground);
00220     }
00221   }
00222 
00223   void RGBAPropertyItem::OnChangeColorModel()
00224   {
00225     if (color_model_ == color::RGB)
00226     {
00227       SetColorModel (color::HLS);
00228       color::HueLightnessSaturation hls(color_);
00229       SetColor(hls.hue, hls.lightness, hls.saturation, color_.alpha);
00230     }
00231     else if (color_model_ == color::HLS)
00232     {
00233       SetColorModel (color::HSV);
00234       color::HueSaturationValue hsv(color_);
00235       SetColor(hsv.hue, hsv.saturation, hsv.value, color_.alpha);
00236     }
00237     else if (color_model_ == color::HSV)
00238     {
00239       SetColorModel (color::RGB);
00240       SetColor(color_.red, color_.green, color_.blue, color_.alpha);
00241     }
00242 
00243     m_green->QueueDraw();
00244     m_blue->QueueDraw();
00245   }
00246 
00247   void RGBAPropertyItem::SetColorModel(color::Model cm)
00248   {
00249     if (cm == color::RGB)
00250     {
00251       color_model_ = color::RGB;
00252       //FIXME - m_ColorModel->SetCaption (TEXT ("RGB") );
00253 
00254       m_red->SetName (TEXT ("Red") );
00255       m_green->SetName (TEXT ("Green") );
00256       m_blue->SetName (TEXT ("Blue") );
00257       m_alpha->SetName (TEXT ("Alpha") );
00258     }
00259 
00260     if (cm == color::HSV)
00261     {
00262       color_model_ = color::HSV;
00263       //FIXME - m_ColorModel->SetCaption (TEXT ("HSV") );
00264 
00265       m_red->SetName (TEXT ("Hue") );
00266       m_green->SetName (TEXT ("Saturation") );
00267       m_blue->SetName (TEXT ("Value") );
00268       m_alpha->SetName (TEXT ("Alpha") );
00269     }
00270 
00271     if (cm == color::HLS)
00272     {
00273       color_model_ = color::HLS;
00274       //FIXME - m_ColorModel->SetCaption (TEXT ("HLS") );
00275 
00276       m_red->SetName (TEXT ("Hue") );
00277       m_green->SetName (TEXT ("Light") );
00278       m_blue->SetName (TEXT ("Saturation") );
00279       m_alpha->SetName (TEXT ("Alpha") );
00280     }
00281 
00282     if (cm == color::YUV)
00283     {
00284       color_model_ = color::YUV;
00285       //FIXME - m_ColorModel->SetBaseString (TEXT ("YUV") );
00286 
00287 //         m_ComponentLabel0->SetBaseString(TEXT("Y"));
00288 //         m_ComponentLabel1->SetBaseString(TEXT("U"));
00289 //         m_ComponentLabel2->SetBaseString(TEXT("V"));
00290 //         m_ComponentAlpha->SetBaseString(TEXT("A"));
00291     }
00292   }
00293 
00294 
00295   void RGBAPropertyItem::OnChangeColorFormat()
00296   {
00297     if (color_format_ == color::FLOAT)
00298     {
00299       color_format_ = color::INT;
00300       //FIXME - m_ColorFormat->SetCaption (TEXT ("int") );
00301     }
00302     else if (color_format_ == color::INT)
00303     {
00304       color_format_ = color::HEX;
00305       //FIXME - m_ColorFormat->SetCaption (TEXT ("hex") );
00306     }
00307     else if (color_format_ == color::HEX)
00308     {
00309       color_format_ = color::FLOAT;
00310       //FIXME - m_ColorFormat->SetCaption (TEXT ("float") );
00311     }
00312 
00313     m_red->SetColorFormat (color_format_);
00314     m_green->SetColorFormat (color_format_);
00315     m_blue->SetColorFormat (color_format_);
00316     m_alpha->SetColorFormat (color_format_);
00317   }
00318 
00319   void RGBAPropertyItem::UpdateStartToEndColors()
00320   {
00321     m_red->Reset();
00322     m_green->Reset();
00323     m_blue->Reset();
00324 
00325     if (color_model_ == color::RGB)
00326     {
00327       color_ = Color(m_red->GetValue(),
00328                      m_green->GetValue(),
00329                      m_blue->GetValue(),
00330                      m_alpha->GetValue());
00331 
00332       m_red->AddColorMark (0, Color (0.0f, color_.green, color_.blue), false);
00333       m_red->AddColorMark (1, Color (1.0f, color_.green, color_.blue), false);
00334       m_green->AddColorMark (0, Color (color_.red, 0.0f, color_.blue), false);
00335       m_green->AddColorMark (1, Color (color_.red, 1.0f, color_.blue), false);
00336       m_blue->AddColorMark (0, Color (color_.red, color_.green, 0.0f), false);
00337       m_blue->AddColorMark (1, Color (color_.red, color_.green, 1.0f), false);
00338     }
00339 
00340     if (color_model_ == color::HSV)
00341     {
00342       color::HueSaturationValue hsv(m_red->GetValue(),
00343                                     m_green->GetValue(),
00344                                     m_blue->GetValue());
00345 
00346       m_red->AddColorMark (0.0f, Color (1.0f, 0.0, 0.0), false);
00347       m_red->AddColorMark (1.0f / 6.0f, Color (1.0f, 1.0, 0.0), false);
00348       m_red->AddColorMark (2.0f / 6.0f, Color (0.0f, 1.0, 0.0), false);
00349       m_red->AddColorMark (3.0f / 6.0f, Color (0.0f, 1.0, 1.0), false);
00350       m_red->AddColorMark (4.0f / 6.0f, Color (0.0f, 0.0, 1.0), false);
00351       m_red->AddColorMark (5.0f / 6.0f, Color (1.0f, 0.0, 1.0), false);
00352       m_red->AddColorMark (1.0f, Color (1.0f, 0.0, 0.0), false);
00353 
00354       if (hsv.hue == 1.0f)
00355         hsv.hue = 0.0f;
00356 
00357       color::RedGreenBlue rgb(hsv);
00358       color_ = Color(rgb, m_alpha->GetValue());
00359 
00360       // The green holds the saturation.
00361       Color min_green(hsv.value, hsv.value, hsv.value);
00362 
00363       // The blue slider handles full value.
00364       hsv.value = 1.0f;
00365       color::RedGreenBlue blue_slider(hsv);
00366       m_blue->AddColorMark (0, color::Black, false);
00367       m_blue->AddColorMark (1.0f, Color(blue_slider), false);
00368 
00369       // Max green slider has full saturation and value
00370       hsv.saturation = 1.0f;
00371       color::RedGreenBlue green_slider(hsv);
00372       Color max_green = Color(green_slider) * hsv.value;
00373       m_green->AddColorMark (0, min_green, false);
00374       m_green->AddColorMark (1.0f, max_green, false);
00375     }
00376 
00377     if (color_model_ == color::HLS)
00378     {
00379       color::HueLightnessSaturation hls(m_red->GetValue(),
00380                                         m_green->GetValue(),
00381                                         m_blue->GetValue());
00382 
00383       m_red->AddColorMark (0.0f, Color (1.0f, 0.0, 0.0), false);
00384       m_red->AddColorMark (1.0f / 6.0f, Color (1.0f, 1.0, 0.0), false);
00385       m_red->AddColorMark (2.0f / 6.0f, Color (0.0f, 1.0, 0.0), false);
00386       m_red->AddColorMark (3.0f / 6.0f, Color (0.0f, 1.0, 1.0), false);
00387       m_red->AddColorMark (4.0f / 6.0f, Color (0.0f, 0.0, 1.0), false);
00388       m_red->AddColorMark (5.0f / 6.0f, Color (1.0f, 0.0, 1.0), false);
00389       m_red->AddColorMark (1.0f, Color (1.0f, 0.0, 0.0), false);
00390 
00391       if (hls.hue == 1.0f)
00392         hls.hue = 0.0f;
00393 
00394       color::RedGreenBlue rgb(hls);
00395       color_ = Color(rgb, m_alpha->GetValue());
00396 
00397       float s = (1.0f - hls.saturation) * 0.5;
00398 
00399       // Need to use HSVtoRGB to compute the primary color
00400       color::HueSaturationValue primary_hsv(hls.hue, 1.0f, 1.0f);
00401       color::RedGreenBlue primary_rgb(primary_hsv);
00402       Color primary = Color(primary_rgb) * hls.saturation + s;
00403       m_green->AddColorMark (0.0f, color::Black, false);
00404       m_green->AddColorMark (0.5f, primary, false);
00405       m_green->AddColorMark (1.0f, color::White, false);
00406 
00407       // Not sure on the name of this color...
00408       Color secondary = Color(primary_rgb);
00409 
00410       if (hls.lightness > 0.5)
00411       {
00412         float factor = (hls.lightness - 0.5f) / 0.5f;
00413         secondary = secondary * ((1 - factor) * hls.saturation) + (s + factor);
00414       }
00415       else
00416       {
00417         float factor = hls.lightness / 0.5f * hls.saturation;
00418         secondary = secondary * factor + s;
00419       }
00420 
00421       m_blue->AddColorMark (0, Color (hls.lightness, hls.lightness, hls.lightness), false);
00422       m_blue->AddColorMark (1.0f, secondary, false);
00423     }
00424   }
00425 
00426   RGBAPropertyItem *RGBAPropertyItem::CreateFromXML (const TiXmlElement *elementxml, NodeNetCom *parent, const char *Name, int id)
00427   {
00428     RGBAPropertyItem *node = new RGBAPropertyItem (Name, 0, 0, 0, 0);
00429     double red, green, blue, alpha;
00430 
00431     const TiXmlElement *childxml = elementxml->FirstChildElement();
00432     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Red"),        &red,       -1);
00433     childxml = childxml->NextSiblingElement();
00434     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Green"),      &green,     -1);
00435     childxml = childxml->NextSiblingElement();
00436     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Blue"),       &blue,      -1);
00437     childxml = childxml->NextSiblingElement();
00438     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Alpha"),      &alpha,     -1);
00439 
00440     node->SetRed (red);
00441     node->SetGreen (green);
00442     node->SetBlue (blue);
00443     node->SetAlpha (alpha);
00444 
00445     node->SetID (id);
00446     return node;
00447   }
00448 
00449   TiXmlElement *RGBAPropertyItem::ToXML() const
00450   {
00451     TiXmlElement *elementxml = NodeNetCom::ToXML();
00452     TiXmlElement *childxml;
00453     childxml = new TiXmlElement (TEXT ("RGBAComponent") );
00454     //childxml->SetAttribute(TEXT("Name"), m_X->GetName());
00455     childxml->SetDoubleAttribute (TEXT ("Red"), color_.red);
00456     elementxml->LinkEndChild (childxml);
00457     childxml = new TiXmlElement (TEXT ("RGBAComponent") );
00458     //childxml->SetAttribute(TEXT("Name"), m_Y->GetName());
00459     childxml->SetDoubleAttribute (TEXT ("Green"), color_.green);
00460     elementxml->LinkEndChild (childxml);
00461     childxml = new TiXmlElement (TEXT ("RGBAComponent") );
00462     //childxml->SetAttribute(TEXT("Name"), m_Z->GetName());
00463     childxml->SetDoubleAttribute (TEXT ("Blue"), color_.blue);
00464     elementxml->LinkEndChild (childxml);
00465     childxml = new TiXmlElement (TEXT ("RGBAComponent") );
00466     //childxml->SetAttribute(TEXT("Name"), m_W->GetName());
00467     childxml->SetDoubleAttribute (TEXT ("Alpha"), color_.alpha);
00468     elementxml->LinkEndChild (childxml);
00469 
00470     return elementxml;
00471   }
00472 
00473   bool RGBAPropertyItem::FromXML (const TiXmlElement *elementxml)
00474   {
00475     double red, green, blue, alpha;
00476     tstring NameX, NameY, NameZ, NameW;
00477     const TiXmlElement *childxml = elementxml->FirstChildElement();
00478     //QueryNodeXMLStringAttribute(childxml, TEXT("Name"), NameX, GetID());
00479     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Red"),       &red,     -1);
00480     childxml = childxml->NextSiblingElement();
00481     //QueryNodeXMLStringAttribute(childxml, TEXT("Name"), NameY, GetID());
00482     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Green"),       &green,     -1);
00483     childxml = childxml->NextSiblingElement();
00484     //QueryNodeXMLStringAttribute(childxml, TEXT("Name"), NameZ, GetID());
00485     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Blue"),       &blue,     -1);
00486     childxml = childxml->NextSiblingElement();
00487     //QueryNodeXMLStringAttribute(childxml, TEXT("Name"), NameW, GetID());
00488     QueryNodeXMLDoubleAttribute (childxml, TEXT ("Alpha"),       &alpha,     -1);
00489     childxml = childxml->NextSiblingElement();
00490 
00491     SetRed (red);
00492     SetGreen (green);
00493     SetBlue (blue);
00494     SetAlpha (alpha);
00495 
00496     return NodeNetCom::FromXML (elementxml);
00497   }
00498 
00499 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends