GME
13
|
00001 // InspectorList.cpp : implementation file 00002 // 00003 00004 #include "stdafx.h" 00005 #include "objectinspector.h" 00006 #include "InspectorList.h" 00007 #include "InspectorDlg.h" 00008 #include "ColourPopup.h" 00009 00010 #ifdef _DEBUG 00011 #define new DEBUG_NEW 00012 #undef THIS_FILE 00013 static char THIS_FILE[] = __FILE__; 00014 #endif 00015 00017 // CInspectorList 00018 00019 CInspectorList::CInspectorList(bool bCategories):m_bCategories(bCategories),m_InPlaceManager(this) 00020 { 00021 m_bIsDividerDrag=FALSE; 00022 m_ItemHeight = 16; 00023 m_ComboboxLineHeight = 13; 00024 HDC hdc = ::GetDC(NULL); 00025 if (hdc) 00026 { 00027 m_ItemHeight = m_ItemHeight * GetDeviceCaps(hdc, LOGPIXELSY) / 96; 00028 m_ComboboxLineHeight = m_ComboboxLineHeight * GetDeviceCaps(hdc, LOGPIXELSY) / 96; 00029 ::ReleaseDC(NULL, hdc); 00030 } 00031 } 00032 00033 CInspectorList::~CInspectorList() 00034 { 00035 00036 } 00037 00038 00039 BEGIN_MESSAGE_MAP(CInspectorList, CListBox) 00040 //{{AFX_MSG_MAP(CInspectorList) 00041 ON_WM_LBUTTONDOWN() 00042 ON_WM_LBUTTONDBLCLK() 00043 ON_WM_LBUTTONUP() 00044 ON_WM_MOUSEMOVE() 00045 ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelChange) 00046 ON_WM_LBUTTONDBLCLK() 00047 ON_WM_VSCROLL() 00048 ON_WM_MOUSEWHEEL() 00049 ON_WM_KEYDOWN() 00050 ON_WM_SIZE() 00051 ON_WM_RBUTTONDOWN() 00052 ON_BN_CLICKED(IDC_ARROW_BUTTON, OnArrowClicked) 00053 ON_BN_CLICKED(IDC_EDITOR_BUTTON, OnEditorClicked) 00054 ON_MESSAGE(MSG_EDIT_END_OK, OnEditEndOK) 00055 ON_COMMAND(ID_LISTCONTEXT_RESETTODEFAULT, OnListContextResetToDefault) 00056 //}}AFX_MSG_MAP 00057 END_MESSAGE_MAP() 00058 00060 // CInspectorList message handlers 00061 00062 BOOL CInspectorList::PreCreateWindow(CREATESTRUCT& cs) 00063 { 00064 // TODO: Add your specialized code here and/or call the base class 00065 cs.style |= WS_VSCROLL |LBS_OWNERDRAWVARIABLE | LBS_NOTIFY | 00066 LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | LBS_HASSTRINGS; 00067 cs.style&=~LBS_SORT; 00068 cs.dwExStyle |= WS_EX_CLIENTEDGE; 00069 return CListBox::PreCreateWindow(cs); 00070 } 00071 00072 void CInspectorList::PreSubclassWindow() 00073 { 00074 m_entryFont.CreatePointFont(INSP_ENTRY_FONT_PTSIZE, INSP_ENTRY_FONT_FACE); 00075 00076 00077 LOGFONT logFont; 00078 memset(&logFont, 0, sizeof(LOGFONT)); 00079 logFont.lfCharSet = DEFAULT_CHARSET; 00080 logFont.lfHeight = INSP_ENTRY_FONT_PTSIZE; 00081 logFont.lfWeight = FW_BOLD; 00082 lstrcpyn(logFont.lfFaceName, INSP_ENTRY_FONT_FACE, sizeof(logFont.lfFaceName) / sizeof(TCHAR)); 00083 00084 VERIFY(m_entryBoldFont.CreatePointFontIndirect(&logFont, NULL)); 00085 00086 00087 m_hCurArrow=AfxGetApp()->LoadStandardCursor(IDC_ARROW); 00088 m_hCurSize=AfxGetApp()->LoadStandardCursor(IDC_SIZEWE); 00089 00090 00091 00092 CListBox::PreSubclassWindow(); 00093 00094 } 00095 00096 void CInspectorList::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 00097 { 00098 00099 UINT nIndex = lpDrawItemStruct->itemID; 00100 BOOL bIsSelected=lpDrawItemStruct->itemState & ODS_SELECTED; 00101 BOOL bIsDisabled=lpDrawItemStruct->itemState & ODS_DISABLED; 00102 00103 // Obtaining the DeviceContext 00104 CDC dc; 00105 dc.Attach(lpDrawItemStruct->hDC); 00106 int savedDC = dc.SaveDC(); 00107 00108 00109 // If the item exists 00110 if (nIndex != (UINT) -1) 00111 { 00112 COLORREF crSelBackGround=::GetSysColor(COLOR_HIGHLIGHT); 00113 COLORREF crNormBackGround=::GetSysColor(COLOR_WINDOW); 00114 COLORREF crDisabledBackGround=::GetSysColor(COLOR_INACTIVEBORDER); 00115 00116 COLORREF crSelText=::GetSysColor(COLOR_HIGHLIGHTTEXT); 00117 COLORREF crNormText=::GetSysColor(COLOR_WINDOWTEXT); 00118 COLORREF crDisabledText=::GetSysColor(COLOR_GRAYTEXT); 00119 00120 COLORREF crText=bIsSelected?crSelText:crNormText; 00121 COLORREF crBckGr=bIsSelected?crSelBackGround:crNormBackGround; 00122 00123 00124 00125 CListItem& ListItem=m_ListItemArray[nIndex]; 00126 00127 00128 00129 // Getting the full rectangle for the item 00130 CRect rectFull = lpDrawItemStruct->rcItem; 00131 00132 // Setting up one rectangle for each columns 00133 CRect rectLeftMargin(rectFull),rectLeft(rectFull),rectRight(rectFull); 00134 if(m_bCategories) 00135 { 00136 rectLeftMargin.right=INSP_LEFT_MARGIN; 00137 } 00138 else 00139 { 00140 rectLeftMargin.right=rectLeftMargin.left; 00141 } 00142 00143 rectLeft.left=rectLeftMargin.right; 00144 rectLeft.right=m_Settings.m_nDivider; 00145 rectRight.left=m_Settings.m_nDivider; 00146 00147 00148 00149 // Repainting the background 00150 00151 // Left margin 00152 if(m_bCategories) 00153 { 00154 dc.FillSolidRect(rectLeftMargin,crNormBackGround); 00155 } 00156 00157 // Left side (name) 00158 dc.FillSolidRect(rectLeft.left-1,rectLeft.top-1,rectLeft.Width()+1,rectLeft.Height()+1,crBckGr); 00159 00160 // Not selecting right panel side - only if it's default 00161 if(ListItem.bIsDefault) 00162 { 00163 // crText=crDisabledText; -- Modification by Volgyesi 00164 crText=bIsSelected ? crText : crDisabledText; 00165 //crBckGr=crDisabledBackGround; 00166 } 00167 00168 if(ListItem.bIsDifferentValue) 00169 { 00170 dc.FillSolidRect(rectRight.left,rectRight.top-1,rectRight.Width(),rectRight.Height()+1,crDisabledBackGround); 00171 } 00172 else 00173 { 00174 dc.FillSolidRect(rectRight.left,rectRight.top-1,rectRight.Width(),rectRight.Height()+1,crNormBackGround); 00175 } 00176 00177 static CBrush Brush(crNormText); 00178 static CPen Pen(PS_SOLID,0,crNormText); 00179 static CPen PenInactiveBorder(PS_SOLID,0,crDisabledBackGround); 00180 00181 00182 // PlusMinus Button 00183 if(m_bCategories) 00184 { 00185 00186 if(ListItem.bIsContainer) 00187 { 00188 int nXPlusMinusOffset=(rectLeftMargin.Width()-INSP_PLUS_MINUS_BUTTON_SIZE)/2; 00189 int nYPlusMinusOffset=(rectLeftMargin.Height()-INSP_PLUS_MINUS_BUTTON_SIZE)/2; 00190 CRect rectPlusMinus(rectLeftMargin.left+nXPlusMinusOffset, 00191 rectLeftMargin.top+nYPlusMinusOffset, 00192 rectLeftMargin.left+nXPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE, 00193 rectLeftMargin.top+nYPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE); 00194 00195 CPoint ptCenter(rectPlusMinus.CenterPoint()); 00196 00197 00198 dc.FrameRect(rectPlusMinus,&Brush); 00199 00200 if(!ListItem.bIsContainerOpen) 00201 { 00202 // perpendicular component of + sign 00203 dc.MoveTo(ptCenter.x, ptCenter.y - 2); 00204 dc.LineTo(ptCenter.x, ptCenter.y + 3); 00205 } 00206 // - sign 00207 dc.MoveTo(ptCenter.x - 2, ptCenter.y); 00208 dc.LineTo(ptCenter.x + 3, ptCenter.y); 00209 } 00210 } 00211 00212 00213 // Drawing edges - But we have to increase the rect 00214 if(!rectLeft.IsRectEmpty()) 00215 { 00216 dc.SelectObject(PenInactiveBorder); 00217 rectLeft.InflateRect(2,1,0,0); 00218 dc.DrawEdge(rectLeft,EDGE_SUNKEN,BF_BOTTOMRIGHT); 00219 00220 dc.MoveTo(rectLeft.TopLeft()); 00221 dc.LineTo(rectLeft.left,rectLeft.bottom); 00222 00223 rectLeft.DeflateRect(2,1,0,0); 00224 } 00225 00226 if(!rectRight.IsRectEmpty()) 00227 { 00228 rectRight.InflateRect(1,0,0,0); 00229 dc.DrawEdge(rectRight,EDGE_SUNKEN,BF_BOTTOM); 00230 rectRight.DeflateRect(1,0,0,0); 00231 } 00232 00233 // Attribute name 00234 CString strName=ListItem.strName; 00235 CString strTxt; 00236 ListItem.Value.toString(strTxt); 00237 00238 dc.SelectObject(&m_entryFont); 00239 dc.SetBkMode(TRANSPARENT); 00240 00241 // Container 00242 if(ListItem.bIsContainer) 00243 { 00244 dc.SelectObject(&m_entryBoldFont); 00245 } 00246 else // Normal data types 00247 { 00248 dc.SetTextColor(ListItem.bIsDefault?crDisabledText:crNormText); 00249 00250 if(ListItem.Value.dataType==ITEMDATA_COLOR) // Color 00251 { 00252 CRect rectColorBox(rectRight); 00253 rectColorBox.left+=INSP_COLORBOX_MARGIN; 00254 rectColorBox.right=rectColorBox.left+INSP_COLORBOX_SIZE; 00255 rectColorBox.top=rectColorBox.top+(rectColorBox.Height()-INSP_COLORBOX_SIZE)/2-1; 00256 rectColorBox.bottom=rectColorBox.top+INSP_COLORBOX_SIZE; 00257 00258 dc.FillSolidRect(rectColorBox,ListItem.Value.colorVal); 00259 dc.FrameRect(rectColorBox,&Brush); 00260 00261 CRect rectText(rectRight); 00262 rectText.left=rectColorBox.right+2*INSP_COLORBOX_MARGIN; 00263 00264 dc.DrawText(strTxt,CRect(rectText.left,rectText.top, 00265 rectText.right,rectText.bottom), 00266 DT_LEFT | DT_SINGLELINE); 00267 } 00268 else if(ListItem.Value.dataType==ITEMDATA_STRING&&ListItem.Value.cLineNum>1) 00269 { 00270 // Multiline string 00271 CString strTxt; 00272 ListItem.Value.toString(strTxt); 00273 dc.DrawText(strTxt,CRect(rectRight.left,rectRight.top, 00274 rectRight.right,rectRight.bottom),DT_LEFT | DT_NOPREFIX); 00275 //DT_NOPREFIX by zolmol: draw string as is, do not interpret the & character 00276 } 00277 else 00278 { 00279 // Do not select the right hand side 00280 00281 dc.DrawText(strTxt,CRect(rectRight.left,rectRight.top, 00282 rectRight.right,rectRight.bottom), 00283 DT_LEFT | DT_SINGLELINE | DT_NOPREFIX); 00284 //DT_NOPREFIX by zolmol: draw string as is, do not interpret the & character 00285 } 00286 } 00287 dc.SetTextColor(crText); 00288 dc.DrawText(strName,CRect(rectLeft.left,rectLeft.top, 00289 rectLeft.right-2,rectLeft.bottom), 00290 DT_LEFT | DT_SINGLELINE); 00291 } 00292 00293 dc.RestoreDC(savedDC); 00294 dc.Detach(); 00295 00296 00297 } 00298 00299 void CInspectorList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 00300 { 00301 int nIndex=lpMeasureItemStruct->itemID; 00302 if(m_ListItemArray[nIndex].Value.dataType==ITEMDATA_STRING) 00303 { 00304 int nLineNum=m_ListItemArray[nIndex].Value.cLineNum; 00305 if(nLineNum==1) 00306 { 00307 lpMeasureItemStruct->itemHeight = m_ItemHeight; 00308 } 00309 else 00310 { 00311 lpMeasureItemStruct->itemHeight = min(255, nLineNum * m_ItemHeight); 00312 } 00313 00314 } 00315 else 00316 { 00317 lpMeasureItemStruct->itemHeight = m_ItemHeight; 00318 } 00319 00320 } 00321 00322 void CInspectorList::DoCollapseExpand(int nIndex) 00323 { 00324 m_InPlaceManager.HideAllInPlace(); 00325 00326 CListItem &ListItem=m_ListItemArray.ElementAt(nIndex); 00327 if(!ListItem.bIsContainer) return; 00328 00329 if(ListItem.bIsContainerOpen) 00330 { 00331 int nChildIndex=nIndex+1; 00332 ListItem.m_ContainedListItemArray.RemoveAll(); 00333 00334 while(nChildIndex<=m_ListItemArray.GetUpperBound()) 00335 { 00336 CListItem ChildListItem=m_ListItemArray.GetAt(nChildIndex); 00337 00338 if(ChildListItem.bIsContainer)break; 00339 00340 ListItem.m_ContainedListItemArray.Add(ChildListItem); 00341 00342 RemoveItem(nChildIndex); 00343 } 00344 00345 // Setting the +/-sign 00346 ListItem.bIsContainerOpen=FALSE; 00347 } 00348 else 00349 { 00350 int nChildIndex=nIndex+1; 00351 for(int i=0;i<=ListItem.m_ContainedListItemArray.GetUpperBound();i++) 00352 { 00353 CListItem ChildListItem=ListItem.m_ContainedListItemArray.GetAt(i); 00354 m_ListItemArray.InsertAt(nChildIndex+i,ChildListItem); 00355 InsertString(nChildIndex+i,_T("")); 00356 00357 } 00358 00359 ListItem.m_ContainedListItemArray.RemoveAll(); 00360 00361 // Setting the +/-sign 00362 ListItem.bIsContainerOpen=TRUE; 00363 } 00364 Invalidate(); 00365 00366 } 00367 00368 00369 void CInspectorList::OnLButtonDown(UINT nFlags, CPoint point) 00370 { 00371 if(GetCount()==0)return; 00372 00373 if(m_bCategories) 00374 { 00375 OnPlusMinusClick(point); 00376 } 00377 if (OnRightSideClick(point)) 00378 return; 00379 00380 if(point.x>=(int)m_Settings.m_nDivider-INSP_MOUSE_RADIUS && 00381 point.x<=(int)m_Settings.m_nDivider+INSP_MOUSE_RADIUS) 00382 { 00383 00384 m_bIsDividerDrag=TRUE; 00385 00386 ::SetCursor(m_hCurSize); 00387 00388 CRect rectWnd; 00389 GetWindowRect(rectWnd); 00390 rectWnd.left += INSP_LEFT_MARGIN+3; rectWnd.right -= 20; 00391 00392 //Mouse within the listbox 00393 ::ClipCursor(rectWnd); 00394 00395 //Capture the mouse 00396 SetCapture(); 00397 00398 00399 CRect rectClient; 00400 GetClientRect(rectClient); 00401 00402 m_ptOldTop.y=rectClient.top; 00403 m_ptOldTop.x=point.x; 00404 00405 m_ptOldBottom.y=rectClient.bottom; 00406 m_ptOldBottom.x=point.x; 00407 00408 CClientDC dc(this); 00409 InvertLine(&dc,m_ptOldTop,m_ptOldBottom); 00410 00411 } 00412 else 00413 { 00414 CListBox::OnLButtonDown(nFlags, point); 00415 } 00416 } 00417 00418 void CInspectorList::OnLButtonUp(UINT nFlags, CPoint point) 00419 { 00420 if(GetCount()==0)return; 00421 00422 if(m_bIsDividerDrag) 00423 { 00424 m_bIsDividerDrag=FALSE; 00425 m_Settings.m_nDivider = point.x; 00426 00427 //Release the mouse 00428 if (this==GetCapture()) 00429 { 00430 ::ReleaseCapture(); 00431 } 00432 00433 // Allow the cursor to go outside 00434 ::ClipCursor(NULL); 00435 00436 // Arrow cursor 00437 ::SetCursor(m_hCurSize); 00438 00439 m_InPlaceManager.HideAllInPlace(); 00440 // Redraw listbox 00441 Invalidate(); 00442 } 00443 CListBox::OnLButtonUp(nFlags, point); 00444 } 00445 00446 void CInspectorList::OnMouseMove(UINT nFlags, CPoint point) 00447 { 00448 if(GetCount()==0)return; 00449 00450 if(m_bIsDividerDrag) 00451 { 00452 // Deleting the previous line 00453 CClientDC dc(this); 00454 InvertLine(&dc,m_ptOldTop,m_ptOldBottom); 00455 00456 // Drawing a new one 00457 m_ptOldTop.x=point.x; 00458 m_ptOldBottom.x=point.x; 00459 InvertLine(&dc,m_ptOldTop,m_ptOldBottom); 00460 00461 } 00462 else 00463 { 00464 if(point.x>=(int)m_Settings.m_nDivider-INSP_MOUSE_RADIUS && 00465 point.x<=(int)m_Settings.m_nDivider+INSP_MOUSE_RADIUS) 00466 { 00467 ::SetCursor(m_hCurSize); 00468 } 00469 else 00470 { 00471 ::SetCursor(m_hCurArrow); 00472 } 00473 00474 } 00475 00476 CListBox::OnMouseMove(nFlags, point); 00477 } 00478 00479 void CInspectorList::InvertLine(CDC *pDC, CPoint ptSrc, CPoint ptDst) 00480 { 00481 00482 int nOldMode = pDC->SetROP2(R2_NOT); 00483 00484 pDC->MoveTo(ptSrc); 00485 pDC->LineTo(ptDst); 00486 00487 pDC->SetROP2(nOldMode); 00488 } 00489 00490 void CInspectorList::OnSelChange() 00491 { 00492 int nSelCount=GetSelCount(); 00493 00494 if(nSelCount<1) 00495 { 00496 SetHelp(-1); 00497 } 00498 else 00499 { 00500 00501 int nSelected; 00502 CListBox::GetSelItems(1,&nSelected); 00503 00504 CRect rectItem; 00505 GetItemRect(nSelected,rectItem); 00506 00507 SetHelp(nSelected); 00508 rectItem.left=m_Settings.m_nDivider; 00509 m_InPlaceManager.ShowInPlace(rectItem,nSelected); 00510 } 00511 00512 } 00513 00514 00515 void CInspectorList::OnArrowClicked() 00516 { 00517 00518 m_InPlaceManager.OnClickArrowButton(false); 00519 00520 } 00521 00522 void CInspectorList::OnEditorClicked() 00523 { 00524 00525 m_InPlaceManager.OnClickEditorButton(); 00526 00527 } 00528 00529 00530 bool CInspectorList::InsertItem(CListItem ListItem, int nIndex) 00531 { 00532 int nUpperBound=m_ListItemArray.GetUpperBound(); 00533 00534 if(nIndex>nUpperBound) 00535 { 00536 return AddItem(ListItem); 00537 } 00538 00539 if(!m_bCategories||nUpperBound==-1) 00540 { 00541 m_ListItemArray.InsertAt(nIndex,ListItem); 00542 InsertString(nIndex,_T("")); 00543 } 00544 else 00545 { 00546 int nLastCategoryIndex=nIndex; 00547 bool bIsOpen; 00548 do 00549 { 00550 const CListItem &LastCategoryListItem=m_ListItemArray.ElementAt(nLastCategoryIndex); 00551 if(LastCategoryListItem.bIsContainer) 00552 { 00553 bIsOpen=LastCategoryListItem.bIsContainerOpen; 00554 break; 00555 } 00556 nLastCategoryIndex--; 00557 }while(nLastCategoryIndex>=0); 00558 00559 00560 if(nLastCategoryIndex!=-1 && !bIsOpen) 00561 { 00562 CListItem & LastCategoryListItem =m_ListItemArray.ElementAt(nLastCategoryIndex); 00563 LastCategoryListItem.m_ContainedListItemArray.Add(ListItem); 00564 } 00565 else 00566 { 00567 m_ListItemArray.InsertAt(nIndex,ListItem); 00568 InsertString(nIndex,_T("")); 00569 00570 } 00571 00572 } 00573 00574 00575 // Checking value 00576 if(!m_bCategories) 00577 { 00578 ASSERT(ListItem.Value.dataType!=ITEMDATA_NULL); 00579 return false; 00580 } 00581 else 00582 { 00583 if(ListItem.Value.dataType==ITEMDATA_NULL && ListItem.bIsContainer==false) 00584 { 00585 // We should not add null items not containing any type 00586 ASSERT(("ITEMDATA_NULL type data was to be inserted in the list",false)); 00587 return false; 00588 } 00589 else 00590 { 00591 return true; 00592 } 00593 } 00594 } 00595 00596 00597 void CInspectorList::GetSelItems(CArray<int,int>&IndexArray,CArray<CListItem,CListItem&> &ListItemArray) 00598 { 00599 IndexArray.RemoveAll(); 00600 ListItemArray.RemoveAll(); 00601 00602 int nSelCount=GetSelCount(); 00603 00604 if(nSelCount>0) 00605 { 00606 IndexArray.SetSize(nSelCount); 00607 CListBox::GetSelItems(nSelCount,IndexArray.GetData()); 00608 } 00609 00610 for(int i=0;i<=IndexArray.GetUpperBound();i++) 00611 { 00612 ListItemArray.Add(m_ListItemArray.ElementAt(IndexArray[i])); 00613 } 00614 } 00615 00616 00617 bool CInspectorList::AddItem(CListItem ListItem) 00618 { 00619 00620 int nUpperBound=m_ListItemArray.GetUpperBound(); 00621 00622 if(!m_bCategories||nUpperBound==-1) 00623 { 00624 m_ListItemArray.Add(ListItem); 00625 AddString(_T("")); 00626 } 00627 else 00628 { 00629 int nLastCategoryIndex=nUpperBound; 00630 bool bIsOpen; 00631 do 00632 { 00633 const CListItem &LastCategoryListItem=m_ListItemArray.ElementAt(nLastCategoryIndex); 00634 if(LastCategoryListItem.bIsContainer) 00635 { 00636 bIsOpen=LastCategoryListItem.bIsContainerOpen; 00637 break; 00638 } 00639 nLastCategoryIndex--; 00640 }while(nLastCategoryIndex>=0); 00641 00642 00643 if(nLastCategoryIndex!=-1 && !bIsOpen) 00644 { 00645 CListItem & LastCategoryListItem =m_ListItemArray.ElementAt(nLastCategoryIndex); 00646 LastCategoryListItem.m_ContainedListItemArray.Add(ListItem); 00647 } 00648 else 00649 { 00650 m_ListItemArray.Add(ListItem); 00651 AddString(_T("")); 00652 } 00653 } 00654 00655 RefreshState(); 00656 // Checking value 00657 if(!m_bCategories) 00658 { 00659 ASSERT(ListItem.Value.dataType!=ITEMDATA_NULL); 00660 return false; 00661 } 00662 else 00663 { 00664 if(ListItem.Value.dataType==ITEMDATA_NULL && ListItem.bIsContainer==false) 00665 { 00666 // We should not add null items not containing any type 00667 ASSERT(("ITEMDATA_NULL type data was to be inserted in the list",false)); 00668 return false; 00669 } 00670 else 00671 { 00672 return true; 00673 } 00674 } 00675 } 00676 00677 00678 void CInspectorList::UpdateItems(CArray<CListItem,CListItem&> &ListItemArray) 00679 { 00680 int nUpperBound=ListItemArray.GetUpperBound(); 00681 int nIndex=0; 00682 00683 for(int i=0;i<=m_ListItemArray.GetUpperBound();i++) 00684 { 00685 CListItem& ListItem=m_ListItemArray.ElementAt(i); 00686 00687 if(nIndex>nUpperBound) 00688 { 00689 CInspectorList::RemoveItem(i); 00690 i--; 00691 continue; 00692 } 00693 else 00694 { 00695 UpdateItem(ListItemArray.ElementAt(nIndex),ListItem, nIndex); 00696 nIndex++; 00697 } 00698 00699 if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen) 00700 { 00701 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++) 00702 { 00703 CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j); 00704 if(nIndex>nUpperBound) 00705 { 00706 ListItem.m_ContainedListItemArray.RemoveAt(j); 00707 j--; 00708 continue; 00709 } 00710 else 00711 { 00712 UpdateItem(ListItemArray.ElementAt(nIndex),InnerListItem, nIndex); 00713 nIndex++; 00714 } 00715 } 00716 } 00717 } 00718 00719 int nLastElement=m_ListItemArray.GetUpperBound(); 00720 if(nLastElement>=0) 00721 { 00722 const CListItem& LastListItem=m_ListItemArray.ElementAt(nLastElement); 00723 00724 if(LastListItem.bIsContainer&& !LastListItem.bIsContainerOpen && nIndex<=nUpperBound) 00725 { 00726 DoCollapseExpand(nLastElement); 00727 } 00728 } 00729 for(int k=nIndex;k<=nUpperBound;k++) 00730 { 00731 CInspectorList::AddItem(ListItemArray.ElementAt(k)); 00732 } 00733 if (m_InPlaceManager.m_ArrowButton.m_hWnd) 00734 m_InPlaceManager.m_ArrowButton.ShowWindow(SW_HIDE); 00735 00736 Invalidate(); 00737 } 00738 00739 00740 void CInspectorList::UpdateItem(const CListItem &srcListItem, CListItem &dstListItem, int nIndex) 00741 { 00742 ASSERT(nIndex < GetCount()); 00743 dstListItem.CopyWithNoState(srcListItem); 00744 00745 00746 // Unfortunately, Windows sends MeasureItem message only once - Volgyesi 00747 if(srcListItem.Value.dataType==ITEMDATA_STRING) 00748 { 00749 int nLineNum=srcListItem.Value.cLineNum; 00750 if(nLineNum==1) 00751 { 00752 SetItemHeight(nIndex, m_ItemHeight); 00753 } 00754 else 00755 { 00756 VERIFY(SetItemHeight(nIndex, min(255, nLineNum * m_ItemHeight)) == LB_OKAY); 00757 } 00758 00759 } 00760 else 00761 { 00762 SetItemHeight(nIndex, m_ItemHeight); 00763 } 00764 // Modification End - Volgyesi 00765 } 00766 00767 00768 bool CInspectorList::RemoveItem(int nIndex) 00769 { 00770 if(nIndex<=m_ListItemArray.GetUpperBound()) 00771 { 00772 m_InPlaceManager.HideAllInPlace(); 00773 m_ListItemArray.RemoveAt(nIndex); 00774 VERIFY(DeleteString(nIndex)!=LB_ERR); 00775 return true; 00776 } 00777 return false; 00778 } 00779 00780 00781 void CInspectorList::RemoveAll() 00782 { 00783 m_ListItemArray.RemoveAll(); 00784 CInspectorList::ResetContent(); 00785 } 00786 00787 00788 void CInspectorList::ResetContent() 00789 { 00790 m_InPlaceManager.HideAllInPlace(); 00791 CListBox::ResetContent(); 00792 } 00793 00794 00795 void CInspectorList::OnLButtonDblClk(UINT nFlags, CPoint point) 00796 { 00797 if (!OnPlusMinusClick(point)) 00798 OnLButtonDown(nFlags, point); 00799 00800 //CListBox::OnLButtonDblClk(nFlags, point); 00801 } 00802 00803 00804 bool CInspectorList::OnPlusMinusClick(CPoint point) 00805 { 00806 BOOL bOutside; 00807 int nIndex=ItemFromPoint(point,bOutside); 00808 if (nIndex==65535) 00809 return false; 00810 if (bOutside) 00811 return false; 00812 00813 CListItem ListItem=m_ListItemArray.GetAt(nIndex); 00814 if(!ListItem.bIsContainer) 00815 return false; 00816 00817 CRect rectItem; 00818 GetItemRect(nIndex,rectItem); 00819 CRect rectLeftMargin(rectItem); 00820 rectLeftMargin.right=INSP_LEFT_MARGIN; 00821 int nXPlusMinusOffset=(rectLeftMargin.Width()-INSP_PLUS_MINUS_BUTTON_SIZE)/2; 00822 int nYPlusMinusOffset=(rectLeftMargin.Height()-INSP_PLUS_MINUS_BUTTON_SIZE)/2; 00823 CRect rectPlusMinus(rectLeftMargin.left+nXPlusMinusOffset, 00824 rectLeftMargin.top+nYPlusMinusOffset, 00825 rectLeftMargin.left+nXPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE, 00826 rectLeftMargin.top+nYPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE); 00827 if(rectPlusMinus.PtInRect(point)) 00828 { 00829 // If it was a click on the correct place 00830 DoCollapseExpand(nIndex); 00831 return true; 00832 } 00833 00834 return false; 00835 } 00836 00837 00838 bool CInspectorList::OnRightSideClick(CPoint point) 00839 { 00840 BOOL bOutside; 00841 int nIndex=ItemFromPoint(point,bOutside); 00842 00843 if(!bOutside) 00844 { 00845 CRect rectItem; 00846 GetItemRect(nIndex,rectItem); 00847 00848 CRect rectRight(rectItem); 00849 rectRight.left=m_Settings.m_nDivider; 00850 00851 if(rectRight.PtInRect(point)) 00852 { 00853 return m_InPlaceManager.OnRightItemClick(nIndex, rectRight); 00854 } 00855 } 00856 00857 return false; 00858 } 00859 00860 00861 void CInspectorList::SetHelp(int nIndex) 00862 { 00863 00864 CWnd* pParent=GetParent(); 00865 CInspectorDlg*pInspectorDlg=(CInspectorDlg*)pParent->GetParent(); 00866 00867 if(nIndex==-1) 00868 { 00869 pInspectorDlg->SetHelp(_T(""),_T("")); 00870 return; 00871 } 00872 00873 00874 int nSelCount=GetSelCount(); 00875 if(nSelCount>1) 00876 { 00877 pInspectorDlg->SetHelp(_T("Multiple Selection"),_T("Select one item to edit its properties \r\nor press Ctrl+D to make selected items default.")); 00878 } 00879 else 00880 { 00881 CListItem ListItem=m_ListItemArray.GetAt(nIndex); 00882 pInspectorDlg->SetHelp(ListItem.strName,ListItem.strToolTip); 00883 } 00884 } 00885 00886 00887 bool CInspectorList::SelectNextItem(BOOL reverse) 00888 { 00889 int nCount = GetCount(); 00890 if (nCount > 1) { 00891 int nCurSel = GetCurSel(); // In a multiple-selection list box, the index of the item that has the focus. 00892 nCurSel = nCurSel + (reverse ? -1 : 1); 00893 nCurSel = (nCurSel + nCount) % nCount; 00894 // Clear current selections 00895 // Get the indexes of all the selected items. 00896 int nSelCount = GetSelCount(); 00897 CArray<int,int> arrListBoxSel; 00898 arrListBoxSel.SetSize(nSelCount); 00899 CListBox::GetSelItems(nSelCount, arrListBoxSel.GetData()); 00900 for(int i = 0; i < nSelCount; i++) 00901 SetSel(arrListBoxSel.GetAt(i), FALSE); 00902 00903 // Select the next focused 00904 SetSel(nCurSel, TRUE); 00905 OnSelChange(); 00906 00907 // TODO: pop up comboboxes (tricky because they're not really comboboxes) 00908 //CListItem& ListItem=m_ListItemArray.ElementAt(nCurSel); 00909 //if (ListItem.Value.dataType == ITEMDATA_BOOLEAN || ListItem.Value.dataType == ITEMDATA_FIXED_LIST) { 00910 // m_InPlaceManager.OnClickArrowButton(false); 00911 //} 00912 return true; 00913 } 00914 return false; 00915 } 00916 00917 00918 LRESULT CInspectorList::OnEditEndOK(WPARAM /*lParam*/, LPARAM /*wParam*/) 00919 { 00920 00921 m_InPlaceManager.OnEditEnd(); 00922 00923 return TRUE; 00924 } 00925 00926 00927 void CInspectorList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 00928 { 00929 m_InPlaceManager.HideAllInPlace(); 00930 00931 CListBox::OnVScroll(nSBCode, nPos, pScrollBar); 00932 } 00933 00934 00935 BOOL CInspectorList::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 00936 { 00937 m_InPlaceManager.HideAllInPlace(); 00938 return CListBox::OnMouseWheel(nFlags, zDelta, pt); 00939 } 00940 00941 00942 00943 void CInspectorList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 00944 { 00945 switch(nChar) 00946 { 00947 case 'D': // That's all abaout Microsoft VK_ codes. 00948 { 00949 if(::GetKeyState(VK_CONTROL) & 0x8000) 00950 { 00951 SetDefault(); 00952 Invalidate(); 00953 00954 } 00955 } 00956 break; 00957 case VK_DELETE: 00958 { 00959 SetDefault(); 00960 Invalidate(); 00961 } 00962 break; 00963 case VK_TAB: // JIRA GME-178 00964 { 00965 SelectNextItem(::GetKeyState(VK_SHIFT) & 0x8000); 00966 } 00967 break; 00968 } 00969 00970 CListBox::OnKeyDown(nChar, nRepCnt, nFlags); 00971 } 00972 00973 00974 void CInspectorList::SetDefault() 00975 { 00976 int nSelCount=GetSelCount(); 00977 00978 CArray<int,int> SelItemArr; 00979 SelItemArr.SetSize(nSelCount); 00980 00981 CListBox::GetSelItems(nSelCount,SelItemArr.GetData()); 00982 00983 for(int i=0;i<=SelItemArr.GetUpperBound();i++) 00984 { 00985 int nCurr=SelItemArr.GetAt(i); 00986 00987 CListItem& ListItem=m_ListItemArray.ElementAt(nCurr); 00988 ListItem.RestoreDefault(); 00989 00990 NotifyParent(nCurr); 00991 } 00992 } 00993 00994 void CInspectorList::OnSize(UINT nType, int cx, int cy) 00995 { 00996 m_InPlaceManager.HideAllInPlace(); 00997 CListBox::OnSize(nType, cx, cy); 00998 00999 } 01000 01001 bool CInspectorList::FindByKey(DWORD dwKey,CListItem& FoundListItem ) 01002 { 01003 for(int i=0;i<=m_ListItemArray.GetUpperBound();i++) 01004 { 01005 CListItem& ListItem=m_ListItemArray.ElementAt(i); 01006 if(ListItem.dwKeyValue==dwKey) 01007 { 01008 FoundListItem= ListItem; 01009 return true; 01010 } 01011 else 01012 { 01013 if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen) 01014 { 01015 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++) 01016 { 01017 CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j); 01018 if(InnerListItem.dwKeyValue==dwKey) 01019 { 01020 FoundListItem= InnerListItem; 01021 return true; 01022 } 01023 } 01024 } 01025 } 01026 } 01027 return false; 01028 01029 } 01030 01031 01032 bool CInspectorList::FindByKey(DWORD dwKey,DWORD dwUserData, CListItem& FoundListItem ) 01033 { 01034 for(int i=0;i<=m_ListItemArray.GetUpperBound();i++) 01035 { 01036 CListItem& ListItem=m_ListItemArray.ElementAt(i); 01037 if(ListItem.dwKeyValue==dwKey && ListItem.dwUserData==dwUserData) 01038 { 01039 FoundListItem= ListItem; 01040 return true; 01041 } 01042 else 01043 { 01044 if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen) 01045 { 01046 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++) 01047 { 01048 CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j); 01049 if(InnerListItem.dwKeyValue==dwKey && InnerListItem.dwUserData==dwUserData) 01050 { 01051 FoundListItem= InnerListItem; 01052 return true; 01053 } 01054 } 01055 } 01056 } 01057 } 01058 return false; 01059 01060 } 01061 01062 01063 void CInspectorList::DeleteByKey(DWORD dwKey, DWORD dwUserData) 01064 { 01065 for(int i=0;i<=m_ListItemArray.GetUpperBound();i++) 01066 { 01067 CListItem& ListItem=m_ListItemArray.ElementAt(i); 01068 if(ListItem.dwKeyValue==dwKey && ListItem.dwUserData==dwUserData) 01069 { 01070 // Remove from array 01071 m_ListItemArray.RemoveAt(i); 01072 // Remove from listbox 01073 DeleteString(i); 01074 // Refresh listbox 01075 Invalidate(); 01076 return; 01077 01078 } 01079 else 01080 { 01081 if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen) 01082 { 01083 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++) 01084 { 01085 CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j); 01086 if(InnerListItem.dwKeyValue==dwKey && InnerListItem.dwUserData==dwUserData) 01087 { 01088 // Remove from inner array 01089 ListItem.m_ContainedListItemArray.RemoveAt(j); 01090 return; 01091 } 01092 } 01093 } 01094 } 01095 } 01096 } 01097 01098 01099 void CInspectorList::DeleteByKey(DWORD dwKey) 01100 { 01101 01102 for(int i=0;i<=m_ListItemArray.GetUpperBound();i++) 01103 { 01104 CListItem& ListItem=m_ListItemArray.ElementAt(i); 01105 if(ListItem.dwKeyValue==dwKey) 01106 { 01107 // Remove from array 01108 m_ListItemArray.RemoveAt(i); 01109 // Remove from listbox 01110 DeleteString(i); 01111 // Refresh listbox 01112 Invalidate(); 01113 return; 01114 01115 } 01116 else 01117 { 01118 if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen) 01119 { 01120 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++) 01121 { 01122 CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j); 01123 if(InnerListItem.dwKeyValue==dwKey) 01124 { 01125 // Remove from inner array 01126 ListItem.m_ContainedListItemArray.RemoveAt(j); 01127 return; 01128 } 01129 } 01130 } 01131 } 01132 } 01133 } 01134 01135 01136 void CInspectorList::NotifyParent(UINT nSelItem) 01137 { 01138 GetParent()->SendMessage(LBN_ON_ITEM_CHANGED,nSelItem,0); 01139 } 01140 01141 void CInspectorList::RefreshState() 01142 { 01143 SetHelp(-1); 01144 // PETER: Removed beacuse of JIRA #GME-64 01145 // OnSelChange(); 01146 } 01147 01148 01149 void CInspectorList::GetItem(int nIndex, CListItem &ListItem) 01150 { 01151 ListItem=m_ListItemArray[nIndex]; 01152 } 01153 01154 01155 void CInspectorList::OnRButtonDown(UINT nFlags, CPoint point) 01156 { 01157 bool bIsCustom = false; 01158 01159 int nSelCount=GetSelCount(); 01160 01161 CArray<int,int> SelItemArr; 01162 SelItemArr.SetSize(nSelCount); 01163 01164 CListBox::GetSelItems(nSelCount,SelItemArr.GetData()); 01165 01166 for(int i=0;i<=SelItemArr.GetUpperBound();i++) 01167 { 01168 int nCurr=SelItemArr.GetAt(i); 01169 01170 CListItem& ListItem=m_ListItemArray.ElementAt(nCurr); 01171 if (!ListItem.bIsDefault) { 01172 bIsCustom = true; 01173 break; 01174 } 01175 } 01176 01177 if (bIsCustom) { 01178 CMenu menu; 01179 menu.LoadMenu(IDR_LISTCNTX_MENU); 01180 ClientToScreen(&point); 01181 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, 01182 point.x, point.y, this); 01183 } 01184 01185 CListBox::OnRButtonDown(nFlags, point); 01186 } 01187 01188 void CInspectorList::OnListContextResetToDefault() 01189 { 01190 SetDefault(); 01191 Invalidate(); 01192 }