|
|
//========= 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; } }
|