nux-1.16.0
|
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 }