| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- // VisErrorReportDialog.cpp : implementation file
- //
- #include "StdAfx.H"
- #include "LevelEdit.H"
- #include "VisErrorReportDialog.H"
- #include "Utils.H"
- #include "VisLog.H"
- #include "SceneEditor.H"
- #include "CameraMgr.H"
- #include "phys.h"
- #include "rendobj.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- //
- // Constants
- //
- /////////////////////////////////////////////////////////////////////////////
- static const int AXIS_BMP_WIDTH = 65;
- static const int AXIS_BMP_HEIGHT = 65;
- /////////////////////////////////////////////////////////////////////////////
- //
- // Local Inlines
- //
- /////////////////////////////////////////////////////////////////////////////
- static inline HBITMAP Load_Bitmap (UINT res_id)
- {
- return (HBITMAP)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (res_id), IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT);
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // VisErrorReportDialogClass
- //
- /////////////////////////////////////////////////////////////////////////////
- VisErrorReportDialogClass::VisErrorReportDialogClass (CWnd *pParent)
- : m_CurrentPoint (0),
- m_GraphArea (0, 0, 0, 0),
- m_AxisArea (0, 0, 0, 0),
- m_CurrentMinPoint (0),
- m_CurrentMaxPoint (0),
- m_TotalPoints (0),
- m_bTrackingSel (false),
- m_TrackPixel (0),
- m_SelStartIndex (0),
- m_SelEndIndex (0),
- m_AxisBMP (NULL),
- m_AxisSelBMP (NULL),
- m_AxisSel (0),
- CDialog(VisErrorReportDialogClass::IDD, pParent)
- {
- //{{AFX_DATA_INIT(VisErrorReportDialogClass)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
- m_PrevButton.normal = Load_Bitmap (IDB_LT_ARROW);
- m_PrevButton.disabled = Load_Bitmap (IDB_LT_ARROW_D);
- m_NextButton.normal = Load_Bitmap (IDB_RT_ARROW);
- m_NextButton.disabled = Load_Bitmap (IDB_RT_ARROW_D);
- m_AxisBMP = Load_Bitmap (IDB_AXIS_BMP);
- m_AxisSelBMP = Load_Bitmap (IDB_AXIS_SEL_BMP);
- m_AxisSelAreas[VIS_FORWARD].left = 1;
- m_AxisSelAreas[VIS_FORWARD].top = 38;
- m_AxisSelAreas[VIS_FORWARD].right = m_AxisSelAreas[VIS_FORWARD].left + 20;
- m_AxisSelAreas[VIS_FORWARD].bottom = m_AxisSelAreas[VIS_FORWARD].top + 16;
- m_AxisSelAreas[VIS_LEFT].left = 1;
- m_AxisSelAreas[VIS_LEFT].top = 12;
- m_AxisSelAreas[VIS_LEFT].right = m_AxisSelAreas[VIS_LEFT].left + 20;
- m_AxisSelAreas[VIS_LEFT].bottom = m_AxisSelAreas[VIS_LEFT].top + 16;
- m_AxisSelAreas[VIS_BACKWARDS].left = 42;
- m_AxisSelAreas[VIS_BACKWARDS].top = 13;
- m_AxisSelAreas[VIS_BACKWARDS].right = m_AxisSelAreas[VIS_BACKWARDS].left + 20;
- m_AxisSelAreas[VIS_BACKWARDS].bottom = m_AxisSelAreas[VIS_BACKWARDS].top + 16;
-
- m_AxisSelAreas[VIS_RIGHT].left = 42;
- m_AxisSelAreas[VIS_RIGHT].top = 39;
- m_AxisSelAreas[VIS_RIGHT].right = m_AxisSelAreas[VIS_RIGHT].left + 20;
- m_AxisSelAreas[VIS_RIGHT].bottom = m_AxisSelAreas[VIS_RIGHT].top + 16;
- m_AxisSelAreas[VIS_UP].left = 21;
- m_AxisSelAreas[VIS_UP].top = 1;
- m_AxisSelAreas[VIS_UP].right = m_AxisSelAreas[VIS_UP].left + 20;
- m_AxisSelAreas[VIS_UP].bottom = m_AxisSelAreas[VIS_UP].top + 16;
- m_AxisSelAreas[VIS_DOWN].left = 22;
- m_AxisSelAreas[VIS_DOWN].top = 47;
- m_AxisSelAreas[VIS_DOWN].right = m_AxisSelAreas[VIS_DOWN].left + 20;
- m_AxisSelAreas[VIS_DOWN].bottom = m_AxisSelAreas[VIS_DOWN].top + 16;
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // ~VisErrorReportDialogClass
- //
- /////////////////////////////////////////////////////////////////////////////
- VisErrorReportDialogClass::~VisErrorReportDialogClass (void)
- {
- //
- // Free the BMPs
- //
- if (m_PrevButton.normal) ::DeleteObject (m_PrevButton.normal);
- if (m_PrevButton.disabled) ::DeleteObject (m_PrevButton.disabled);
- if (m_NextButton.normal) ::DeleteObject (m_NextButton.normal);
- if (m_NextButton.disabled) ::DeleteObject (m_NextButton.disabled);
- Free_Point_List ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // DoDataExchange
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::DoDataExchange (CDataExchange *pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(VisErrorReportDialogClass)
- DDX_Control(pDX, IDC_ZOOM_SLIDER, m_ZoomSlider);
- //}}AFX_DATA_MAP
- return ;
- }
- BEGIN_MESSAGE_MAP(VisErrorReportDialogClass, CDialog)
- //{{AFX_MSG_MAP(VisErrorReportDialogClass)
- ON_WM_PAINT()
- ON_WM_VSCROLL()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_MOUSEMOVE()
- ON_BN_CLICKED(IDC_PREV_ERROR, OnPrevError)
- ON_BN_CLICKED(IDC_NEXT_ERROR, OnNextError)
- ON_WM_DRAWITEM()
- ON_WM_NCHITTEST()
- ON_WM_SETCURSOR()
- ON_WM_DESTROY()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnInitDialog
- //
- /////////////////////////////////////////////////////////////////////////////
- BOOL
- VisErrorReportDialogClass::OnInitDialog (void)
- {
- CDialog::OnInitDialog ();
-
- //
- // Register this window for timer-based screen refreshing
- //
- ::SetProp (m_hWnd, "ALLOW_UPDATE", (HANDLE)1);
- //
- // Set the dimensions of the graph area
- //
- ::GetWindowRect (::GetDlgItem (m_hWnd, IDC_HISTOGRAM), &m_GraphArea);
- ScreenToClient (&m_GraphArea);
- m_GraphArea.left ++;
- m_GraphArea.right --;
- m_GraphArea.top ++;
- m_GraphArea.bottom --;
- m_Graph.Set_Dimensions (m_GraphArea.Width (), m_GraphArea.Height ());
- //
- // Set the dimensions of the 'axis' area.
- //
- CRect rect;
- ::GetWindowRect (::GetDlgItem (m_hWnd, IDC_AXIS_AREA), &rect);
- ScreenToClient (&rect);
- rect.left ++;
- rect.right --;
- rect.top ++;
- rect.bottom --;
- m_AxisArea.left = rect.left + (rect.Width () >> 1) - (AXIS_BMP_WIDTH >> 1);
- m_AxisArea.top = rect.top + (rect.Height () >> 1) - (AXIS_BMP_HEIGHT >> 1);
- m_AxisArea.right = m_AxisArea.left + AXIS_BMP_WIDTH;
- m_AxisArea.bottom = m_AxisArea.top + AXIS_BMP_HEIGHT;
-
- // Update the dialog with data from the scene
- Re_Sync_Data ();
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Re_Sync_Data
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Re_Sync_Data (void)
- {
- //
- // Get the error list from the scene
- //
- VisLogClass &vis_log = ::Get_Scene_Editor ()->Get_Vis_Log ();
- VIS_SAMPLE_LIST &error_list = vis_log.Peek_Error_List ();
- m_TotalPoints = error_list.Count ();
- //
- // Setup the 'zoom' slider
- //
- m_ZoomSlider.SetRange (2, m_TotalPoints >> 1);
- m_ZoomSlider.SetPos (m_TotalPoints >> 2);
-
- // Reset the range of values in the y-axis
- int max = (m_TotalPoints >> 1) - (m_ZoomSlider.GetPos () - 2);
- m_Graph.Set_Y_Axis_Range (0, max);
- //
- // Add the vis error points to the graph
- //
- Free_Point_List ();
- int bad_points = 0;
- for (int index = 0; index < error_list.Count (); index ++) {
- VisSampleClass *sample = error_list[index];
- Add_Point (*sample);
- //
- // Determining which direction resulted in the largest backface fraction
- //
- float fraction = sample->Get_Biggest_Fraction ();
- m_Graph.Add_Data_Point (fraction);
- //
- // Determine if this point was bad or not
- //
- int dir_index = sample->Get_Biggest_Fraction_Index ();
- if (sample->Sample_Status ((VisDirType)dir_index) != VIS_STATUS_OK) {
- bad_points ++;
- }
- }
- //
- // Set the dialog text fields
- //
- int points = ::Get_Scene_Editor ()->Get_Total_Vis_Points ();
- SetDlgItemInt (IDC_VIS_POINTS, points);
- SetDlgItemInt (IDC_BAD_POINTS, bad_points);
- SetDlgItemInt (IDC_MAX_POINTS, max);
- int bad_percent = (points > 0) ? ((bad_points * 100) / points) : 0;
- CString message;
- message.Format ("%d %%", bad_percent);
- SetDlgItemText (IDC_PERCENT_BAD, message);
- m_CurrentPoint = 0;
- m_CurrentMinPoint = 0;
- m_CurrentMaxPoint = 0;
- On_Graph_Sel_Changed ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Refresh_View
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Refresh_View (void)
- {
- if (m_hWnd != NULL) {
- InvalidateRect (&m_GraphArea, FALSE);
- UpdateWindow ();
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnPaint
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnPaint (void)
- {
- CPaintDC dc(this);
- m_Graph.Render (dc, m_GraphArea.left, m_GraphArea.top);
- Paint_Axis_Area (dc);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnVScroll
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnVScroll
- (
- UINT nSBCode,
- UINT nPos,
- CScrollBar *pScrollBar
- )
- {
- // Reset the range of values in the y-axis
- int max = m_TotalPoints - (m_ZoomSlider.GetPos () - 2);
- m_Graph.Set_Y_Axis_Range (0, max);
- SetDlgItemInt (IDC_MAX_POINTS, max);
- //
- // Repaint the graph
- //
- Refresh_View ();
- CDialog::OnVScroll (nSBCode, nPos, pScrollBar);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnLButtonDown
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnLButtonDown (UINT nFlags, CPoint point)
- {
- if (m_GraphArea.PtInRect (point)) {
- m_TrackPixel = point.x - m_GraphArea.left;
- m_Graph.Set_Selection (m_TrackPixel, m_TrackPixel);
- m_bTrackingSel = true;
- SetCapture ();
- Refresh_View ();
- On_Graph_Sel_Changed ();
- } else if (m_AxisArea.PtInRect (point)) {
- Update_Axis_Area (true);
- }
- CDialog::OnLButtonDown (nFlags, point);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnLButtonUp
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnLButtonUp (UINT nFlags, CPoint point)
- {
- if (m_bTrackingSel) {
- m_bTrackingSel = false;
- ReleaseCapture ();
- }
- CDialog::OnLButtonUp (nFlags, point);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnMouseMove
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnMouseMove (UINT nFlags, CPoint point)
- {
- if (m_bTrackingSel) {
- int new_pixel = point.x - m_GraphArea.left;
- new_pixel = max (new_pixel, 0);
- new_pixel = min (new_pixel, m_GraphArea.right-1);
- m_Graph.Set_Selection (m_TrackPixel, new_pixel);
- Refresh_View ();
- On_Graph_Sel_Changed ();
- }
- CDialog::OnMouseMove (nFlags, point);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Display_Point
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Display_Point (const Matrix3D &transform, bool fly_to)
- {
- if (fly_to) {
- ::Get_Camera_Mgr ()->Fly_To_Transform (transform);
- } else {
- ::Get_Camera_Mgr ()->Set_Transform (transform);
- }
- ::Refresh_Main_View ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // Free_Point_List
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Free_Point_List (void)
- {
- //
- // Delete all the vis samples
- //
- for (int index = 0; index < m_PointList.Count (); index ++) {
- VisSampleClass *vis_sample = m_PointList[index];
- SAFE_DELETE (vis_sample);
- }
- m_PointList.Delete_All ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // Add_Point
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Add_Point (const VisSampleClass &point)
- {
- int start = 0;
- int end = m_PointList.Count ();
- end = max (end, 0);
- float fraction = point.Get_Biggest_Fraction ();
- int index = end;
- while (end > start)
- {
- index = start + ((end - start) >> 1);
- float curr_fraction = m_PointList[index]->Get_Biggest_Fraction ();
- if (fraction > curr_fraction) {
- if (start == index) { index ++; break; }
- start = index;
- } else if (fraction < curr_fraction) {
- if (end == index) { index --; break; }
- end = index;
- } else {
- break;
- }
- }
- ASSERT (index >=0 );
- //
- // Simple binary search to find the right place
- // to insert the new data point
- //
- /*while (end > start) {
-
- int index = start + ((end - start) >> 1);
- float curr_fraction = m_PointList[index]->BackfaceFraction;
- if ((index == start) || (fraction == curr_fraction)) {
- break;
- } else if (fraction > curr_fraction) {
- start = index;
- } else if (fraction < curr_fraction) {
- end = index;
- }
- }*/
- //
- // Insert the new point into the list
- //
- m_PointList.Insert (index, new VisSampleClass (point));
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Find_Value_Index
- //
- /////////////////////////////////////////////////////////////////////////////
- int
- VisErrorReportDialogClass::Find_Value_Index (float fraction)
- {
- /*int retval = -1;
- //
- // Simple binary search to find the right place
- // to insert the new data point
- //
- int start = 0;
- int end = m_PointList.Count () - 1;
- while ((end > start) && (retval == -1)) {
-
- int index = start + ((end - start) >> 1);
- float curr_fraction = m_PointList[index]->BackfaceFraction;
- if (index == start) {
- retval = (fraction > curr_fraction) ? end : start;
- break;
- } else if (fraction > curr_fraction) {
- start = index;
- } else if (fraction < curr_fraction) {
- end = index;
- } else {
- retval = index;
- }
- }
- if (retval == -1) {
- retval = start;
- }*/
- int start = 0;
- int end = m_PointList.Count ();
- end = max (end, 0);
- int index = end;
- while (end > start)
- {
- index = start + ((end - start) >> 1);
- float curr_fraction = m_PointList[index]->Get_Biggest_Fraction ();
- if (fraction > curr_fraction) {
- if (start == index) { index ++; break; }
- start = index;
- } else if (fraction < curr_fraction) {
- if (end == index) { index --; break; }
- end = index;
- } else {
-
- while ((curr_fraction == fraction) && (index > 0)) {
- curr_fraction = m_PointList[--index]->Get_Biggest_Fraction ();
- }
- index = (curr_fraction == fraction) ? index : index + 1;
- //m_ValueList[index].count ++;
- //found = true;
- break;
- }
- }
- ASSERT (index >=0 );
- return index;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // On_Graph_Sel_Changed
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::On_Graph_Sel_Changed (void)
- {
- float range_min = 0;
- float range_max = 0;
- m_Graph.Get_Selection (range_min, range_max);
- if (range_min >= 0 && range_max >= 0) {
- m_SelStartIndex = Find_Value_Index (range_min);
- m_SelEndIndex = Find_Value_Index (range_max);
- } else {
- m_SelStartIndex = 0;
- m_SelEndIndex = m_PointList.Count () - 1;
- m_SelEndIndex = max (m_SelEndIndex, 0);
- }
- m_CurrentPoint = m_SelStartIndex - 1;
- //
- // Update the dialog UI
- //
- Update_Current_Point_Text ();
- Update_Nav_Buttons ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // Update_Nav_Buttons
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Update_Nav_Buttons (void)
- {
- bool enable_prev = m_CurrentPoint > m_SelStartIndex;
- bool enable_next = (m_CurrentPoint < m_SelEndIndex) && (m_PointList.Count () > 0);
- ::EnableWindow (::GetDlgItem (m_hWnd, IDC_PREV_ERROR), enable_prev);
- ::EnableWindow (::GetDlgItem (m_hWnd, IDC_NEXT_ERROR), enable_next);
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // OnPrevError
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnPrevError (void)
- {
- if (m_CurrentPoint > m_SelEndIndex) {
- m_CurrentPoint = m_SelEndIndex;
- } else {
- m_CurrentPoint --;
- m_CurrentPoint = max (m_CurrentPoint, 0);
- }
-
- //
- // Show the point
- //
- if (m_CurrentPoint < m_PointList.Count ()) {
- VisSampleClass *vis_sample = m_PointList[m_CurrentPoint];
- int index = vis_sample->Get_Biggest_Fraction_Index ();
-
- vis_sample->Set_Cur_Direction ((VisDirType)index);
- Display_Point (vis_sample->Get_Camera_Transform ((VisDirType)index), true);
- }
- //
- // Update the UI
- //
- Update_Current_Point_Text ();
- Update_Nav_Buttons ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // OnNextError
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnNextError (void)
- {
- if (m_CurrentPoint < m_SelStartIndex) {
- m_CurrentPoint = m_SelStartIndex;
- } else {
- m_CurrentPoint ++;
- m_CurrentPoint = min (m_CurrentPoint, m_PointList.Count () - 1);
- }
- //
- // Show the point
- //
- if (m_CurrentPoint < m_PointList.Count ()) {
- VisSampleClass *vis_sample = m_PointList[m_CurrentPoint];
- int index = vis_sample->Get_Biggest_Fraction_Index ();
- vis_sample->Set_Cur_Direction ((VisDirType)index);
- Display_Point (vis_sample->Get_Camera_Transform ((VisDirType)index), true);
- }
- //
- // Update the UI
- //
- Update_Current_Point_Text ();
- Update_Nav_Buttons ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // Update_Current_Point_Text
- //
- //////////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Update_Current_Point_Text (void)
- {
- //
- // Update the point-range static text control
- //
- int current_point = max ((m_CurrentPoint - m_SelStartIndex) + 1, 0);
- CString message;
- message.Format ("%d of %d", current_point, m_SelEndIndex - m_SelStartIndex);
- SetDlgItemText (IDC_CURRENT_POINT, message);
- if ((m_CurrentPoint >= 0) &&
- (m_CurrentPoint < m_PointList.Count ()))
- {
- VisSampleClass *vis_sample = m_PointList[m_CurrentPoint];
-
- //
- // Update the backface percent for this sample
- //
- float fraction = vis_sample->Get_Biggest_Fraction ();
- message.Format ("%.2f %%", fraction * 100);
- SetDlgItemText (IDC_CURRENT_PERCENT, message);
- //
- // Get the status string for the current direction
- //
- int dir_index = vis_sample->Get_Cur_Direction ();
- switch (vis_sample->Sample_Status ((VisDirType)dir_index)) {
-
- case VIS_STATUS_OK:
- message = "Ok";
- break;
- case VIS_STATUS_NOT_TAKEN:
- message = "Not Taken";
- break;
- case VIS_STATUS_ERROR:
- message = "!!Error!!";
- break;
- case VIS_STATUS_BACKFACE_LEAK:
- message = "Leak";
- break;
- case VIS_STATUS_BACKFACE_OVERFLOW:
- message = "Overflow";
- break;
- }
- SetDlgItemText (IDC_CURRENT_POINT_STATUS, message);
- } else {
- SetDlgItemText (IDC_CURRENT_PERCENT, "");
- SetDlgItemText (IDC_CURRENT_POINT_STATUS, "");
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnDrawItem
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnDrawItem
- (
- int nIDCtl,
- LPDRAWITEMSTRUCT lpDrawItemStruct
- )
- {
- //
- // Determine what state to draw the button in (pushed or normal)
- //
- UINT state = DFCS_BUTTONPUSH | DFCS_ADJUSTRECT;
- POINT offset = { 0 };
- if (lpDrawItemStruct->itemState & ODS_SELECTED) {
- state |= DFCS_PUSHED;
- offset.x = 1;
- offset.y = 1;
- }
- // Draw the button's outline
- CRect rect = lpDrawItemStruct->rcItem;
- ::DrawFrameControl (lpDrawItemStruct->hDC, rect, DFC_BUTTON, state);
- //
- // Determine which BMP to use
- //
- HBITMAP hbmp = NULL;
- if (nIDCtl == IDC_PREV_ERROR) {
- hbmp = ::IsWindowEnabled (lpDrawItemStruct->hwndItem) ? m_PrevButton.normal : m_PrevButton.disabled;
- } else if (nIDCtl == IDC_NEXT_ERROR) {
- hbmp = ::IsWindowEnabled (lpDrawItemStruct->hwndItem) ? m_NextButton.normal : m_NextButton.disabled;
- }
- HDC mem_dc = ::CreateCompatibleDC (NULL);
- HBITMAP old_bmp = (HBITMAP)::SelectObject (mem_dc, hbmp);
- //
- // Draw the BMP centered in the button
- //
- const int BMP_WIDTH = 25;
- const int BMP_HEIGHT = 28;
- int x_pos = rect.left + (rect.Width () >> 1) - (BMP_WIDTH >> 1) + offset.x;
- int y_pos = rect.top + (rect.Height () >> 1) - (BMP_HEIGHT >> 1) + offset.y;
- ::BitBlt (lpDrawItemStruct->hDC, x_pos, y_pos, BMP_WIDTH, BMP_HEIGHT, mem_dc, 0, 0, SRCCOPY);
- ::SelectObject (mem_dc, old_bmp);
- ::DeleteDC (mem_dc);
-
- // Draw the focus rectangle if necessary
- if (lpDrawItemStruct->itemState & ODS_FOCUS) {
- ::DrawFocusRect (lpDrawItemStruct->hDC, &rect);
- }
-
- // Allow the base class to process this message
- CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Paint_Axis_Area
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::Paint_Axis_Area (HDC hdc)
- {
- HDC mem_dc = ::CreateCompatibleDC (NULL);
- HBITMAP old_bmp = (HBITMAP)::SelectObject (mem_dc, m_AxisBMP);
- //
- // Draw the BMP centered in the button
- //
- const int BMP_WIDTH = 65;
- const int BMP_HEIGHT = 65;
- //int x_pos = m_AxisArea.left + (m_AxisArea.Width () >> 1) - (BMP_WIDTH >> 1);
- //int y_pos = m_AxisArea.top + (m_AxisArea.Height () >> 1) - (BMP_HEIGHT >> 1);
- ::BitBlt (hdc, m_AxisArea.left, m_AxisArea.top, BMP_WIDTH, BMP_HEIGHT, mem_dc, 0, 0, SRCCOPY);
- ::SelectObject (mem_dc, old_bmp);
- old_bmp = (HBITMAP)::SelectObject (mem_dc, m_AxisSelBMP);
- //
- // Paint the selected areas of the axis
- //
- for (int index = 0; index < 6; index ++) {
- if (m_AxisSel & (1 << index)) {
- CRect &rect = m_AxisSelAreas[index];
- int x_pos = m_AxisArea.left + rect.left;
- int y_pos = m_AxisArea.top + rect.top;
- ::BitBlt (hdc, x_pos, y_pos, rect.Width (), rect.Height (), mem_dc, rect.left, rect.top, SRCCOPY);
- }
- }
- ::SelectObject (mem_dc, old_bmp);
- ::DeleteDC (mem_dc);
- return ;
- }
- UINT VisErrorReportDialogClass::OnNcHitTest(CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
-
- return CDialog::OnNcHitTest(point);
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnSetCursor
- //
- /////////////////////////////////////////////////////////////////////////////
- BOOL
- VisErrorReportDialogClass::OnSetCursor
- (
- CWnd * pwnd,
- UINT hit_test,
- UINT message
- )
- {
- BOOL retval = FALSE;
- //
- // Determine if the cursor is over a 'hot-spot' in the axis area.
- //
- if (Update_Axis_Area ()) {
- ::SetCursor (::LoadCursor (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDC_HAND_POINTER)));
- } else {
- retval = CDialog::OnSetCursor (pwnd, hit_test, message);
- }
- return retval;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Update_Axis_Area
- //
- /////////////////////////////////////////////////////////////////////////////
- bool
- VisErrorReportDialogClass::Update_Axis_Area (bool do_view_change)
- {
- CPoint point;
- ::GetCursorPos (&point);
- ScreenToClient (&point);
- point.x -= m_AxisArea.left;
- point.y -= m_AxisArea.top;
- bool found = false;
- int old_sel = m_AxisSel;
- m_AxisSel = 0;
- //
- // Only do the UI stuff if we have a current point.
- //
- if ((m_CurrentPoint >= 0) &&
- (m_CurrentPoint < m_PointList.Count ()))
- {
- VisSampleClass *vis_sample = m_PointList[m_CurrentPoint];
- if ((point.x >= 0) && (point.y >= 0)) {
- //
- // Determine which direction we are over (if any)
- //
- for (int index = 0; index < 6 && !found; index ++) {
- if (m_AxisSelAreas[index].PtInRect (point)) {
- m_AxisSel |= (1 << index);
- found = true;
-
- //
- // Update the camera if necessary
- //
- if (do_view_change) {
- vis_sample->Set_Cur_Direction ((VisDirType)index);
- Display_Point (vis_sample->Get_Camera_Transform ((VisDirType)index), false);
- }
- }
- }
- }
-
- //
- // Hilight the direction that is currently displayed
- //
- int direction = vis_sample->Get_Cur_Direction ();
- int bit = (1 << direction);
- m_AxisSel |= bit;
- }
-
- if (old_sel != m_AxisSel) {
- //
- // Repaint the axis area
- //
- HDC hdc = ::GetDC (m_hWnd);
- Paint_Axis_Area (hdc);
- ::ReleaseDC (m_hWnd, hdc);
- }
- return found;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnDestroy
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VisErrorReportDialogClass::OnDestroy (void)
- {
- CDialog::OnDestroy();
- ::RemoveProp (m_hWnd, "ALLOW_UPDATE");
- return ;
- }
|