// CurveEditor.cpp : implementation file // #include "stdafx.h" #include "pixelwhippro.h" #include "CurveEditor.h" #include "EffectEditWin.h" #include "TreeParamView.h" #include "DataParamView.h" #include "CurveSet.h" #include extern CPixelWhipProApp theApp; extern gosFX::Effect *CurrentEffect; #define LINEDIVS 30 #define HANDLELEN 5 ///////////////////////////////////////////////////////////////////////////// // CCurveEditor //IMPLEMENT_DYNCREATE(CCurveEditor, CWnd) CCurveEditor::CCurveEditor() { CurrentEditMode=MOVE; EditHan=EditVar=false; StartY=-100; EndY=100; NumCurves=0; DCurve=VCurve=NULL; CurrentCSet=NULL; SelectedKey=-1; } CCurveEditor::~CCurveEditor() { } BEGIN_MESSAGE_MAP(CCurveEditor, CWnd) //{{AFX_MSG_MAP(CCurveEditor) ON_WM_CLOSE() ON_WM_PAINT() ON_COMMAND(ID_EDIT_INSERTMODE, OnEditInsertmode) ON_COMMAND(ID_EDIT_MOVEMODE, OnEditMovemode) ON_COMMAND(ID_EDIT_PANMODE, OnEditPanmode) ON_COMMAND(ID_EDIT_SCALEMODE, OnEditScalemode) ON_COMMAND(ID_EDIT_ZOOMMODE, OnEditZoommode) ON_UPDATE_COMMAND_UI(ID_EDIT_INSERTMODE, OnUpdateEditInsertmode) ON_UPDATE_COMMAND_UI(ID_EDIT_MOVEMODE, OnUpdateEditMovemode) ON_UPDATE_COMMAND_UI(ID_EDIT_PANMODE, OnUpdateEditPanmode) ON_UPDATE_COMMAND_UI(ID_EDIT_SCALEMODE, OnUpdateEditScalemode) ON_UPDATE_COMMAND_UI(ID_EDIT_ZOOMMODE, OnUpdateEditZoommode) ON_COMMAND(ID_EDIT_EDITVARAINCECURVE, OnEditEditvaraincecurve) ON_UPDATE_COMMAND_UI(ID_EDIT_EDITVARAINCECURVE, OnUpdateEditEditvaraincecurve) ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_COMMAND(ID_EDIT_DELETEVERTEX, OnEditDeletevertex) ON_COMMAND(ID_VIEW_ZOOMTOCURVE, OnViewZoomtocurve) ON_WM_CREATE() ON_WM_KEYDOWN() ON_WM_SIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCurveEditor message handlers void CCurveEditor::OnClose() { ShowWindow(SW_HIDE); // CWnd::OnClose(); } void CCurveEditor::Refresh() { SelectedKey=-1; ReDraw(); } void CCurveEditor::OnPaint() { CPaintDC dc(this); // device context for painting ReDrawInternal(); } void CCurveEditor::DrawHandles(CDC *dc,gosFX::Curve *curve) { CRect crct; GetClientRect(&crct); int hlen=crct.Width()m_type) { case gosFX::Curve::e_SplineType: { gosFX::SplineCurve *SCurve=(gosFX::SplineCurve *)curve; double ang; float slp; lpt.x=0; lpt.y=CurveToClient(SCurve->ComputeValue(0.0f,0.0f),crct.Height()); dc->MoveTo(lpt); slp=SCurve->ComputeSlope(0.0f); slp=(float)(CurveToClient(slp,crct.Height())-CurveToClient(0.0f,crct.Height()))/crct.Width(); ang=atan(slp); lpt.x+=(int)((float)hlen*cos(ang)); lpt.y+=(int)((float)hlen*sin(ang)); H1Pos=lpt; dc->LineTo(lpt); dc->Ellipse(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); lpt.x=crct.Width(); lpt.y=CurveToClient(SCurve->ComputeValue(1.0f,0.0f),crct.Height()); dc->MoveTo(lpt); slp=SCurve->ComputeSlope(1.0f); slp=(float)(CurveToClient(slp,crct.Height())-CurveToClient(0.0f,crct.Height()))/crct.Width(); ang=atan(slp); lpt.x-=(int)(hlen*cos(ang)); lpt.y-=(int)(hlen*sin(ang)); H2Pos=lpt; dc->LineTo(lpt); dc->Ellipse(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } break; case gosFX::Curve::e_ComplexType: { gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)curve; Stuff::Scalar tme; tme=(*SCurve)[SCurve->GetKeyCount()-1].m_time; lpt.x=(int)(tme*crct.Width()); lpt.y=CurveToClient(SCurve->ComputeValue(tme,0.0f),crct.Height()); dc->MoveTo(lpt); lpt.x=crct.Width(); lpt.y=CurveToClient(SCurve->ComputeValue(1.0f,0.0f),crct.Height()); H1Pos=lpt; dc->LineTo(lpt); dc->Ellipse(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } break; default: break; } } } void CCurveEditor::DrawCurve(CDC *dc,gosFX::Curve *curve,bool DrawKeys) { CRect crct; GetClientRect(&crct); Check_Object(curve); switch(curve->m_type) { case gosFX::Curve::e_ConstantType: { CPoint lpt; gosFX::ConstantCurve *SCurve=(gosFX::ConstantCurve *)curve; lpt.x=0; lpt.y=CurveToClient(SCurve->m_value,crct.Height()); if(DrawKeys) { dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } dc->MoveTo(lpt); lpt.x=crct.Width(); dc->LineTo(lpt); } break; case gosFX::Curve::e_LinearType: { CPoint lpt; gosFX::LinearCurve *SCurve=(gosFX::LinearCurve *)curve; lpt.x=0; lpt.y=CurveToClient(SCurve->ComputeValue(0.0f,0.0f),crct.Height()); if(DrawKeys) { dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } dc->MoveTo(lpt); lpt.x=crct.Width(); lpt.y=CurveToClient(SCurve->ComputeValue(1.0f,0.0f),crct.Height()); dc->LineTo(lpt); } break; case gosFX::Curve::e_SplineType: { gosFX::SplineCurve *SCurve=(gosFX::SplineCurve *)curve; CPoint lpt; if(DrawKeys) { lpt.x=0; lpt.y=CurveToClient(SCurve->ComputeValue(0.0f,0.0f),crct.Height()); dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); lpt.x=crct.Width(); lpt.y=CurveToClient(SCurve->ComputeValue(1.0f,0.0f),crct.Height()); dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } lpt.x=0; lpt.y=CurveToClient(SCurve->ComputeValue(0.0f,0.0f),crct.Height()); float finc,linelen=1.0f/LINEDIVS; dc->MoveTo(lpt); for(finc=linelen;finc<=1.0f;finc+=linelen) { lpt.x=(long)(finc*crct.Width()); lpt.y=CurveToClient(SCurve->ComputeValue(finc,0.0f),crct.Height()); dc->LineTo(lpt); } lpt.x=crct.Width(); lpt.y=CurveToClient(SCurve->ComputeValue(1.0f,0.0f),crct.Height()); dc->LineTo(lpt); } break; case gosFX::Curve::e_ComplexType: { gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)curve; int key; float st,finc,linelen=1.0f/LINEDIVS,nextx=0.0f; CPoint lpt,pt; if(DrawKeys) { for(key=0;keyGetKeyCount();key++) { st=(*SCurve)[key].m_time; lpt.x=(long)(st*crct.Width()); lpt.y=CurveToClient(SCurve->ComputeValue(st,0.0f),crct.Height()); dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } } lpt.x=0; lpt.y=CurveToClient(SCurve->ComputeValue(0.0,0.0f),crct.Height()); key=1; for(finc=0.0f;finc<=1.0f;finc+=linelen) { if(keyGetKeyCount()) { st=(*SCurve)[key].m_time; if(finc>st) { finc=st; key++; } else { if(st-fincComputeValue(finc,0.0f),crct.Height()); dc->MoveTo(lpt); dc->LineTo(pt); lpt=pt; if(finc<1.0f && (finc+linelen)>1.0f) finc-=linelen; //cap end } } break; default: break; } } void CCurveEditor::OnEditInsertmode() { CurrentEditMode=INSERT; } void CCurveEditor::OnEditMovemode() { CurrentEditMode=MOVE; } void CCurveEditor::OnEditPanmode() { CurrentEditMode=PAN; } void CCurveEditor::OnEditScalemode() { CurrentEditMode=SCALE; } void CCurveEditor::OnEditZoommode() { CurrentEditMode=ZOOM; } void CCurveEditor::OnUpdateEditInsertmode(CCmdUI* pCmdUI) { pCmdUI->SetCheck(CurrentEditMode==INSERT?1:0); } void CCurveEditor::OnUpdateEditMovemode(CCmdUI* pCmdUI) { pCmdUI->SetCheck(CurrentEditMode==MOVE?1:0); } void CCurveEditor::OnUpdateEditPanmode(CCmdUI* pCmdUI) { pCmdUI->SetCheck(CurrentEditMode==PAN?1:0); } void CCurveEditor::OnUpdateEditScalemode(CCmdUI* pCmdUI) { pCmdUI->SetCheck(CurrentEditMode==SCALE?1:0); } void CCurveEditor::OnUpdateEditZoommode(CCmdUI* pCmdUI) { pCmdUI->SetCheck(CurrentEditMode==ZOOM?1:0); } void CCurveEditor::OnEditEditvaraincecurve() { EditVar=!EditVar; SelectedKey=-1; ReDraw(); } void CCurveEditor::OnUpdateEditEditvaraincecurve(CCmdUI* pCmdUI) { pCmdUI->SetCheck(EditVar?1:0); } void CCurveEditor::OnLButtonUp(UINT nFlags, CPoint point) { switch(CurrentEditMode) { case INSERT: break; case MOVE: ReleaseCapture(); break; case PAN: ReleaseCapture(); break; case SCALE: ReleaseCapture(); break; case ZOOM: ReleaseCapture(); break; } CWnd::OnLButtonUp(nFlags, point); } void CCurveEditor::OnMouseMove(UINT nFlags, CPoint point) { if(nFlags&MK_LBUTTON) { CRect rct; GetClientRect(&rct); switch(CurrentEditMode) { case INSERT: break; case MOVE: { gosFX::Curve *Curve=EditVar?VCurve:DCurve; if(Curve) { Check_Object(Curve); Stuff::DynamicMemoryStream stream; if(CurrentCSet) CurrentCSet->PushState(); Stuff::Scalar newy; newy=ClientToCurve(point.y,rct.Height()); switch(Curve->m_type) { case gosFX::Curve::e_ConstantType: { gosFX::ConstantCurve *SCurve=(gosFX::ConstantCurve *)Curve; SCurve->SetCurve(newy); } break; case gosFX::Curve::e_LinearType: { gosFX::LinearCurve *SCurve=(gosFX::LinearCurve *)Curve; Stuff::Scalar v0,v1; v0=SCurve->ComputeValue(0.0f,0.0f); v1=SCurve->ComputeValue(1.0f,0.0f); if(SelectedKey<0) v0=newy; else v1=newy; SCurve->SetCurve(v0,v1); } break; case gosFX::Curve::e_SplineType: { gosFX::SplineCurve *SCurve=(gosFX::SplineCurve *)Curve; Stuff::Scalar v0,v1,s0,s1; v0=SCurve->ComputeValue(0.0f,0.0f); v1=SCurve->ComputeValue(1.0f,0.0f); s0=SCurve->ComputeSlope(0.0f); s1=SCurve->ComputeSlope(1.0f); if(EditHan) { float cx=(float)point.x/rct.Width(); if(cx<0.00000001f || fabs(cx-1.0f)<0.00000001f) return; if(SelectedKey<0) s0=(newy-SCurve->ComputeValue(0.0f,0.0f))/cx; else s1=-((newy-SCurve->ComputeValue(1.0f,0.0f))/(1.0f-cx)); } else { if(SelectedKey<0) v0=newy; else v1=newy; } SCurve->SetCurve(v0,s0,v1,s1); } break; case gosFX::Curve::e_ComplexType: if(SelectedKey>=0) { gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)Curve; if(EditHan) { Stuff::Scalar val,tme,ntme; tme=(*SCurve)[SCurve->GetKeyCount()-1].m_time; val=(*SCurve)[SCurve->GetKeyCount()-1].m_value; ntme=((float)point.x/rct.Width()); if(point.x<(tme*rct.Width()) || (ntme-tme)<0.000001f) return; (*SCurve)[SCurve->GetKeyCount()-1].SetLinearKey(tme,val,newy,ntme-tme); } else { Stuff::Scalar tme,slp; int MinX,MaxX; if(SelectedKey==0) MinX=0; else MinX=(int)ceil((*SCurve)[SelectedKey-1].m_time*rct.Width())+1; if(SelectedKey==SCurve->GetKeyCount()-1) MaxX=rct.Width(); else MaxX=(int)floor((*SCurve)[SelectedKey+1].m_time*rct.Width())-1; int xval=point.x; xval=xvalMaxX?MaxX:xval; // slp=(*SCurve)[SelectedKey].m_slope; slp=SCurve->ComputeValue(1.0f,0.0f); tme=(float)xval/rct.Width(); if(tme<1.0f) { (*SCurve)[SelectedKey].SetLinearKey(tme,newy,slp,1.0f-tme); } } } break; default: break; } //end of cs type FixCurve(Curve); if(CurrentCSet) CurrentCSet->VerifyAndPop(); theApp.ParamWin->DataPane->UpdateControls(); ReDraw(); }//end of If Curve } break; case PAN: { float add; add=((point.y-OldPoint.y)*(EndY-StartY))/rct.Height(); StartY+=add; EndY+=add; ReDraw(); } break; case SCALE: { gosFX::Curve *Curve=EditVar?VCurve:DCurve; if(Curve) { Check_Object(Curve); Stuff::DynamicMemoryStream stream; if(CurrentCSet) CurrentCSet->PushState(); float perchange; perchange=(float)pow((EndY-StartY)/2,(float)(OldPoint.y-point.y)/rct.Height()); Curve->AxisScale(perchange,0.0f); theApp.ParamWin->DataPane->UpdateControls(); ReDraw(); if(CurrentCSet) CurrentCSet->VerifyAndPop(); } } break; case ZOOM: { float perchange,add; perchange=(float)pow(4.0,(float)(point.y-OldPoint.y)/rct.Height()); add=(EndY-StartY)*(1.0f-perchange); StartY+=add; EndY-=add; ReDraw(); } break; } OldPoint=point; } CWnd::OnMouseMove(nFlags, point); } void CCurveEditor::OnLButtonDown(UINT nFlags, CPoint point) { OldPoint=point; switch(CurrentEditMode) { case INSERT: { CRect crct; GetClientRect(&crct); Stuff::DynamicMemoryStream stream; if(CurrentCSet) CurrentCSet->PushState(); gosFX::Curve *Curve=EditVar?VCurve:DCurve; if(Curve && Curve->m_type==gosFX::Curve::e_ComplexType) { Check_Object(Curve); gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)Curve; SelectedKey=SCurve->InsertKey((float)point.x/crct.Width()); } if(CurrentCSet) CurrentCSet->VerifyAndPop(); theApp.Modified=true; ReDraw(); } break; case MOVE: SetCapture(); SelectedKey=GetClosestKey(point); ReDraw(); theApp.Modified=true; break; case PAN: SetCapture(); break; case SCALE: SetCapture(); theApp.Modified=true; break; case ZOOM: SetCapture(); break; } CWnd::OnLButtonDown(nFlags, point); } void CCurveEditor::UpdateCurveList(HTREEITEM itm) { if(itm==NULL) return; if(itm!=TVI_ROOT) { CurveSet *CSet=(CurveSet *)theApp.ParamWin->TreePane->m_PTree.GetItemData(itm); gosFX::Curve *curve; if(CSet) curve=CSet->Curve; else curve=NULL; if(curve) { Check_Object(curve); if(!DCurve && theApp.ParamWin->TreePane->m_PTree.GetSelectedItem()==itm) { CurrentCSet=CSet; DCurve=curve->GetSubCurve(0); VCurve=curve->GetSubCurve(1); EditHan=false; } else if(theApp.ParamWin->TreePane->m_PTree.GetCheck(itm)) { Curves[NumCurves++]=curve->GetSubCurve(0); Verify(NumCurvesTreePane->m_PTree.GetChildItem(itm); while(nitm!=NULL) { UpdateCurveList(nitm); nitm=theApp.ParamWin->TreePane->m_PTree.GetNextSiblingItem(nitm); } if(itm==TVI_ROOT) ReDraw(); } int CCurveEditor::GetClosestKey(CPoint &pnt) { int i; CRect crct; GetClientRect(&crct); int kx,ky; int dist,lval=crct.Width()*crct.Width()+crct.Height()*crct.Height(); int lnum=0; gosFX::Curve *Curve=EditVar?VCurve:DCurve; if(!Curve) return -1; Check_Object(Curve); switch(Curve->m_type) { case gosFX::Curve::e_ConstantType: { gosFX::ConstantCurve *SCurve=(gosFX::ConstantCurve *)Curve; return -1; } break; case gosFX::Curve::e_LinearType: { gosFX::LinearCurve *SCurve=(gosFX::LinearCurve *)Curve; if(pnt.xComputeValue(0.0f,0.0f),crct.Height())); dist=pnt.x*pnt.x+tval*tval; tval=(int)(pnt.y-CurveToClient(SCurve->ComputeValue(1.0f,0.0f),crct.Height())); tdist=(pnt.x-crct.Width())*(pnt.x-crct.Width())+tval*tval; if(tdistComputeValue(1.0f,0.0f),crct.Height()); lval=(pnt.x-kx)*(pnt.x-kx)+(pnt.y-ky)*(pnt.y-ky); lnum=-1; for(i=0;iGetKeyCount();i++) { kx=(int)((*SCurve)[i].m_time*crct.Width()); ky=(int)CurveToClient(SCurve->ComputeValue((*SCurve)[i].m_time,0.0f),crct.Height()); dist=(pnt.x-kx)*(pnt.x-kx)+(pnt.y-ky)*(pnt.y-ky); if(distGetKeyCount()-1; } else { EditHan=false; return lnum; } } break; default: break; } return -1; } void CCurveEditor::OnEditDeletevertex() { gosFX::Curve *Curve=EditVar?VCurve:DCurve; if(!Curve || Curve->m_type!=gosFX::Curve::e_ComplexType) return; gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)Curve; if(SelectedKey>0) { float cfx,cfy; cfx=(*SCurve)[SelectedKey].m_time; cfy=SCurve->ComputeValue(cfx,0.0f); SCurve->DeleteKey(SelectedKey); CRect crct; GetClientRect(&crct); SelectedKey=GetClosestKey(CPoint((long)(cfx*crct.Width()),CurveToClient(cfy,crct.Height()))); FixCurve(Curve); } else { int i; for(i=1;iGetKeyCount();i++) SCurve->DeleteKey(i); FixCurve(Curve); } ReDraw(); } void CCurveEditor::FixCurve(gosFX::Curve *Curve) { switch(Curve->m_type) { case gosFX::Curve::e_SplineType: { gosFX::SplineCurve *SCurve=(gosFX::SplineCurve *)Curve; } break; case gosFX::Curve::e_ComplexType: { gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)Curve; Stuff::Scalar cval,nval,ctme,ntme; if(SCurve->GetKeyCount()==1) { cval=(*SCurve)[0].m_value; nval=SCurve->ComputeValue(1.0f,0.0f); (*SCurve)[0].SetLinearKey(0.0f,cval,nval,1.0f); } else { cval=(*SCurve)[0].m_value; (*SCurve)[0].SetLinearKey(0.0f,cval,cval,0.01f); } // Connect the Keys int key; for(key=0;keyGetKeyCount()-1;key++) { ctme=(*SCurve)[key].m_time; ntme=(*SCurve)[key+1].m_time; cval=(*SCurve)[key].m_value; nval=(*SCurve)[key+1].m_value; (*SCurve)[key].SetLinearKey(ctme,cval,nval,ntme-ctme); } } break; default: break; } } void CCurveEditor::OnViewZoomtocurve() { gosFX::Curve *Curve=EditVar?VCurve:DCurve; if(Curve==NULL) { StartY=-100.0f; EndY=100.0f; return; } Curve->ExpensiveComputeRange(&StartY,&EndY); float aval; aval=(float)fabs(StartY); aval=(float)fabs(EndY)>aval?(float)fabs(EndY):aval; aval+=aval*0.2f; StartY=-aval; EndY=aval; /* if(StartY==EndY) { StartY-=.5; EndY+=.5; } else { EndY+=(EndY-StartY)*0.1f; StartY-=(EndY-StartY)*0.1f; } */ ReDraw(); } void CCurveEditor::DrawTicks(CDC *dc) { float cury,nexty; int Ccury,Cnexty; CRect rct; GetClientRect(&rct); dc->SelectObject(&TickPen); CString lab; CRect textrect; dc->SetTextColor(0xffffff); dc->SetBkColor(0x000000); if(StartY<0) { cury=-StartY; cury=(float)pow(10,(int)log10(cury)); Ccury=CurveToClient(-cury,rct.Height()); nexty=cury*0.1f; Cnexty=CurveToClient(-nexty,rct.Height()); while((Ccury-Cnexty)>3 && Ccury>0 && -curyMoveTo(0,Ccury); dc->LineTo(rct.Width(),Ccury); lab.Format("%5.3f",-cury); textrect.top=Ccury-10; textrect.left=0; textrect.bottom=Ccury+10; textrect.right=100; dc->DrawText(lab,&textrect,DT_LEFT ); cury=nexty; Ccury=Cnexty; nexty=cury*0.1f; Cnexty=CurveToClient(-nexty,rct.Height()); } } if(EndY>0) { cury=EndY; cury=(float)pow(10,(int)log10(cury)); Ccury=CurveToClient(cury,rct.Height()); nexty=cury*0.1f; Cnexty=CurveToClient(nexty,rct.Height()); while((Cnexty-Ccury)>3 && CcuryStartY) { dc->MoveTo(0,Ccury); dc->LineTo(rct.Width(),Ccury); lab.Format("%5.3f",cury); textrect.top=Ccury-10; textrect.left=0; textrect.bottom=Ccury+10; textrect.right=100; dc->DrawText(lab,&textrect,DT_LEFT ); cury=nexty; Ccury=Cnexty; nexty=cury*0.1f; Cnexty=CurveToClient(nexty,rct.Height()); } } dc->SelectObject(&ZeroPen); dc->MoveTo(0,CurveToClient(0,rct.Height())); dc->LineTo(rct.Width(),CurveToClient(0,rct.Height())); } BOOL CCurveEditor::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } int CCurveEditor::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; LOGBRUSH lb; lb.lbColor=0x00C800; lb.lbStyle=BS_SOLID; InactivePen.CreatePen(PS_SOLID,1,&lb); lb.lbColor=0x7f7f7f; lb.lbStyle=BS_SOLID; TickPen.CreatePen(PS_DASHDOT,1,&lb); lb.lbColor=0x00ffff; lb.lbStyle=BS_SOLID; ZeroPen.CreatePen(PS_DOT,1,&lb); EditablePen.CreatePen(PS_SOLID,1,0x0000ff); VarPen.CreatePen(PS_SOLID,1,0xff0000); SelVertPen.CreatePen(PS_SOLID,1,0x00ff00); BlackPen.CreatePen(PS_SOLID,1,(COLORREF)0x000000); HandlePen.CreatePen(PS_SOLID,1,(COLORREF)0xff00ff); BGBrush.CreateSolidBrush(0xC8C8C8); return 0; } void CCurveEditor::ReDrawInternal() { if(theApp.ParamWin) { CDC *dc,*pDC=GetDC(); theApp.AllowDraw=false; CDC bbufDC; bbufDC.CreateCompatibleDC(pDC); bbufDC.SelectObject(BackBuffer); CRect crct; GetClientRect(&crct); // dc->SelectObject(&BGBrush); // dc->Rectangle(crct); /* static bool flip=false; flip=!flip; pDC->BitBlt(0,0,crct.Width(),crct.Height(),NULL,0,0,flip?BLACKNESS:WHITENESS); */ dc=&bbufDC; // dc=pDC; dc->BitBlt(0,0,crct.Width(),crct.Height(),NULL,0,0,BLACKNESS); int i; dc->SelectObject(GetStockObject(NULL_BRUSH)); DrawTicks(dc); dc->SelectObject(&InactivePen); for(i=0;iSelectObject(&EditablePen); DrawCurve(dc,DCurve); } if(VCurve) { dc->SelectObject(&VarPen); DrawCurve(dc,VCurve,true); } } else { if(VCurve) { dc->SelectObject(&VarPen); DrawCurve(dc,VCurve); } if(DCurve) { dc->SelectObject(&EditablePen); DrawCurve(dc,DCurve,true); } } gosFX::Curve *Curve=EditVar?VCurve:DCurve; //DrawHandles dc->SelectObject(&HandlePen); DrawHandles(dc,Curve); //OverDrawSelected Key dc->SelectObject(&SelVertPen); if(Curve) { Check_Object(Curve); switch(Curve->m_type) { case gosFX::Curve::e_ComplexType: { gosFX::ComplexCurve *SCurve=(gosFX::ComplexCurve *)Curve; if(SelectedKey>=SCurve->GetKeyCount()) SelectedKey=-1; if(SelectedKey!=-1) { float st=(*SCurve)[SelectedKey].m_time; CPoint lpt; lpt.x=(long)(st*crct.Width()); lpt.y=CurveToClient(SCurve->ComputeValue(st,0.0f),crct.Height()); dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } } break; default: if(SelectedKey<0) { CPoint lpt; lpt.x=0; lpt.y=CurveToClient(Curve->ExpensiveCompute(0.0f),crct.Height()); dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } else { CPoint lpt; lpt.x=crct.Width(); lpt.y=CurveToClient(Curve->ExpensiveCompute(1.0f),crct.Height()); dc->Rectangle(lpt.x-5,lpt.y-5,lpt.x+5,lpt.y+5); } break; } } theApp.AllowDraw=true; pDC->BitBlt(crct.left,crct.top,crct.Width(),crct.Height(),&bbufDC,0,0,SRCCOPY); ReleaseDC(pDC); } } void CCurveEditor::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default switch(nChar) { case 'E': OnEditMovemode(); break ; case 'A': OnEditInsertmode(); break ; case 'Z': OnEditZoommode(); break ; case ' ': OnEditPanmode(); break ; case 'S': OnEditScalemode(); break ; case 'V': OnEditEditvaraincecurve(); break ; case 'F': OnViewZoomtocurve(); break ; case 'D': OnEditDeletevertex(); break ; } CWnd::OnKeyDown(nChar, nRepCnt, nFlags); } void CCurveEditor::BuildBackBuffer() { BackBuffer.DeleteObject(); CRect crect; GetClientRect(&crect); CDC *pDC=GetDC(); BackBuffer.CreateCompatibleBitmap(pDC,crect.Width(),crect.Height()); ReleaseDC(pDC); } void CCurveEditor::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); BuildBackBuffer(); // TODO: Add your message handler code here }