nux-1.16.0
SplineCurveEditor.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 "NuxCore/Math/Spline.h"
00026 
00027 #include "NuxGraphics/GpuDevice.h"
00028 #include "NuxGraphics/GLDeviceObjects.h"
00029 #include "NuxGraphics/GLSh_DrawFunction.h"
00030 
00031 #include "SplineCurveEditor.h"
00032 
00033 namespace nux
00034 {
00035 
00036   static const int KNOT_SIZE = 2;
00037   static const int KNOT_HIT_TEST = 4;
00038   static const int GRAPH_MARGIN = 2;
00039 
00040   unsigned long CTRL_KEY = 0;
00041 // todo InitWidget
00042   SplineCurveEditor::SplineCurveEditor (NUX_FILE_LINE_DECL)
00043     :   View (NUX_FILE_LINE_PARAM)
00044   {
00045     m_minX              = 0.0f;
00046     m_minY              = 0.0f;
00047     m_maxX              = 1.0f;
00048     m_maxY              = 1.0f;
00049     m_FunctionCallback  = 0;
00050     m_Background        = 0;
00051 
00052     InitializeLayout();
00053     InitializeWidgets();
00054 
00055     m_control_knot.Reset();
00056     m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00057 
00058 
00059     m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (256, 4, 0, BITFMT_R8G8B8A8);
00060     m_DrawFunctionShader = new GLSh_DrawFunction();
00061 
00062     NTextureData image;
00063     MakeCheckBoardImage (image.GetSurface (0), 64, 64, Color (0xff323232), Color (0xff535353), 8, 8);
00064     BaseTexture* CheckboardPattern = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture ();
00065     CheckboardPattern->Update(&image);
00066 
00067     TexCoordXForm texxform;
00068     texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
00069     texxform.SetWrap (TEXWRAP_REPEAT, TEXWRAP_REPEAT);
00070     m_Background = new TextureLayer (CheckboardPattern->GetDeviceTexture(), texxform, color::White);
00071 
00072     CheckboardPattern->UnReference ();;
00073 //     m_Background = PaintLayer(m_CheckboardPattern);
00074 //     m_Background.SetTileTexture(true);
00075   }
00076 
00077   SplineCurveEditor::~SplineCurveEditor()
00078   {
00079     NUX_SAFE_DELETE (m_DrawFunctionShader);
00080     NUX_SAFE_DELETE (m_Background);
00081   }
00082 
00083   void SplineCurveEditor::InitializeWidgets()
00084   {
00085 
00086   }
00087 
00088   void SplineCurveEditor::InitializeLayout()
00089   {
00090     SetMinimumSize (200, 200);
00091     mouse_down.connect (sigc::mem_fun (this, &SplineCurveEditor::RecvMouseDown) );
00092     mouse_up.connect (sigc::mem_fun (this, &SplineCurveEditor::RecvMouseUp) );
00093     mouse_drag.connect (sigc::mem_fun (this, &SplineCurveEditor::RecvMouseDrag) );
00094     key_down.connect (sigc::mem_fun (this, &SplineCurveEditor::RecvKeyEvent) );
00095   }
00096 
00097   void SplineCurveEditor::SetControlPoints (const SplineKnot &splineKnot)
00098   {
00099     m_control_knot.Reset();
00100     m_control_knot = splineKnot;
00101     m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00102   }
00103 
00104   const SplineKnot &SplineCurveEditor::GetControlPoints() const
00105   {
00106     return m_control_knot;
00107   }
00108 
00109   void SplineCurveEditor::AddKnot (double x, double y, bool selected)
00110   {
00111     m_control_knot.AddKnot (x, y, selected);
00112     m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00113     sigCurveChange.emit (this);
00114     QueueDraw();
00115   }
00116 
00117   void SplineCurveEditor::Reset()
00118   {
00119     m_control_knot.Reset();
00120   }
00121 
00122   double SplineCurveEditor::Eval (double t)
00123   {
00124     double val;
00125     int nbKnot = m_control_knot.GetNumKnot();
00126 
00127     if (nbKnot <= 1)
00128       return 0.0;
00129 
00130     if (t < m_control_knot[0].GetX() )
00131       val = m_control_knot[0].GetY();
00132     else if (t > m_control_knot[nbKnot-1].GetX() )
00133       val = m_control_knot[nbKnot-1].GetY();
00134     else
00135       val = m_CubicSpline.Eval (t);
00136 
00137     if (val > m_maxY)
00138       val = m_maxY;
00139 
00140     if (val < m_minY)
00141       val = m_minY;
00142 
00143     return val;
00144   }
00145 
00146   long SplineCurveEditor::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
00147   {
00148     long ret = TraverseInfo;
00149 
00150     if (ievent.e_event == NUX_MOUSE_PRESSED)
00151     {
00152       if (!GetGeometry().IsPointInside (ievent.e_x, ievent.e_y) )
00153       {
00154         //return TraverseInfo;
00155       }
00156     }
00157 
00158     CTRL_KEY = ievent.GetVirtualKeyState (NUX_VK_LCONTROL);
00159     ret = PostProcessEvent2 (ievent, ret, ProcessEventInfo);
00160     return ret;
00161   }
00162 
00163 
00164   void SplineCurveEditor::Draw (GraphicsEngine &GfxContext, bool force_draw)
00165   {
00166     Geometry base = GetGeometry();
00167 
00168     GetPainter().PaintBackground (GfxContext, base);
00169     GetPainter().Paint2DQuadColor (GfxContext, base, Color (COLOR_BACKGROUND_PRIMARY) );
00170 
00171     base.OffsetPosition (GRAPH_MARGIN, GRAPH_MARGIN);
00172     base.OffsetSize (-2 * GRAPH_MARGIN, -2 * GRAPH_MARGIN);
00173 
00174     int i;
00175     int nsample = base.GetWidth();
00176     int nbKnot = m_control_knot.GetNumKnot();
00177 
00178     if (1)
00179     {
00180       double *t = 0;
00181       double *y = 0;
00182 
00183       if (nbKnot > 1)
00184       {
00185         t = new double[nbKnot];
00186         y = new double[nbKnot];
00187       }
00188 
00189       std::vector<double> a;
00190       std::vector<double> b;
00191 
00192       if (nbKnot > 1)
00193       {
00194         for (i = 0; i < nbKnot; i++)
00195         {
00196           t[i] = m_control_knot[i].GetX();
00197           y[i] = m_control_knot[i].GetY();
00198           a.push_back (m_control_knot[i].GetX() );
00199           b.push_back (m_control_knot[i].GetY() );
00200         }
00201       }
00202 
00203       int W = GetBaseWidth() - 2 * GRAPH_MARGIN;
00204       int H = GetBaseHeight() - 2 * GRAPH_MARGIN;
00205       int X = GetBaseX() + GRAPH_MARGIN;
00206       int Y = GetBaseY() + GRAPH_MARGIN;
00207 
00208       double tval_prev, val_prev;
00209       double tval, val;
00210       tval_prev = 0.0;
00211 
00212       val_prev = Eval (tval_prev);
00213 
00214       GetPainter().PushDrawLayer (GfxContext, base, m_Background);
00215       GetPainter().PopBackground();
00216 
00217       GfxContext.PushClippingRectangle (base);
00218 
00219       GfxContext.GetRenderStates().EnableLineSmooth (TRUE, 1, GL_FASTEST);
00220       GfxContext.GetRenderStates().SetBlend (TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00221       GfxContext.GetRenderStates().SetColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
00222 
00223       if (nbKnot <= 1)
00224         GetPainter().Draw2DLine (GfxContext, X, Y + H - 1, X + W, Y + H - 1, Color (0xFFFFFFFF) );
00225       else
00226       {
00227         float tex_dx = (m_maxX - m_minX) / m_Texture->GetWidth();
00228         SURFACE_LOCKED_RECT lockrect;
00229         m_Texture->LockRect (0, &lockrect, 0);
00230         BYTE *dest = (BYTE *) lockrect.pBits;
00231 
00232         for (t_s32 i = 0; i < m_Texture->GetWidth(); i++)
00233         {
00234           float y = m_CubicSpline.Eval (m_minX + i * tex_dx);
00235           y = (y - m_minY) / (m_maxY - m_minY);
00236 
00237           for (t_s32 j = 0; j < m_Texture->GetHeight(); j++)
00238           {
00239             dest[4*i + 0 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00240             dest[4*i + 1 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00241             dest[4*i + 2 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00242             dest[4*i + 3 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f);
00243           }
00244         }
00245 
00246         m_Texture->UnlockRect (0);
00247 
00248         m_DrawFunctionShader->SetTextureFunction (m_Texture);
00249         m_DrawFunctionShader->SetBackgroundColor (Color(0.1f, 0.1f, 0.1f, 0.6f));
00250         m_DrawFunctionShader->Render (X, Y, 0, W, H, GfxContext.GetWindowWidth(), GfxContext.GetWindowHeight() );
00251         //m_DrawFunctionShader->End();
00252 
00253         for ( int i = 1; i < nsample; i++ )
00254         {
00255           tval = ( double ) ( i ) / ( double ) ( nsample - 1 );
00256           val = m_CubicSpline.Eval (tval);
00257 
00258           if (val > m_maxY)
00259             val = m_maxY;
00260 
00261           if (val <= m_minY)
00262             val = m_minY + 1.0f / H;
00263 
00264           int X0, Y0, X1, Y1;
00265           X0 = X + W * (tval_prev - m_minX) / (m_maxX - m_minX);
00266           Y0 = Y + H * ( 1 - (val_prev - m_minY) / (m_maxY - m_minY) );
00267           X1 = X + W * (tval - m_minX) / (m_maxX - m_minX);
00268           Y1 = Y + H * ( 1 - (val - m_minY) / (m_maxY - m_minY) );
00269 
00270           GetPainter().Draw2DLine (GfxContext, X0, Y0, X1, Y1, Color (0xFFFFFFFF) );
00271 
00272           tval_prev = tval;
00273           val_prev = val;
00274         }
00275 
00276       }
00277 
00278       GfxContext.GetRenderStates().EnableLineSmooth (GL_FALSE);
00279       GfxContext.GetRenderStates().SetBlend (GL_FALSE);
00280       GfxContext.GetRenderStates().SetColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00281 
00282       for (i = 0; i < nbKnot; i++)
00283       {
00284         int X0, Y0;
00285         X0 = X + W * (m_control_knot[i].GetX() - m_minX) / (m_maxX - m_minX);
00286         Y0 = Y + H * ( 1 - (m_control_knot[i].GetY() - m_minY) / (m_maxY - m_minY) );
00287 
00288         Geometry ShapeGeo = GetTheme().GetImageGeometry (eDOT6x6);
00289 
00290         if (m_control_knot.isKnotSelected (i) )
00291         {
00292           GetPainter().PaintShape (GfxContext,
00293                                Geometry (X0 - ShapeGeo.GetWidth() / 2, Y0 - ShapeGeo.GetHeight() / 2, ShapeGeo.GetWidth(), ShapeGeo.GetHeight() ),
00294                                Color (0xFF44FF44), eDOT6x6);
00295         }
00296         else
00297         {
00298           GetPainter().PaintShape (GfxContext,
00299                                Geometry (X0 - ShapeGeo.GetWidth() / 2, Y0 - ShapeGeo.GetHeight() / 2, ShapeGeo.GetWidth(), ShapeGeo.GetHeight() ),
00300                                Color (0xFFFFFFFF), eDOT6x6);
00301 
00302         }
00303       }
00304 
00305       GfxContext.PopClippingRectangle();
00306 
00307       delete[] t;
00308       delete[] y;
00309     }
00310 
00311     // We do some ajustment here because when a knot is at one of the border, we still want to see the entire knot and not have the wireframe
00312     // square draw itself over it.
00313     GetPainter().Paint2DQuadWireframe (GfxContext, Geometry (base.x - KNOT_SIZE,
00314                                    base.y - KNOT_SIZE,
00315                                    base.GetWidth() + 2 * KNOT_SIZE,
00316                                    base.GetHeight() + 2 * KNOT_SIZE), Color (0xFF000000) );
00317   }
00318 
00319 
00320   void SplineCurveEditor::DrawContent (GraphicsEngine &GfxContext, bool force_draw)
00321   {
00322 
00323   }
00324 
00325   void SplineCurveEditor::PostDraw (GraphicsEngine &GfxContext, bool force_draw)
00326   {
00327 
00328   }
00329 
00330 
00331   void SplineCurveEditor::SetXAxisBounds (float minX, float maxX)
00332   {
00333     m_minX = minX;
00334     m_maxX = maxX;
00335     QueueDraw();
00336   }
00337 
00338   void SplineCurveEditor::SetYAxisBounds (float minY, float maxY)
00339   {
00340     m_minY = minY;
00341     m_maxY = maxY;
00342     QueueDraw();
00343   }
00344 
00345   void SplineCurveEditor::SetFunctionCallback (SplineFunctionCallback f)
00346   {
00347     m_FunctionCallback = f;
00348     QueueDraw();
00349   }
00350 
00351   float SplineCurveEditor::EvalFunction (float x)
00352   {
00353     if (m_FunctionCallback != 0)
00354       return (*m_FunctionCallback) (x);
00355 
00356     return 0;
00357   }
00358 
00359   void SplineCurveEditor::UpdateGraph()
00360   {
00361     QueueDraw();
00362   }
00363 
00364 
00365 // check if a value lies within a closed interval
00366 #ifndef INSIDE_BOUNDS
00367 #define INSIDE_BOUNDS( x, lo, hi ) ( (x) >= (lo) && (x) <= (hi) )
00368 #endif
00369 
00370 //check if a 2D point lies within a 2D box
00371 #ifndef PT_INSIDE_BOX
00372 #define PT_INSIDE_BOX( x, y, lo_x, hi_x, lo_y, hi_y ) ( INSIDE_BOUNDS(x,lo_x,hi_x) && INSIDE_BOUNDS(y,lo_y,hi_y) )
00373 #endif
00374 
00375   void SplineCurveEditor::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags)
00376   {
00377     QueueDraw();
00378 
00379     if (m_control_knot.GetNumSelectedKnot() > 0)
00380       sigCurveChange.emit (this);
00381   }
00382 
00383   void SplineCurveEditor::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags)
00384   {
00385     int nbKnot = m_control_knot.GetNumKnot();
00386 
00387     if (CTRL_KEY == 0)
00388     {
00389       m_control_knot.UnSelectAllKnot();
00390     }
00391 
00392     int W = GetBaseWidth() - 2 * GRAPH_MARGIN;
00393     int H = GetBaseHeight() - 2 * GRAPH_MARGIN;
00394     int X = GetBaseX() + GRAPH_MARGIN;
00395     int Y = GetBaseY() + GRAPH_MARGIN;
00396 
00397     bool b = PT_INSIDE_BOX (X - GRAPH_MARGIN + x, Y - GRAPH_MARGIN + y, X - GRAPH_MARGIN, X + W + 2 * GRAPH_MARGIN, Y - GRAPH_MARGIN, Y + H + 2 * GRAPH_MARGIN);
00398 
00399     if (b == false)
00400       return;
00401 
00402     X = GetBaseX();
00403     Y = GetBaseY();
00404 
00405     double new_x, new_y;
00406     new_x = (double) (x - GRAPH_MARGIN) / (double) W;
00407     new_y = 1.0 - (double) (y - GRAPH_MARGIN) / (double) H;
00408 
00409     hit_point_dx = 0;
00410     hit_point_dy = 0;
00411 
00412     for (int i = 0; i < nbKnot; i++)
00413     {
00414       int Xp, Yp;
00415       Xp = X + W * (m_control_knot[i].GetX() - m_minX) / (m_maxX - m_minX);
00416       Yp = Y + H * ( 1 - (m_control_knot[i].GetY() - m_minY) / (m_maxY - m_minY) );
00417 
00418       int tx, ty;
00419       tx = X + x - GRAPH_MARGIN;
00420       ty = Y + y - GRAPH_MARGIN;
00421 
00422       if (PT_INSIDE_BOX (tx, ty, Xp - KNOT_HIT_TEST, Xp + KNOT_HIT_TEST, Yp - KNOT_HIT_TEST, Yp + KNOT_HIT_TEST) )
00423       {
00424         hit_point_dx = (tx) - Xp;
00425         hit_point_dy = Yp - (ty);
00426 
00427         m_control_knot.SelectKnot (i, TRUE);
00428         m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00429         QueueDraw();
00430         return;
00431       }
00432     }
00433 
00434     double eval = Eval (new_x);
00435 
00436     if (new_y >= eval - 4.0 / H && (new_y <= eval + 4.0 / H) )
00437     {
00438       m_control_knot.AddKnot (new_x, new_y, TRUE);
00439       m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00440       sigCurveChange.emit (this);
00441       QueueDraw();
00442     }
00443   }
00444 
00445   void SplineCurveEditor::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00446   {
00447     float xp, yp;
00448     int W = GetBaseWidth() - 2 * GRAPH_MARGIN;
00449     int H = GetBaseHeight() - 2 * GRAPH_MARGIN;
00450     int X = GetBaseX() + GRAPH_MARGIN;
00451     int Y = GetBaseY() + GRAPH_MARGIN;
00452     int nbKnot = m_control_knot.GetNumKnot();
00453 
00454     if (nbKnot <= 1)
00455       return;     // no drag when there is not enough knots.
00456 
00457     xp = m_minX + (m_maxX - m_minX) * dx / W;
00458     yp = m_minY + (m_maxY - m_minY) * dy / H;
00459 
00460 
00461 
00462     for (int i = 0; i < nbKnot; i++)
00463     {
00464       if (m_control_knot.isKnotSelected (i) )
00465       {
00466         int tempx, tempy;
00467         tempx = X + x - GRAPH_MARGIN;
00468         tempy = Y + y - GRAPH_MARGIN;
00469 
00470         int Xp, Yp;
00471         Xp = X + W * (m_control_knot[i].GetX() - m_minX) / (m_maxX - m_minX);
00472         Yp = Y + H * ( 1 - (m_control_knot[i].GetY() - m_minY) / (m_maxY - m_minY) );
00473 
00474         if (dx > 0)
00475         {
00476           if (tempx > Xp + hit_point_dx)
00477           {
00478             xp = /*m_minX +*/ (m_maxX - m_minX) * (tempx - Xp - hit_point_dx) / W;
00479           }
00480           else
00481           {
00482             xp = 0;
00483           }
00484         }
00485         else if (dx < 0)
00486         {
00487           if (tempx < Xp + hit_point_dx)
00488           {
00489             xp = /*m_minX +*/ (m_maxX - m_minX) * (tempx - Xp - hit_point_dx) / W;
00490           }
00491           else
00492           {
00493             xp = 0;
00494           }
00495         }
00496 
00497         if (dy > 0)
00498         {
00499           if (tempy > Yp - hit_point_dy)
00500           {
00501             yp = /*m_minY +*/ (m_maxY - m_minY) * (tempy - Yp + hit_point_dy) / H;
00502           }
00503           else
00504           {
00505             yp = 0;
00506           }
00507         }
00508         else if (dy < 0)
00509         {
00510           if (tempy < Yp - hit_point_dy)
00511           {
00512             yp = /*m_minY +*/ (m_maxY - m_minY) * (tempy - Yp + hit_point_dy) / H;
00513           }
00514           else
00515           {
00516             yp = 0;
00517           }
00518         }
00519 
00520         m_control_knot[i].SetX (m_control_knot[i].GetX() + xp);
00521         m_control_knot[i].SetY (m_control_knot[i].GetY() - yp);
00522 
00523         if (m_control_knot[i].GetX() < m_minX)
00524         {
00525           m_control_knot[i].SetX (m_minX);
00526         }
00527 
00528         if (m_control_knot[i].GetX() > m_maxX)
00529         {
00530           m_control_knot[i].SetX (m_maxX);
00531         }
00532 
00533         if (m_control_knot[i].GetY() < m_minY)
00534         {
00535           m_control_knot[i].SetY (m_minY);
00536         }
00537 
00538         if (m_control_knot[i].GetY() > m_maxY)
00539         {
00540           m_control_knot[i].SetY (m_maxY);
00541         }
00542 
00543 
00544         if (i == 0)
00545         {
00546           if ( m_control_knot[i].GetX() > m_control_knot[i + 1].GetX() - 0.01)
00547             m_control_knot[i].SetX (m_control_knot[i + 1].GetX() - 0.01);
00548         }
00549         else if (i == nbKnot - 1)
00550         {
00551           if (m_control_knot[i].GetX() < m_control_knot[i - 1].GetX() + 0.01)
00552           {
00553             m_control_knot[i].SetX (m_control_knot[i - 1].GetX() + 0.01);
00554           }
00555         }
00556         else
00557         {
00558           if (m_control_knot[i].GetX() > m_control_knot[i + 1].GetX() - 0.01)
00559           {
00560             m_control_knot[i].SetX (m_control_knot[i + 1].GetX() - 0.01);
00561           }
00562 
00563           if (m_control_knot[i].GetX() < m_control_knot[i - 1].GetX() + 0.01)
00564           {
00565             m_control_knot[i].SetX (m_control_knot[i - 1].GetX() + 0.01);
00566           }
00567         }
00568 
00569         break;
00570       }
00571     }
00572 
00573     m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00574     QueueDraw();
00575   }
00576 
00577   void SplineCurveEditor::RecvKeyEvent (
00578     unsigned long   eventType  , /*event type*/
00579     unsigned long   keysym     , /*event keysym*/
00580     unsigned long   state      , /*event state*/
00581     const TCHAR*    character  , /*character*/
00582     unsigned short  keyCount     /*key repeat count*/
00583   )
00584   {
00585     if (!HasKeyboardFocus() )
00586     {
00587       return;
00588     }
00589 
00590     if ( (keysym == NUX_VK_DELETE) || (keysym == NUX_VK_DELETE) || (keysym == NUX_VK_BACKSPACE) )
00591     {
00592 
00593       int kn = m_control_knot.GetNumSelectedKnot();
00594 
00595       m_control_knot.EraseSelectedKnot();
00596       m_CubicSpline.Set (m_control_knot.GetNumKnot(), m_control_knot.GetXArray(), m_control_knot.GetYArray() );
00597 
00598       if (kn > 0)
00599         sigCurveChange.emit (this);
00600 
00601       QueueDraw();
00602     }
00603   }
00604 
00605 
00606 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends