csgo-2018-source/hammer/listboxex.cpp

432 lines
8.8 KiB
C++
Raw Permalink Normal View History

2021-07-25 12:11:47 +08:00
//========= Copyright <20> 1996-2005, 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;
strcpy(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;
}
}