2 #include "RampControl.h"
8 #include "../panel/LODInterface.h"
10 using namespace LODGenerator
;
12 /*****************************************************************************************************/
13 CCRampControl::CCRampControl()
16 m_ptLeftDown
= QPoint(0,0);
20 m_movedHandles
= false;
21 m_canMoveSelected
= false;
22 m_mouseMoving
= false;
25 CCRampControl::CCRampControl(QWidget
* qWidget
):QWidget(qWidget
)
28 m_ptLeftDown
= QPoint(0,0);
32 m_movedHandles
= false;
33 m_canMoveSelected
= false;
34 m_mouseMoving
= false;
36 setMouseTracking(true);
39 CCRampControl::~CCRampControl()
44 void CCRampControl::SetStats(RampControlMeshInfo stats
)
46 m_currentStats
= stats
;
49 void CCRampControl::DrawBackground(QPainter
& painter
)
51 CLodGeneratorInteractionManager
* pInstance
= CLodGeneratorInteractionManager::Instance();
52 const int nNumMoves
= pInstance
->GetNumMoves();
56 //pen.setColor(QColor(128,128,128));
57 pen
.setColor(QColor(0,255,0));
60 QRect rc
= this->rect();
61 painter
.setBackgroundMode(Qt::OpaqueMode
);
64 m_selectedError
=-1.0f
;
67 for (int i
=0; i
<nNumMoves
; i
++)
69 m_totalError
+=pInstance
->GetErrorAtMove(i
);
72 if (m_totalError
>0.0f
)
74 m_totalError
=logf(m_totalError
);
81 //pen.setColor(QColor(64,64,64));
82 pen
.setColor(QColor(255,0,255));
85 float bar
=floorf(m_totalError
);
92 lrc.setBottom(lrc.bottom() - (int)(rc.height()*bar/m_totalError));
93 lrc.setTop(lrc.bottom()-1);
95 pen.setColor(QColor(255,0,255));
97 //pen.setColor(QColor(64,64,64));
98 painter.drawRect(lrc);
103 pen
.setColor(QColor(255,255,255));
105 float currentError
=0.0f
;
108 float yScale
=(nNumMoves
>1)?(1.0f
/(float)(nNumMoves
-1)):1.0f
;
109 for (int i
=0; i
<nNumMoves
; i
++)
112 lrc
.setLeft(lrc
.left() + +(int)floorf(rc
.width()*(1.0f
-i
*yScale
)));
113 if (lrc
.left()!=lastX
)
115 lrc
.setRight(lrc
.left() + 1);
116 lrc
.setBottom(rc
.bottom() -(int)(rc
.height()*((currentError
==0.0f
)?0.0f
:logf(currentError
))/m_totalError
));
117 lrc
.setTop(lrc
.bottom()-1);
119 pen
.setColor(QColor(255,255,255));
121 painter
.drawRect(lrc
);
125 HandleData handleData
;
126 if ( GetSelectedData(handleData
) )
128 float selectedPercentage
=handleData
.percentage
;
129 int selected
=(int)floorf(nNumMoves
*(1.0f
-selectedPercentage
/100.0f
)+0.5f
);
132 m_selectedError
=currentError
;
136 currentError
+=pInstance
->GetErrorAtMove(i
);
141 void CCRampControl::DrawForeground(QPainter
& painter
)
145 pen
.setColor(QColor(255,255,255));
147 QRect rc
= this->rect();
148 painter
.setBackgroundMode(Qt::TransparentMode
);
150 HandleData handleData
;
151 if ( GetSelectedData(handleData
) )
153 IStatObj::SStatistics loadedStats
= CLodGeneratorInteractionManager::Instance()->GetLoadedStatistics();
155 int tris
=m_currentStats
.nIndices
/3;
156 int verts
=m_currentStats
.nVertices
;
157 if ( tris
!= 0 && verts
!= 0 )
161 tempValue
= (int)(((float)tris
/ (float)(loadedStats
.nIndices
/3)) * 100.0f
);
162 str
= QString("Tris:%1 ( %2 %)\n").arg(tris
).arg(tempValue
);
163 painter
.drawText(rc
,Qt::AlignRight
| Qt::TextSingleLine
,str
,&ret
);
164 //dc.DrawText(str, rc, DT_RIGHT|DT_SINGLELINE|DT_END_ELLIPSIS);
165 rc
.setTop(rc
.top() + ret
.height());
166 tempValue
= (int)(((float)verts
/ (float)loadedStats
.nVertices
) * 100.0f
);
167 str
= QString("Verts:%1 ( %2 %)\n").arg(verts
).arg(tempValue
);
168 painter
.drawText(rc
,Qt::AlignRight
| Qt::TextSingleLine
,str
,&ret
);
169 rc
.setTop(rc
.top() + ret
.height());
170 str
= QString("Error:%1 \n").arg(m_selectedError
);//arg(QString::number(m_selectedError, 'g', 1));
171 painter
.drawText(rc
,Qt::AlignRight
| Qt::TextSingleLine
,str
,&ret
);
172 //str.Format("Error:%.1f\n", m_selectedError);
176 painter
.setBackgroundMode(Qt::OpaqueMode
);
179 void CCRampControl::DrawFrame(QPainter
& painter
)
181 QRect rect
= this->rect();
184 pen
.setColor(QColor(0,0,0));
187 float x0
= rect
.left();
188 float x1
= rect
.right();
189 float y0
= rect
.top();
190 float y1
= rect
.bottom();
191 line
.setLine(x0
,y0
,x0
,y1
);
192 painter
.drawLine(line
);
193 line
.setLine(x1
,y0
,x1
,y1
);
194 painter
.drawLine(line
);
195 line
.setLine(x0
,y0
,x1
,y0
);
196 painter
.drawLine(line
);
197 line
.setLine(x0
,y1
,x1
,y1
);
198 painter
.drawLine(line
);
202 void CCRampControl::DrawRamp(QPainter
& painter
)
205 DrawBackground(painter
);
207 QRect rect
= this->rect();
210 pen
.setColor(QColor(0,0,0));
216 // x1 = rect.right();
217 // y0 = rect.top() + ((rect.bottom() - rect.top())/2);
219 // line.setLine(x0,y0,x1 - x0,y1 - y0);
220 // painter.drawLine(line);
222 for (int idx
= 0; idx
< 100; ++idx
)
224 x0
= (int)((((float)(rect
.right()-rect
.left()))/100.0f
)*idx
);
225 y0
= rect
.bottom() - 5;//rect.top() + ((rect.bottom() - rect.top())/2) - 5;
235 line
.setLine(x0
,y0
,x1
,y1
);
236 painter
.drawLine(line
);
239 DrawForeground(painter
);
241 // if (GetFocus() == this)
243 // dc.DrawFocusRect(&rect);
248 void CCRampControl::DrawHandle(QPainter
& painter
, const HandleData
& data
)
252 pen
.setColor(QColor(0,0,0));
255 QRect rect
= this->rect();
260 const float pixelsPercent
= ((float)rect
.right() - (float)rect
.left()) / 100.0f
;
262 x0
= (int)(pixelsPercent
* data
.percentage
);
263 data
.flags
& hfSelected
&& m_drawPercentage
? y0
= rect
.top() + 14 : y0
= rect
.top();
268 if ( data
.flags
& hfHotitem
)
270 pen
.setColor(QColor(255,0,0));
274 line
.setLine(x0
,y0
,x1
,y1
);
275 painter
.drawLine(line
);
283 pen
.setColor(QColor(255,255,255));
287 qBrush
.setColor(QColor(255,255,255));
288 qBrush
.setStyle(Qt::SolidPattern
);
289 painter
.setBrush(qBrush
);
291 QRect
qRect(x0
,y0
,x1
- x0
,y1
- y0
);
292 painter
.drawRect(qRect
);
294 if ( data
.flags
& hfSelected
)
296 pen
.setColor(QColor(255,0,0));
298 painter
.drawRect(qRect
);
300 if ( m_drawPercentage
)
302 const QString str
= QString("%1").arg((int)data
.percentage
);;
304 x0
= (int)(pixelsPercent
* data
.percentage
) - 7;
309 const QRectF
qqRect(x0
,y0
,x1
-x0
,y1
-y0
);
310 painter
.setBackgroundMode(Qt::TransparentMode
);
311 painter
.drawText(qqRect
,Qt::AlignCenter
| Qt::TextSingleLine
| Qt::TextDontClip
,str
,NULL
);
312 painter
.setBackgroundMode(Qt::OpaqueMode
);
318 void CCRampControl::paintEvent(QPaintEvent
* ev
)
320 QWidget::paintEvent(ev
);
322 QPainter
painter(this);
323 //----------------------------------------------------------------------------
326 const int handleCount
= m_handles
.size();
327 for (int idx
= 0; idx
< handleCount
; ++idx
)
329 DrawHandle(painter
, m_handles
[idx
]);
332 //----------------------------------------------------------------------------
335 void CCRampControl::OnLButtonDblClk(QPoint point
)
337 float percent
= DeterminePercentage(point
);
338 if ( !HitAnyHandles(percent
) )
340 if ( AddHandle(percent
) )
341 OnLodAdded((int)percent
);
346 void CCRampControl::mousePressEvent(QMouseEvent
*ev
)
348 Qt::MouseButton mouseButton
= ev
->button();
349 QPoint point
= ev
->pos();
350 if (mouseButton
== Qt::LeftButton
)
352 OnLButtonDown(point
);
357 void CCRampControl::mouseReleaseEvent(QMouseEvent
*ev
)
359 Qt::MouseButton mouseButton
= ev
->button();
360 QPoint point
= ev
->pos();
361 if (mouseButton
== Qt::LeftButton
)
368 void CCRampControl::mouseMoveEvent(QMouseEvent
*ev
)
370 QPoint point
= ev
->pos();
374 void CCRampControl::mouseDoubleClickEvent(QMouseEvent
*ev
)
376 Qt::MouseButton mouseButton
= ev
->button();
377 QPoint point
= ev
->pos();
378 if (mouseButton
== Qt::LeftButton
)
380 OnLButtonDblClk(point
);
384 void CCRampControl::keyPressEvent(QKeyEvent
*ev
)
386 OnKeyDown(ev
->nativeScanCode(),ev
->count());
389 void CCRampControl::keyReleaseEvent(QKeyEvent
*ev
)
391 OnKeyUp(ev
->nativeScanCode(),ev
->count());
394 void CCRampControl::OnLButtonDown(QPoint point
)
396 float percent
= DeterminePercentage(point
);
397 if ( HitAnyHandles(percent
) && !(GetKeyState(VK_CONTROL
) & 0x8000) )
399 ClearSelectedHandles();
400 OnSelectionCleared();
403 m_ptLeftDown
= point
;
405 m_canMoveSelected
= IsSelectedHandle(percent
);
409 void CCRampControl::OnLButtonUp(QPoint point
)
411 float percent
= DeterminePercentage(point
);
412 if ( m_movedHandles
== false )
414 if ( !HitAnyHandles(percent
) && !(GetKeyState(VK_CONTROL
) & 0x8000) )
416 ClearSelectedHandles();
417 OnSelectionCleared();
419 else if ( HitAnyHandles(percent
) )
421 if ( IsSelectedHandle(percent
) )
423 DeSelectHandle(percent
);
427 if ( SelectHandle(percent
) )
433 m_ptLeftDown
= QPoint(0,0);
436 m_mouseMoving
= false;
437 m_canMoveSelected
= false;
438 m_movedHandles
= false;
444 void CCRampControl::OnMouseMove(QPoint point
)
446 float abspercent
= DeterminePercentage(point
);
447 SetHotItem(abspercent
);
450 const int handleCount
= m_handles
.size();
451 if ( !m_bLeftDown
|| handleCount
== 0 )
454 if (m_movedHandles
== false && !m_mouseMoving
&& !m_canMoveSelected
)
455 m_canMoveSelected
= SelectHandle(abspercent
);
457 m_mouseMoving
= true;
459 if ( !m_canMoveSelected
)
464 bool modified
= false;
466 QPoint movement
= point
- m_ptLeftDown
;
467 float percent
= DeterminePercentage(movement
);
469 //early out if we hit the edge limits
470 for (int idx
= 0; idx
< handleCount
; ++idx
)
472 if ( m_handles
[idx
].flags
& hfSelected
&& ((movement
.x() < 0 && m_handles
[idx
].percentage
<= 1) || (movement
.x() > 0 && m_handles
[idx
].percentage
>= 99)))
478 if ( movement
.x() > 0)
480 // move the hanldes clamping in direction where required
481 for (int idx
= handleCount
-1; idx
>= 0; --idx
)
483 if ( m_handles
[idx
].flags
& hfSelected
)
485 float amountClamped
= MoveHandle(m_handles
[idx
], percent
);
486 if ( amountClamped
!= 0.0f
)
487 percent
+= amountClamped
;
492 else if (movement
.x() < 0)
494 // move the hanldes clamping in direction where required
495 for (int idx
= 0; idx
< handleCount
; ++idx
)
497 if ( m_handles
[idx
].flags
& hfSelected
)
499 float amountClamped
= MoveHandle(m_handles
[idx
], percent
);
500 if ( amountClamped
!= 0.0f
)
501 percent
+= amountClamped
;
506 m_ptLeftDown
= point
;
510 m_movedHandles
= true;
517 void CCRampControl::OnKeyUp(int nChar
, int nRepCnt
)
522 void CCRampControl::OnKeyDown(int nChar
, int nRepCnt
)
524 if ( nChar
== VK_DELETE
)
526 RemoveSelectedHandles();
530 if ( nChar
== VK_LEFT
)
532 SelectPreviousHandle();
536 if ( nChar
== VK_RIGHT
)
545 void CCRampControl::OnKillFocus()
551 void CCRampControl::contextMenuEvent(QContextMenuEvent
* ev
)
553 m_menuPoint
= ev
->pos();;
554 float percent
= DeterminePercentage(m_menuPoint
);
555 bool hit
= HitAnyHandles(percent
);
556 bool maxed
= GetHandleCount() == GetMaxHandles();
561 QAction
* Act_SelectAll
;
562 QAction
* Act_SelectNone
;
564 Act_Add
= new QAction(tr("Add"), this);
565 Act_Add
->setEnabled(!maxed
);
566 //Act_Add->setIcon(QIcon("Resources/logo.png"));
567 Act_Delete
= new QAction(tr("Delete"), this);
568 Act_Select
= new QAction(tr("Select"), this);
569 Act_SelectAll
= new QAction(tr("Select All"), this);
570 Act_SelectNone
= new QAction(tr("Select None"), this);
572 connect(Act_Add
, SIGNAL(triggered()), this, SLOT(ADDChange()));
573 connect(Act_Delete
, SIGNAL(triggered()), this, SLOT(DeleteChange()));
574 connect(Act_Select
, SIGNAL(triggered()), this, SLOT(SelectChange()));
575 connect(Act_SelectAll
, SIGNAL(triggered()), this, SLOT(SelectAllChange()));
576 connect(Act_SelectNone
, SIGNAL(triggered()), this, SLOT(SelectNoneChange()));
578 QMenu
* menu
= new QMenu();
579 menu
->addAction(Act_Add
);
580 menu
->addSeparator();
581 menu
->addAction(Act_Delete
);
582 menu
->addAction(Act_Select
);
583 menu
->addSeparator();
584 menu
->addAction(Act_SelectAll
);
585 menu
->addAction(Act_SelectNone
);
586 menu
->exec(ev
->globalPos());
591 delete Act_SelectAll
;
592 delete Act_SelectNone
;
595 // void CCRampControl::OnContextMenu(QPoint point)
597 // m_menuPoint = point;
598 // ScreenToClient(&m_menuPoint);
599 // float percent = DeterminePercentage(m_menuPoint);
600 // bool hit = HitAnyHandles(percent);
601 // bool maxed = GetHandleCount() == GetMaxHandles();
604 // CMenu *menu = new CMenu;
605 // menu->CreatePopupMenu();
606 // menu->AppendMenu(!maxed ? MF_STRING : MF_STRING|MF_GRAYED, ID_MENU_ADD, "&Add");
607 // menu->AppendMenu(MF_SEPARATOR,0,"");
608 // menu->AppendMenu(hit ? MF_STRING : MF_STRING|MF_GRAYED, ID_MENU_DELETE, "&Delete");
609 // menu->AppendMenu(hit ? MF_STRING : MF_STRING|MF_GRAYED, ID_MENU_SELECT, "&Select");
610 // menu->AppendMenu(MF_SEPARATOR,0,"");
611 // menu->AppendMenu(MF_STRING, ID_MENU_SELECTALL, "Select A&ll");
612 // menu->AppendMenu(MF_STRING, ID_MENU_SELECTNONE, "Select &None");
613 // AddCustomMenuOptions(menu);
614 // menu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON,point.x,point.y,pWnd);
619 void CCRampControl::ADDChange(bool checked
)
621 float percent
= DeterminePercentage(m_menuPoint
);
622 if ( AddHandle(percent
) )
623 OnLodAdded((int)percent
);
627 void CCRampControl::DeleteChange(bool checked
)
629 ClearSelectedHandles();
630 float percent
= DeterminePercentage(m_menuPoint
);
631 SelectHandle(percent
);
632 RemoveSelectedHandles();
637 void CCRampControl::SelectChange(bool checked
)
639 ClearSelectedHandles();
640 float percent
= DeterminePercentage(m_menuPoint
);
641 SelectHandle(percent
);
646 void CCRampControl::SelectAllChange(bool checked
)
653 void CCRampControl::SelectNoneChange(bool checked
)
655 ClearSelectedHandles();
656 OnSelectionCleared();
660 void CCRampControl::OnSize(int nType
, int cx
, int cy
)
665 float CCRampControl::DeterminePercentage(const QPoint
& point
)
667 QRect rect
= this->rect();
668 float percent
= ((float)(point
.x() - rect
.left()) / (float)(rect
.right()-rect
.left())) * 100.0f
;
672 bool CCRampControl::AddHandle(const float percent
)
674 if (m_handles
.size() >= m_max
)
678 data
.percentage
= percent
;
680 m_handles
.push_back(data
);
686 void CCRampControl::SortHandles()
688 std::sort(m_handles
.begin(),m_handles
.end(),SortHandle
);
691 bool CCRampControl::SortHandle(const CCRampControl::HandleData
& dataA
, const CCRampControl::HandleData
& dataB
)
693 return dataA
.percentage
< dataB
.percentage
;
696 void CCRampControl::ClearSelectedHandles()
698 const int handleCount
= m_handles
.size();
699 for (int idx
= 0; idx
< handleCount
; ++idx
)
701 m_handles
[idx
].flags
&= ~hfSelected
;
705 void CCRampControl::Reset()
710 bool CCRampControl::SelectHandle(const float percent
)
712 const int handleCount
= m_handles
.size();
713 for (int idx
= 0; idx
< handleCount
; ++idx
)
715 if ( HitTestHandle(m_handles
[idx
],percent
) && !(m_handles
[idx
].flags
& hfSelected
) )
717 m_handles
[idx
].flags
|= hfSelected
;
724 bool CCRampControl::DeSelectHandle(const float percent
)
726 const int handleCount
= m_handles
.size();
727 for (int idx
= 0; idx
< handleCount
; ++idx
)
729 if ( HitTestHandle(m_handles
[idx
],percent
) && (m_handles
[idx
].flags
& hfSelected
))
731 m_handles
[idx
].flags
&= ~hfSelected
;
738 bool CCRampControl::IsSelectedHandle(const float percent
)
740 const int handleCount
= m_handles
.size();
741 for (int idx
= 0; idx
< handleCount
; ++idx
)
743 if ( HitTestHandle(m_handles
[idx
],percent
) )
744 if ( m_handles
[idx
].flags
& hfSelected
)
750 void CCRampControl::SelectAllHandles()
752 const int handleCount
= m_handles
.size();
753 for (int idx
= 0; idx
< handleCount
; ++idx
)
755 m_handles
[idx
].flags
|= hfSelected
;
759 float CCRampControl::MoveHandle(HandleData
& data
, const float percent
)
761 float clampedby
= 0.0f
;
762 data
.percentage
+= percent
;
763 if ( data
.percentage
< 0.0f
)
765 clampedby
= -data
.percentage
;
766 data
.percentage
= 0.0f
;
769 if ( data
.percentage
> 99.99f
)
771 clampedby
= -(data
.percentage
- 99.0f
);
772 data
.percentage
= 99.0f
;
777 bool CCRampControl::HitAnyHandles(const float percent
)
779 const int handleCount
= m_handles
.size();
780 for (int idx
= 0; idx
< handleCount
; ++idx
)
782 if ( HitTestHandle(m_handles
[idx
],percent
) )
788 bool CCRampControl::HitTestHandle(const HandleData
& data
, const float percent
)
790 if ( percent
> data
.percentage
-1 && percent
< data
.percentage
+1 )
795 bool CCRampControl::CheckSelected(const CCRampControl::HandleData
& data
)
797 return data
.flags
& CCRampControl::hfSelected
;
800 void CCRampControl::RemoveSelectedHandles()
802 m_handles
.erase(remove_if(m_handles
.begin(),m_handles
.end(),CCRampControl::CheckSelected
),m_handles
.end());
806 void CCRampControl::SelectNextHandle()
808 bool selected
= false;
809 const int count
= m_handles
.size();
810 for ( int idx
= count
-1; idx
>= 0; --idx
)
812 if ( (m_handles
[idx
].flags
& hfSelected
) && ( idx
+1 < count
) )
814 m_handles
[idx
+1].flags
|= hfSelected
;
817 m_handles
[idx
].flags
&= ~hfSelected
;
820 if ( selected
== false && count
> 0 )
822 m_handles
[0].flags
|= hfSelected
;
826 void CCRampControl::SelectPreviousHandle()
828 bool selected
= false;
829 const int count
= m_handles
.size();
830 for ( int idx
= 0; idx
< count
; ++idx
)
832 if ( (m_handles
[idx
].flags
& hfSelected
) && ( idx
-1 >= 0) )
834 m_handles
[idx
-1].flags
|= hfSelected
;
837 m_handles
[idx
].flags
&= ~hfSelected
;
840 if ( selected
== false && count
> 0 )
842 m_handles
[count
-1].flags
|= hfSelected
;
847 /*************************************************************************************/
848 const bool CCRampControl::GetSelectedData(CCRampControl::HandleData
& data
)
850 const int handleCount
= m_handles
.size();
851 for (int idx
= 0; idx
< handleCount
; ++idx
)
853 if ( m_handles
[idx
].flags
& hfSelected
)
855 data
= m_handles
[idx
];
862 const int CCRampControl::GetHandleCount()
864 return m_handles
.size();
867 const CCRampControl::HandleData
CCRampControl::GetHandleData(const int idx
)
869 return m_handles
[idx
];
872 const int CCRampControl::GetHotHandleIndex()
874 const int count
= m_handles
.size();
875 for ( int idx
= 0; idx
< count
; ++idx
)
877 if ( m_handles
[idx
].flags
& hfHotitem
)
885 void CCRampControl::SetHotItem(const float percentage
)
887 const int count
= m_handles
.size();
888 for ( int idx
= 0; idx
< count
; ++idx
)
890 if ( HitTestHandle(m_handles
[idx
],percentage
) )
892 m_handles
[idx
].flags
|= hfHotitem
;
896 m_handles
[idx
].flags
&= ~hfHotitem
;