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