nux-1.14.0
TimeGraph.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 
00025 #include "NuxGraphics/GLSh_DrawFunction.h"
00026 #include "NuxGraphics/GpuDevice.h"
00027 #include "NuxGraphics/GLDeviceObjects.h"
00028 
00029 #include "TimeGraph.h"
00030 
00031 #include "VLayout.h"
00032 #include "HLayout.h"
00033 #include "Button.h"
00034 #include "StaticTextBox.h"
00035 
00036 namespace nux
00037 {
00038   NUX_IMPLEMENT_OBJECT_TYPE (TimeGraph);
00039 
00040   TimeGraph::Graph::Graph (Color PrimaryColor, Color SecondaryColor)
00041     :   m_HasBeenUpdated (false)
00042   {
00043     m_PrimaryColor = PrimaryColor;
00044     m_SecondaryColor = SecondaryColor;
00045   }
00046 
00047   TimeGraph::Graph::Graph (const Graph &graph)
00048   {
00049     m_PrimaryColor = graph.m_PrimaryColor;
00050     m_SecondaryColor = graph.m_SecondaryColor;
00051     m_HasBeenUpdated = graph.m_HasBeenUpdated;
00052     m_ValueList = graph.m_ValueList;
00053   }
00054 
00055   TimeGraph::Graph &TimeGraph::Graph::operator = (const TimeGraph::Graph &graph)
00056   {
00057     if (this == &graph)
00058       return *this;
00059 
00060     m_PrimaryColor = graph.m_PrimaryColor;
00061     m_SecondaryColor = graph.m_SecondaryColor;
00062     m_HasBeenUpdated = graph.m_HasBeenUpdated;
00063     m_ValueList = graph.m_ValueList;
00064 
00065     return *this;
00066   }
00067 
00068   TimeGraph::Graph::~Graph()
00069   {
00070     Clear();
00071   }
00072 
00073   void TimeGraph::Graph::Update (float Value)
00074   {
00075     m_ValueList.push_front (Value);
00076 
00077     if (m_ValueList.size() >= sBufferSize)
00078     {
00079       m_ValueList.pop_back();
00080     }
00081 
00082     m_HasBeenUpdated = false;
00083   }
00084 
00085   void TimeGraph::Graph::Clear()
00086   {
00087     m_ValueList.clear();
00088     m_HasBeenUpdated = false;
00089   }
00090 
00091   void TimeGraph::Graph::Reset()
00092   {
00093 
00094   }
00095 
00096   t_u32 TimeGraph::sBufferSize = 2048;
00097 
00098   TimeGraph::TimeGraph (const TCHAR *Title, NUX_FILE_LINE_DECL)
00099     :   View (NUX_FILE_LINE_PARAM)
00100   {
00101     m_minY  = 0.0f;
00102     m_maxY  = 1.0f;
00103 
00104     m_Option = SHOW_GRAPH;
00105     m_Title = Title;
00106 
00107     InitializeLayout ();
00108     InitializeWidgets ();
00109   }
00110 
00111   TimeGraph::~TimeGraph()
00112   {
00113     NUX_SAFE_DELETE (m_DrawFunctionShader);
00114     NUX_SAFE_DELETE (m_BackgroundLayer);
00115   }
00116 
00117   void TimeGraph::InitializeWidgets()
00118   {
00119     SetMinimumSize (200, 100);
00120     SetBaseSize (200, 100);
00121 
00122     if (!m_Title.IsEmpty() )
00123       m_GraphTitle->SetText (m_Title);
00124 
00125     Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (256, 4, 0, BITFMT_R8G8B8A8);
00126     m_DrawFunctionShader = new GLSh_DrawFunction();
00127 
00128     NTextureData image;
00129     MakeCheckBoardImage (image.GetSurface (0), 64, 64, Color (0xff323232), Color (0xff535353), 8, 8);
00130     BaseTexture* CheckboardPattern = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture ();
00131     CheckboardPattern->Update (&image);
00132 
00133     TexCoordXForm texxform;
00134     texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
00135     texxform.SetWrap (TEXWRAP_REPEAT, TEXWRAP_REPEAT);
00136     m_BackgroundLayer = new TextureLayer (CheckboardPattern->GetDeviceTexture(), texxform, color::White);
00137 
00138     CheckboardPattern->UnReference ();
00139 
00140     m_ValueIcon->SetMinMaxSize (40, 16);
00141     m_GraphIcon->SetMinMaxSize (16, 16);
00142     m_GraphBarIcon->SetMinMaxSize (16, 16);
00143 
00144 
00145     m_GraphBarIcon->mouse_click.connect (sigc::mem_fun (this, &TimeGraph::RecvShowBarGraphics) );
00146     m_GraphIcon->mouse_click.connect (sigc::mem_fun (this, &TimeGraph::RecvShowCurveGraphics) );
00147     m_ValueIcon->mouse_click.connect (sigc::mem_fun (this, &TimeGraph::RecvShowValue) );
00148 
00149     m_GraphTitle->SetFont (GetSysBoldFont() );
00150     m_hlayout->AddView (new SpaceLayout (40, 40, 0, AREA_MAX_HEIGHT), 1);
00151     m_hlayout->AddView (m_GraphTitle, 1);
00152     m_hlayout->AddView (m_ValueIcon, 0);
00153     m_hlayout->AddView (m_GraphBarIcon, 0);
00154     m_hlayout->AddView (m_GraphIcon, 0);
00155     m_hlayout->SetHorizontalInternalMargin (4);
00156 
00157     m_hlayout2->AddLayout (new SpaceLayout (40, 40, 0, AREA_MAX_HEIGHT), 1);
00158     m_hlayout2->AddView (m_GraphArea, 1);
00159     m_hlayout2->AddLayout (new SpaceLayout (50, 40, 0, AREA_MAX_HEIGHT), 1);
00160 
00161     m_vlayout->AddLayout (m_hlayout, 0);
00162     m_vlayout->AddLayout (m_hlayout2, 1);
00163     m_vlayout->SetVerticalInternalMargin (2);
00164 
00165     SetCompositionLayout (m_vlayout);
00166     SetMinimumSize (200, 120);
00167   }
00168 
00169   void TimeGraph::InitializeLayout()
00170   {
00171     m_vlayout       = new VLayout (NUX_TRACKER_LOCATION);
00172     m_hlayout       = new HLayout (NUX_TRACKER_LOCATION);
00173     m_hlayout2      = new HLayout (TEXT ("QWERTY"), NUX_TRACKER_LOCATION);
00174     m_GraphTitle    = new StaticTextBox (TEXT ("Time Graph"), NUX_TRACKER_LOCATION);
00175     m_GraphArea     = new InputArea (NUX_TRACKER_LOCATION);
00176     m_GraphBarIcon  = new InputArea (NUX_TRACKER_LOCATION);
00177     m_GraphIcon     = new InputArea (NUX_TRACKER_LOCATION);
00178     m_ValueIcon     = new InputArea (NUX_TRACKER_LOCATION);
00179   }
00180 
00181   void TimeGraph::RecvShowBarGraphics (int x, int y, unsigned long button_flags, unsigned long key_flags)
00182   {
00183     m_Option = SHOW_COLUMN;
00184     QueueDraw();
00185   }
00186 
00187   void TimeGraph::RecvShowCurveGraphics (int x, int y, unsigned long button_flags, unsigned long key_flags)
00188   {
00189     m_Option = SHOW_GRAPH;
00190     QueueDraw();
00191   }
00192 
00193   void TimeGraph::RecvShowValue (int x, int y, unsigned long button_flags, unsigned long key_flags)
00194   {
00195     m_Option = SHOW_VALUE;
00196     QueueDraw();
00197   }
00198 
00199 
00200   long TimeGraph::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
00201   {
00202     long ret = m_GraphBarIcon->OnEvent (ievent, TraverseInfo, ProcessEventInfo);
00203     ret = m_GraphIcon->OnEvent (ievent, ret, ProcessEventInfo);
00204     ret = m_ValueIcon->OnEvent (ievent, ret, ProcessEventInfo);
00205     return ret;
00206   }
00207 
00208   void TimeGraph::Draw (GraphicsEngine &GfxContext, bool force_draw)
00209   {
00210     Geometry base = GetGeometry();
00211 
00212     GfxContext.PushClippingRectangle (base);
00213     GetPainter().PaintBackground (GfxContext, base);
00214 
00215     base.OffsetPosition (1, 1);
00216     base.OffsetSize (-2, -2);
00217 
00218 
00219     int W = m_GraphArea->GetBaseWidth() - 2;
00220     int H = m_GraphArea->GetBaseHeight() - 2;
00221     int X = m_GraphArea->GetBaseX() + 1;
00222     int Y = m_GraphArea->GetBaseY() + 1;
00223 
00224 
00225 
00226     m_GraphTitle->ProcessDraw (GfxContext, true);
00227 
00228     // Draw Graph Background
00229     {
00230       m_BackgroundLayer->SetGeometry (Geometry (X, Y, W, H) );
00231       m_BackgroundLayer->Renderlayer (GfxContext);
00232     }
00233 
00234     {
00235       GetPainter().PaintBackground (GfxContext, m_GraphBarIcon->GetGeometry() );
00236       GeometryPositioning gp (eHACenter, eVACenter);
00237       Geometry GeoPo = ComputeGeometryPositioning (m_GraphBarIcon->GetGeometry(), GetTheme().GetImageGeometry (eGraphBarIcon), gp);
00238       GetPainter().Paint2DQuadColor (GfxContext, m_GraphBarIcon->GetGeometry(), Color (0xFF000000) );
00239       GetPainter().PaintShape (GfxContext, GeoPo, Color (0xFFFF9C00), eGraphBarIcon);
00240     }
00241 
00242     {
00243       GetPainter().PaintBackground (GfxContext, m_GraphIcon->GetGeometry() );
00244       GeometryPositioning gp (eHACenter, eVACenter);
00245       Geometry GeoPo = ComputeGeometryPositioning (m_GraphIcon->GetGeometry(), GetTheme().GetImageGeometry (eGraphIcon), gp);
00246       GetPainter().Paint2DQuadColor (GfxContext, m_GraphIcon->GetGeometry(), Color (0xFF000000) );
00247       GetPainter().PaintShape (GfxContext, GeoPo, Color (0xFFFF9C00), eGraphIcon);
00248     }
00249 
00250     {
00251       NString ValueString;
00252       ValueString = NString::Printf (TEXT ("%.2f"), m_maxY);
00253       GetPainter().PaintTextLineStatic (GfxContext, GetSysFont(), Geometry (base.x, Y, 40, 12), ValueString, Color (0xFFFFFFFF) );
00254 
00255       ValueString = NString::Printf (TEXT ("%.2f"), m_minY);
00256       GetPainter().PaintTextLineStatic (GfxContext, GetSysFont(), Geometry (base.x, Y + H - 12, 40, 12), ValueString, Color (0xFFFFFFFF) );
00257 
00258     }
00259 
00260     t_u32 numGraph = (t_u32) m_DynValueArray.size();
00261     t_u32 PosY = Y;
00262 
00263     for (t_u32 index = 0; index < numGraph; index++)
00264     {
00265       GeometryPositioning gp (eHACenter, eVACenter);
00266       Geometry GeoPo = ComputeGeometryPositioning (Geometry (X + W + 2, PosY, 8, 12), GetTheme().GetImageGeometry (eDOT6x6), gp);
00267       //GetPainter().Paint2DQuadColor(GfxContext, Geometry(X + W + 2, PosY, 8, 8), 0xFF000000);
00268       GetPainter().PaintShape (GfxContext, GeoPo, m_DynValueArray[index].m_PrimaryColor, eDOT6x6);
00269 
00270       NString ValueString;
00271 
00272       if (m_DynValueArray[index].m_ValueList.size() == 0)
00273         ValueString = NString::Printf (TEXT ("%.2f"), TEXT ("0.00") );
00274       else
00275         ValueString = NString::Printf (TEXT ("%.2f"), (*m_DynValueArray[index].m_ValueList.begin() ) );
00276 
00277       GetPainter().PaintTextLineStatic (GfxContext, GetSysFont(), Geometry (X + W + 2 + 6, PosY, 40, 12), ValueString, Color (0xFFFFFFFF), true, eAlignTextCenter);
00278 
00279       PosY += 14;
00280     }
00281 
00282     if ((m_Option == SHOW_GRAPH) && m_DynValueArray.size())
00283     {
00284       GfxContext.PushClippingRectangle (m_GraphArea->GetGeometry() );
00285       t_s32 numGraph = (t_s32) m_DynValueArray.size();
00286 
00287       for (t_s32 index = 0; index < numGraph; index++)
00288       {
00289         if (m_DynValueArray[index].m_ValueList.size() <= 1)
00290           continue;
00291 
00292         std::list<float>::iterator it = m_DynValueArray[index].m_ValueList.begin();
00293 
00294         if (Texture->GetWidth() != W)
00295         {
00296           Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (W, 4, 1, BITFMT_R8G8B8A8);
00297         }
00298 
00299         it = m_DynValueArray[index].m_ValueList.begin();
00300         SURFACE_LOCKED_RECT lockrect;
00301         Texture->LockRect (0, &lockrect, 0);
00302         BYTE *dest = (BYTE *) lockrect.pBits;
00303 
00304         for (t_s32 i = 0; i < Texture->GetWidth(); i++)
00305         {
00306           float y;
00307 
00308           if (it == m_DynValueArray[index].m_ValueList.end() )
00309             y = 0.0f;
00310           else
00311           {
00312             y = (*it);
00313             it++;
00314           }
00315 
00316           y = (y - m_minY) / (m_maxY - m_minY);
00317 
00318           for (t_s32 j = 0; j < Texture->GetHeight(); j++)
00319           {
00320             dest[j * lockrect.Pitch + 4* (W - 1 - i) + 0] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00321             dest[j * lockrect.Pitch + 4* (W - 1 - i) + 1] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00322             dest[j * lockrect.Pitch + 4* (W - 1 - i) + 2] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00323             dest[j * lockrect.Pitch + 4* (W - 1 - i) + 3] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00324           }
00325         }
00326 
00327         Texture->UnlockRect (0);
00328         GfxContext.GetRenderStates().SetBlend (TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00329 
00330         m_DrawFunctionShader->SetTextureFunction (Texture);
00331         m_DrawFunctionShader->SetBackgroundColor (m_DynValueArray[index].m_SecondaryColor);
00332         m_DrawFunctionShader->Render (X, Y, 0, W, H, GfxContext.GetWindowWidth(), GfxContext.GetWindowHeight() );
00333 
00334         GfxContext.GetRenderStates().EnableLineSmooth (TRUE, 1, GL_FASTEST);   //You need this blending formula to get anti-aliased lines
00335 
00336         it = m_DynValueArray[index].m_ValueList.begin();
00337         float x0, y0;
00338         x0 = X + W;
00339         y0 = (*it++);
00340 
00341         for ( ; it != m_DynValueArray[index].m_ValueList.end(); it++)
00342         {
00343           float x1, y1;
00344           x1 = x0 - 1;
00345           y1 = (*it);
00346 
00347           int X0, Y0, X1, Y1;
00348           X0 = x0; //X + W * (x0 - m_minX) / (m_maxX - m_minX);
00349           Y0 = Y + H * ( 1 - (y0 - m_minY) / (m_maxY - m_minY) );
00350           X1 = x1; //X + W * (x1 - m_minX) / (m_maxX - m_minX);
00351           Y1 = Y + H * ( 1 - (y1 - m_minY) / (m_maxY - m_minY) );
00352           // NUXTODO: use a vertex buffer instead of sending individual lines
00353           GetPainter().Draw2DLine (GfxContext, X0, Y0, X1, Y1, Color (m_DynValueArray[index].m_PrimaryColor) );
00354 
00355           x0 = x1;
00356           y0 = y1;
00357         }
00358 
00359         GfxContext.GetRenderStates().EnableLineSmooth (FALSE);
00360         GfxContext.GetRenderStates().SetBlend (GL_FALSE);
00361       }
00362 
00363       GfxContext.PopClippingRectangle();
00364     }
00365 
00366     if ((m_Option == SHOW_COLUMN) && m_DynValueArray.size ())
00367     {
00368       t_u32 BarWidth = W / (t_u32) m_DynValueArray.size();
00369 
00370       if (BarWidth < 10)
00371         BarWidth = 10;
00372 
00373       GfxContext.PushClippingRectangle (m_GraphArea->GetGeometry() );
00374       t_u32 numGraph = (t_u32) m_DynValueArray.size();
00375 
00376       for (t_u32 index = 0; index < numGraph; index++)
00377       {
00378         float x0 = 0.0f;
00379         float y0 = 0.0f;
00380         int X0, Y0;
00381 
00382         //y0 = 0.0f;
00383         if (m_DynValueArray[index].m_ValueList.size() != 0)
00384         {
00385           y0 = (*m_DynValueArray[index].m_ValueList.begin() );
00386         }
00387 
00388         x0 = X + W - (index + 1) * BarWidth;
00389 
00390         X0 = x0;
00391         Y0 = Y + H * ( 1 - (y0 - m_minY) / (m_maxY - m_minY) );
00392 
00393         if (index == numGraph - 1)
00394         {
00395           if (X0 > X)
00396           {
00397             X0 = X;
00398             BarWidth += W - numGraph * BarWidth;
00399           }
00400         }
00401 
00402         GetPainter().Paint2DQuadColor (GfxContext, X0, Y0, BarWidth, Y + H - Y0, m_DynValueArray[index].m_PrimaryColor);
00403       }
00404 
00405       GfxContext.PopClippingRectangle();
00406     }
00407 
00408     GetPainter().Paint2DQuadWireframe (GfxContext, m_GraphArea->GetGeometry(), Color (COLOR_BACKGROUND_SECONDARY) );
00409 
00410     GfxContext.PopClippingRectangle();
00411 //     else
00412 //     {
00413 //         NString ValueString;
00414 //         if(m_DynValueArray[index].m_ValueList.size() == 0)
00415 //             ValueString = NString::Printf(TEXT("%.2f"), TEXT("0.00"));
00416 //         else
00417 //             ValueString = NString::Printf(TEXT("%.2f"), (*m_DynValueArray[index].m_ValueList.begin()));
00418 //         GetPainter().PaintTextLineStatic(GfxContext, GetSysBoldFont(), m_GraphArea->GetGeometry(), ValueString, 0xFFFFFFFF, eAlignTextCenter);
00419 //     }
00420   }
00421 
00422   void TimeGraph::DrawContent (GraphicsEngine &GfxContext, bool force_draw)
00423   {
00424   }
00425 
00426   void TimeGraph::PostDraw (GraphicsEngine &GfxContext, bool force_draw)
00427   {
00428   }
00429 
00430   void TimeGraph::SetYAxisBounds (float minY, float maxY)
00431   {
00432     m_minY = minY;
00433     m_maxY = maxY;
00434     QueueDraw();
00435   }
00436 
00437   void TimeGraph::AddValue (float Value)
00438   {
00439 
00440   }
00441 
00442   t_u32 TimeGraph::AddGraph (Color PrimaryColor, Color SecondaryColor)
00443   {
00444     Graph graph (PrimaryColor, SecondaryColor);
00445     // Set an initial value;
00446     graph.Update (0.0f);
00447     t_u32 index = (t_u32) m_DynValueArray.size();
00448     m_DynValueArray.push_back (graph);
00449 
00450     return index;
00451   }
00452 
00453   void TimeGraph::UpdateGraph (t_u32 index, float Value)
00454   {
00455     nuxAssert (index < m_DynValueArray.size() );
00456 
00457     if (index >= m_DynValueArray.size() )
00458       return;
00459 
00460     m_DynValueArray[index].Update (Value);
00461     QueueDraw();
00462   }
00463 
00464   void TimeGraph::ShowGraphStyle()
00465   {
00466     m_Option = SHOW_GRAPH;
00467     QueueDraw();
00468   }
00469 
00470   void TimeGraph::ShowColumnStyle()
00471   {
00472     m_Option = SHOW_COLUMN;
00473     QueueDraw();
00474   }
00475 
00476   void TimeGraph::ShowNumberStyle()
00477   {
00478     m_Option = SHOW_VALUE;
00479     QueueDraw();
00480   }
00481 
00482 
00483 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends