diff options
Diffstat (limited to 'hammer/listboxex.cpp')
| -rw-r--r-- | hammer/listboxex.cpp | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/hammer/listboxex.cpp b/hammer/listboxex.cpp new file mode 100644 index 0000000..49fd1e0 --- /dev/null +++ b/hammer/listboxex.cpp @@ -0,0 +1,431 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// ListBoxEx.cpp : implementation file +// + +#include "stdafx.h" +#include "hammer.h" +#include "ListBoxEx.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + +///////////////////////////////////////////////////////////////////////////// +// CListBoxEx + +CListBoxEx::CListBoxEx() +{ + Items.SetSize(16); + nItems = 0; + iItemHeight = -1; + dwStyle = 0; + bControlActive = FALSE; + bIgnoreChange = FALSE; +} + +CListBoxEx::~CListBoxEx() +{ +} + + +BEGIN_MESSAGE_MAP(CListBoxEx, CListBox) + //{{AFX_MSG_MAP(CListBoxEx) + ON_WM_LBUTTONDOWN() + ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelchange) + ON_WM_LBUTTONUP() + ON_WM_CHAR() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CListBoxEx message handlers + +void CListBoxEx::SetStyle(DWORD dwStyle_) +{ + this->dwStyle = dwStyle_; +} + +void CListBoxEx::AddItem(char *pszCaption, int iEditType, PVOID pData, + int iRangeMin, int iRangeMax, const char * pszHelp) +{ + LBEXTITEMSTRUCT lbis; + + memset(&lbis, 0, sizeof lbis); + + strcpy(lbis.szCaption, pszCaption); + lbis.pszSaveCaption = pszCaption; + lbis.iEditType = iEditType; + + switch(iEditType) + { + case lbeYesNo: + case lbeOnOff: + lbis.iDataType = lbdBool; + lbis.iDataValue = PINT(pData)[0]; + break; + case lbeInteger: + lbis.iDataType = lbdInteger; + lbis.iDataValue = PINT(pData)[0]; + break; + case lbeTexture: + case lbeString: + lbis.iDataType = lbdString; + strcpy(lbis.szDataString, LPCTSTR(pData)); + break; + case lbeChoices: + lbis.iDataType = lbdString; + lbis.pChoices = NULL; + break; + } + + lbis.pSaveTo = pData; + + lbis.iRangeMin = iRangeMin; + lbis.iRangeMax = iRangeMax; + lbis.pszHelp = pszHelp; + + Items[nItems++] = lbis; + + AddString(""); // trick windows! muahaha +} + +void CListBoxEx::SetItemChoices(int iItem, CStringArray * pChoices, + int iDefaultChoice) +{ + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + lbis.pChoices = pChoices; + lbis.iDataValue = iDefaultChoice; + V_strcpy_safe( lbis.szDataString, pChoices->GetAt( iDefaultChoice ) ); +} + +void CListBoxEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) +{ + if(iItemHeight == -1) + { + CDC *pDC = GetDC(); + TEXTMETRIC tm; + pDC->GetOutputTextMetrics(&tm); + iItemHeight = tm.tmHeight + 4; + + CRect r; + GetClientRect(r); + iCaptionWidthPixels = r.Width() / 2; + + ReleaseDC(pDC); + } + + lpMeasureItemStruct->itemHeight = iItemHeight; +} + +void CListBoxEx::GetItemText(int iItem, char *pszText) +{ + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + switch(lbis.iDataType) + { + case lbdBool: + if(lbis.iEditType == lbeYesNo) + strcpy(pszText, lbis.iDataValue ? "Yes" : "No"); + else + strcpy(pszText, lbis.iDataValue ? "On" : "Off"); + break; + case lbdString: + strcpy(pszText, lbis.szDataString); + break; + case lbdInteger: + ltoa(lbis.iDataValue, pszText, 10); + break; + } +} + +void CListBoxEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + CDC dc; + dc.Attach(lpDrawItemStruct->hDC); + dc.SaveDC(); + + RECT& r = lpDrawItemStruct->rcItem; + + if(lpDrawItemStruct->itemID != -1 && + (lpDrawItemStruct->itemAction == ODA_DRAWENTIRE || + lpDrawItemStruct->itemAction == ODA_SELECT)) + { + LBEXTITEMSTRUCT& item = Items[lpDrawItemStruct->itemID]; + dc.SetROP2(R2_COPYPEN); + + int iBackIndex = COLOR_WINDOW; + int iForeIndex = COLOR_WINDOWTEXT; + BOOL bDrawCaptionOnly = FALSE; + + if(lpDrawItemStruct->itemAction == ODA_SELECT && + (lpDrawItemStruct->itemState & ODS_SELECTED)) + { + iBackIndex = COLOR_HIGHLIGHT; + iForeIndex = COLOR_HIGHLIGHTTEXT; + bDrawCaptionOnly = item.iDataType != lbdBool ? TRUE : FALSE; + } + + // draw background + CBrush brush; + brush.CreateSolidBrush(GetSysColor(iBackIndex)); + + if(0)//!bDrawCaptionOnly) + dc.FillRect(&r, &brush); + else + { + CRect r2(&r); + r2.right = iCaptionWidthPixels; + dc.FillRect(r2, &brush); + } + + // first, draw text + dc.SetTextColor(GetSysColor(iForeIndex)); + dc.SetBkColor(GetSysColor(iBackIndex)); + dc.TextOut(r.left + 1, r.top+ 1, item.szCaption, + strlen(item.szCaption)); + + if(!bDrawCaptionOnly) + { + // draw value .. + char szText[128]; + GetItemText(lpDrawItemStruct->itemID, szText); + dc.TextOut(r.left + iCaptionWidthPixels + 1, r.top + 1, + szText, strlen(szText)); + } + + // draw border. + CPen pen(PS_SOLID, 1, RGB(200, 200, 200)); + dc.SelectObject(pen); + dc.MoveTo(r.left, r.bottom-1); + dc.LineTo(r.right, r.bottom-1); + dc.MoveTo(r.left + iCaptionWidthPixels, r.top); + dc.LineTo(r.left + iCaptionWidthPixels, r.bottom-1); + } + else if(lpDrawItemStruct->itemAction == ODA_FOCUS) + { + dc.DrawFocusRect(&r); + } + + dc.RestoreDC(-1); +} + +void CListBoxEx::OnLButtonDown(UINT nFlags, CPoint point) +{ + BOOL bOutside; + int iItem = ItemFromPoint(point, bOutside); + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + if(lbis.iDataType == lbdBool) + { + // toggle bool field + lbis.iDataValue = !lbis.iDataValue; + } + + CListBox::OnLButtonDown(nFlags, point); +} + +int CListBoxEx::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct) +{ + return 0; +} + +void CListBoxEx::CreateEditControl() +{ + if(IsWindow(EditCtrl.m_hWnd)) + return; + + // create edit control + int iItem = GetCurSel(); + if(iItem == LB_ERR) + return; + + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + if(lbis.iEditType != lbeString && + lbis.iEditType != lbeInteger && + lbis.iEditType != lbeTexture) + return; + + CRect r; + GetItemRect(iItem, r); + r.InflateRect(-1, -1); + r.left += iCaptionWidthPixels; + + // create edit ctrl + EditCtrl.Create(ES_LEFT | ES_LOWERCASE | WS_VISIBLE | WS_TABSTOP, r, this, + IDC_EDITPARAMETER); + // set font + HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + if (hFont == NULL) + hFont = (HFONT)GetStockObject(ANSI_VAR_FONT); + EditCtrl.SendMessage(WM_SETFONT, (WPARAM)hFont); + + // set current text in edit ctrl + char szBuf[128]; + GetItemText(iItem, szBuf); + EditCtrl.SetWindowText(szBuf); + + EditCtrl.SetForegroundWindow(); + EditCtrl.SetSel(0, -1); + + bControlActive = TRUE; + iControlItem = iItem; +} + +void CListBoxEx::CreateComboControl() +{ + if(IsWindow(ComboCtrl.m_hWnd)) + return; + + // create edit control + int iItem = GetCurSel(); + if(iItem == LB_ERR) + return; + + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + if(lbis.iEditType != lbeChoices) + return; + + CRect r; + GetItemRect(iItem, r); + r.left += iCaptionWidthPixels; + r.bottom += 80; + + // create combo ctrl + ComboCtrl.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST | + WS_TABSTOP, r, this, IDC_EDITPARAMETER); + // set font + HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + if (hFont == NULL) + hFont = (HFONT)GetStockObject(ANSI_VAR_FONT); + ComboCtrl.SendMessage(WM_SETFONT, (WPARAM)hFont); + + // add strings to combo ctrl + CStringArray * pChoices = lbis.pChoices; + Assert(pChoices); + + for(int i = 0; i < pChoices->GetSize(); i++) + ComboCtrl.AddString(pChoices->GetAt(i)); + + // set current selection in combo ctrl + ComboCtrl.SetCurSel(lbis.iDataValue); + ComboCtrl.SetForegroundWindow(); + + bControlActive = TRUE; + iControlItem = iItem; +} + +void CListBoxEx::DestroyControls() +{ + // get rid of window if there is one + if(::IsWindow(EditCtrl.m_hWnd)) + { + EditCtrl.DestroyWindow(); + } + if(::IsWindow(ComboCtrl.m_hWnd)) + { + ComboCtrl.DestroyWindow(); + } + + bControlActive = FALSE; +} + +void CListBoxEx::OnSelchange() +{ + if(bControlActive) + { + // on combobox/edit controls, save string back to data + LBEXTITEMSTRUCT& lbis = Items[iControlItem]; + + if(lbis.iEditType == lbeChoices) + { + ComboCtrl.GetLBText(ComboCtrl.GetCurSel(), lbis.szDataString); + lbis.iDataValue = ComboCtrl.GetCurSel(); + } + else if(lbis.iDataType == lbdString) + { + EditCtrl.GetWindowText(lbis.szDataString, 128); + } + else if(lbis.iDataType == lbdInteger) + { + EditCtrl.GetWindowText(lbis.szDataString, 128); + lbis.iDataValue = atoi(lbis.szDataString); + } + } + + DestroyControls(); + + int iCurItem = GetCurSel(); + LBEXTITEMSTRUCT& lbis = Items[iCurItem]; + + if(lbis.iEditType == lbeChoices) + { + CreateComboControl(); + } + else + { + CreateEditControl(); + } +} + +void CListBoxEx::OnLButtonUp(UINT nFlags, CPoint point) +{ + CListBox::OnLButtonUp(nFlags, point); + + int iItem = GetCurSel(); + if(iItem == LB_ERR) + return; + + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + if(lbis.iDataType == lbdBool) + { + lbis.iDataValue = !lbis.iDataValue; + Invalidate(); + } +} + +void CListBoxEx::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + CListBox::OnChar(nChar, nRepCnt, nFlags); + + return; + + int iItem = GetCurSel(); + if(iItem == LB_ERR) + return; + + LBEXTITEMSTRUCT& lbis = Items[iItem]; + + switch(nChar) + { + case VK_RETURN: + if(!(nFlags & 0x8000)) + break; + if(lbis.iDataType == lbdBool) + { + // toggle bool field + lbis.iDataValue = !lbis.iDataValue; + + Invalidate(); + } + else if(lbis.iEditType == lbeChoices) + { + CreateComboControl(); + } + else if(lbis.iEditType == lbeString || + lbis.iEditType == lbeInteger || + lbis.iEditType == lbeTexture) + { + CreateEditControl(); + } + break; + } +} |