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 "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 }