mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 06:06:50 +00:00
938 lines
21 KiB
C++
938 lines
21 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "stdafx.h"
|
|
#pragma warning(push, 1)
|
|
#pragma warning(disable:4701 4702 4530)
|
|
#include <fstream>
|
|
#pragma warning(pop)
|
|
#include "hammer.h"
|
|
#include "TextureWindow.h"
|
|
#include "TextureBrowser.h"
|
|
#include "CustomMessages.h"
|
|
#include "IEditorTexture.h"
|
|
#include "GameConfig.h"
|
|
#include "GlobalFunctions.h"
|
|
#include "TextureSystem.h"
|
|
#include "materialsystem/imaterial.h"
|
|
#include "materialsystem/imaterialsystem.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include <tier0/memdbgon.h>
|
|
|
|
|
|
const DWORD NO_FILE_FILTER = 0xFFFFFFF0L;
|
|
const int iPadding = 4;
|
|
const int iTexNameFontHeight = 7;
|
|
const int iTexIconHeight = 12;
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTextureWindow, CWnd)
|
|
//{{AFX_MSG_MAP(CTextureWindow)
|
|
ON_WM_PAINT()
|
|
ON_WM_SIZE()
|
|
ON_WM_HSCROLL()
|
|
ON_WM_VSCROLL()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_KEYDOWN()
|
|
ON_WM_MOUSEWHEEL()
|
|
ON_WM_CHAR()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Constructor. Initializes data members.
|
|
//-----------------------------------------------------------------------------
|
|
CTextureWindow::CTextureWindow(void)
|
|
{
|
|
bFirstPaint = TRUE;
|
|
|
|
m_szFilter[0] = '\0';
|
|
m_nFilters = 0;
|
|
|
|
m_szKeywords[0] = '\0';
|
|
m_nKeywords = 0;
|
|
|
|
m_pSpecificList = NULL;
|
|
szCurTexture[0] = '\0';
|
|
|
|
m_eTextureFormat = g_pGameConfig->GetTextureFormat();
|
|
|
|
m_bEnableUpdate = true;
|
|
m_nTypeFilter = ~0;
|
|
m_bShowErrors = true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Destructor.
|
|
//-----------------------------------------------------------------------------
|
|
CTextureWindow::~CTextureWindow(void)
|
|
{
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pParentWnd -
|
|
// rect -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::Create(CWnd *pParentWnd, RECT& rect)
|
|
{
|
|
static CString TextureWndClassName;
|
|
|
|
iDisplaySize = 64;
|
|
|
|
if(TextureWndClassName.IsEmpty())
|
|
{
|
|
// create class
|
|
TextureWndClassName = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW |
|
|
CS_VREDRAW, LoadCursor(NULL, IDC_ARROW),
|
|
(HBRUSH) GetStockObject(BLACK_BRUSH),
|
|
AfxGetApp()->LoadIcon(IDI_TEXTUREWINDOW));
|
|
}
|
|
|
|
CWnd::Create(TextureWndClassName, "TextureBrowserWindow",
|
|
SS_SUNKEN | WS_TABSTOP | WS_CHILD | WS_VSCROLL | WS_HSCROLL,
|
|
rect, pParentWnd, IDC_TEXTUREWINDOW);
|
|
|
|
UpdateScrollSizes();
|
|
|
|
// create font
|
|
if(!TexFont.m_hObject)
|
|
TexFont.CreatePointFont(iTexNameFontHeight * 10, "Courier New");
|
|
|
|
CDC *pDC = GetDC();
|
|
pDC->SelectObject(&TexFont);
|
|
pDC->GetCharWidth('A', 'A', &iTexNameCharWidth);
|
|
ReleaseDC(pDC);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : bEnable -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::EnableUpdate(bool bEnable)
|
|
{
|
|
m_bEnableUpdate = bEnable;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Searches for all of the keywords in an array of keywords within
|
|
// a given search string, case-insensitive.
|
|
// Input : pszSearch - String to search for keywords within.
|
|
// pszKeyword - Array of pointers to keywords.
|
|
// nKeywords - Number of keywords in the array.
|
|
// Output : Returns true if all keywords were found, false otherwise.
|
|
//-----------------------------------------------------------------------------
|
|
bool CTextureWindow::MatchKeywords(const char *pszSearch, char **pszKeyword, int nKeywords)
|
|
{
|
|
if (nKeywords != 0)
|
|
{
|
|
for (int i = 0; i < nKeywords; i++)
|
|
{
|
|
if (Q_stristr(pszSearch, pszKeyword[i]) == NULL)
|
|
{
|
|
return(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Changes type filter bits
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CTextureWindow::SetTypeFilter( int filter, bool enable )
|
|
{
|
|
if (enable)
|
|
m_nTypeFilter |= filter;
|
|
else
|
|
m_nTypeFilter &= ~filter;
|
|
|
|
if (m_bEnableUpdate)
|
|
{
|
|
UpdateScrollSizes();
|
|
SelectTexture(szCurTexture, false);
|
|
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
Invalidate();
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pTE -
|
|
// bStart -
|
|
// Output : Returns TRUE on success, FALSE on failure.
|
|
//-----------------------------------------------------------------------------
|
|
BOOL CTextureWindow::EnumTexturePositions(TWENUMPOS *pTE, BOOL bStart)
|
|
{
|
|
RECT &texrect = pTE->texrect;
|
|
|
|
if (bStart)
|
|
{
|
|
pTE->cur_x = iPadding;
|
|
pTE->cur_y = iPadding;
|
|
pTE->largest_y = 0;
|
|
pTE->iTexIndex = 0;
|
|
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
GetClientRect(&pTE->clientrect);
|
|
}
|
|
|
|
SetRect(&texrect, 0, 0, 0, 0);
|
|
}
|
|
|
|
bool bFound = false;
|
|
|
|
do
|
|
{
|
|
pTE->pTex = g_Textures.EnumActiveTextures(&pTE->iTexIndex, m_eTextureFormat);
|
|
|
|
if (pTE->pTex == NULL)
|
|
continue;
|
|
|
|
bFound = false;
|
|
|
|
// If we are iterating a specific list of textures, make sure it is in the list.
|
|
// dvs: inefficient, the specific list should control the loop, not act as a filter
|
|
if (m_pSpecificList != NULL)
|
|
{
|
|
int nIndex = m_pSpecificList->Find(pTE->pTex);
|
|
if (nIndex == -1)
|
|
continue;
|
|
|
|
pTE->nUsageCount = m_pSpecificList->Element(nIndex).nUsageCount;
|
|
}
|
|
|
|
// Filter by texture name.
|
|
char szTemp[MAX_PATH];
|
|
pTE->pTex->GetShortName(szTemp);
|
|
if (MatchKeywords(szTemp, m_Filters, m_nFilters))
|
|
{
|
|
//
|
|
// Filter by keywords.
|
|
//
|
|
|
|
// NOTE: Try not to access the material here when finding the position
|
|
// because it causes the materials to be cached (slow!!)
|
|
if (m_nKeywords)
|
|
{
|
|
pTE->pTex->GetKeywords(szTemp);
|
|
if (MatchKeywords(szTemp, m_Keyword, m_nKeywords))
|
|
{
|
|
bFound = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bFound = true;
|
|
}
|
|
}
|
|
|
|
// Filter based on opacity, etc.
|
|
// NOTE: Try not to access the material here when finding the position
|
|
// because it causes the materials to be cached (slow!!)
|
|
if (bFound && ((m_nTypeFilter & TYPEFILTER_ALL) != TYPEFILTER_ALL))
|
|
{
|
|
IMaterial* pMaterial = pTE->pTex->GetMaterial();
|
|
if (pMaterial)
|
|
{
|
|
bFound = false;
|
|
if ( pMaterial->GetMaterialVarFlag( MATERIAL_VAR_SELFILLUM ) )
|
|
{
|
|
if (m_nTypeFilter & TYPEFILTER_SELFILLUM)
|
|
bFound = true;
|
|
}
|
|
if ( pMaterial->GetMaterialVarFlag( MATERIAL_VAR_BASEALPHAENVMAPMASK ) )
|
|
{
|
|
if (m_nTypeFilter & TYPEFILTER_ENVMASK)
|
|
bFound = true;
|
|
}
|
|
|
|
if ( pMaterial->GetMaterialVarFlag( MATERIAL_VAR_TRANSLUCENT ) )
|
|
{
|
|
if (m_nTypeFilter & TYPEFILTER_TRANSLUCENT)
|
|
bFound = true;
|
|
}
|
|
else
|
|
{
|
|
if (m_nTypeFilter & TYPEFILTER_OPAQUE)
|
|
bFound = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Blow off zero-size materials, but only if they've been loaded...
|
|
// Otherwise we have to cache everything which will take forever...
|
|
if ( bFound && pTE->pTex->IsLoaded() )
|
|
{
|
|
if ((pTE->pTex->GetWidth() == 0) || (pTE->pTex->GetHeight() == 0))
|
|
{
|
|
bFound = false;
|
|
}
|
|
}
|
|
|
|
} while ((pTE->pTex != NULL) && (!bFound));
|
|
|
|
if ((!bFound) || (pTE->pTex == NULL))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
doresize:
|
|
|
|
SetRect( &texrect, pTE->cur_x, pTE->cur_y,
|
|
pTE->cur_x + iDisplaySize,
|
|
pTE->cur_y + iDisplaySize );
|
|
|
|
// if we've got one texture on this row already, and this one goes out of
|
|
// the client area, jump to the next row. we want to have at least one texture on
|
|
// each row, or we will sit in an infinite loop.
|
|
if(pTE->cur_x > iPadding && texrect.right > pTE->clientrect.right)
|
|
{
|
|
pTE->cur_x = iPadding;
|
|
pTE->cur_y = pTE->largest_y + iPadding;
|
|
goto doresize;
|
|
}
|
|
|
|
texrect.bottom += (8 + iTexNameFontHeight + iTexIconHeight);
|
|
|
|
if(texrect.bottom > pTE->largest_y)
|
|
pTE->largest_y = texrect.bottom;
|
|
|
|
// update cur_x
|
|
pTE->cur_x = texrect.right + iPadding;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Sets the dimensions of each texture within the texture window.
|
|
// Input : iSize - 32 to display as 32 x 32 textures.
|
|
// 64 to display as 64 x 64 textures.
|
|
// 128 to display as 128 x 128 textures.
|
|
// 512 to display as 512 x 512 textures
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::SetDisplaySize(int iSize)
|
|
{
|
|
iDisplaySize = iSize;
|
|
UpdateScrollSizes();
|
|
SelectTexture(szCurTexture, FALSE);
|
|
RedrawWindow();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Sets the name filter that is used to filter the texture window contents.
|
|
// Input : pszFilter - Space, comma, or semicolon delimited names to filter against.
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::SetNameFilter(LPCTSTR pszFilter)
|
|
{
|
|
if (m_bEnableUpdate)
|
|
{
|
|
// kill highlight
|
|
HighlightCurTexture();
|
|
}
|
|
|
|
// set filter
|
|
strcpy(m_szFilter, pszFilter);
|
|
strupr(m_szFilter);
|
|
|
|
// delimit the filter
|
|
m_nFilters = 0;
|
|
char *p = strtok(m_szFilter, " ,;");
|
|
while (p != NULL)
|
|
{
|
|
m_Filters[m_nFilters++] = p;
|
|
p = strtok(NULL, " ,;");
|
|
}
|
|
|
|
if (m_bEnableUpdate)
|
|
{
|
|
UpdateScrollSizes();
|
|
SelectTexture(szCurTexture, false);
|
|
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
Invalidate();
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Sets the keywords that are used to filter the texture window contents.
|
|
// Input : pszFilter - Space, comma, or semicolon delimited keywords to filter against.
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::SetKeywords(LPCTSTR pszKeywords)
|
|
{
|
|
if (m_bEnableUpdate)
|
|
{
|
|
// kill highlight
|
|
HighlightCurTexture();
|
|
}
|
|
|
|
// set keyword filter
|
|
strcpy(m_szKeywords, pszKeywords);
|
|
strupr(m_szKeywords);
|
|
|
|
// delimit the filter
|
|
m_nKeywords = 0;
|
|
char *p = strtok(m_szKeywords, " ,;");
|
|
while (p != NULL)
|
|
{
|
|
m_Keyword[m_nKeywords++] = p;
|
|
p = strtok(NULL, " ,;");
|
|
}
|
|
|
|
if (m_bEnableUpdate)
|
|
{
|
|
UpdateScrollSizes();
|
|
SelectTexture(szCurTexture, false);
|
|
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
Invalidate();
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::UpdateScrollSizes(void)
|
|
{
|
|
TWENUMPOS TE;
|
|
|
|
total_x = total_y = 0;
|
|
|
|
if(EnumTexturePositions(&TE, TRUE))
|
|
do {
|
|
if(TE.texrect.right > total_x)
|
|
total_x = TE.texrect.right;
|
|
if(TE.texrect.bottom > total_y)
|
|
total_y = TE.texrect.bottom;
|
|
} while(EnumTexturePositions(&TE));
|
|
|
|
// update total_x and total_y
|
|
total_x += iPadding;
|
|
total_y += iPadding;
|
|
|
|
SCROLLINFO si;
|
|
si.cbSize = sizeof(SCROLLINFO);
|
|
si.fMask = SIF_ALL;
|
|
si.nMin = 0;
|
|
si.nPos = 0;
|
|
si.nMax = total_x;
|
|
si.nPage = TE.clientrect.right;
|
|
SetScrollInfo(SB_HORZ, &si, TRUE);
|
|
|
|
si.nMax = total_y;
|
|
si.nPage = TE.clientrect.bottom;
|
|
SetScrollInfo(SB_VERT, &si, TRUE);
|
|
|
|
char szbuf[100];
|
|
sprintf(szbuf, "Size = %d %d\n", total_y, TE.clientrect.bottom);
|
|
TRACE0(szbuf);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnPaint(void)
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
// setup font
|
|
dc.SelectObject(&TexFont);
|
|
dc.SetTextColor(RGB(255, 255, 255));
|
|
//dc.SetBkColor(RGB(0,0,0));
|
|
dc.SetBkMode(TRANSPARENT);
|
|
|
|
CRect clientrect;
|
|
GetClientRect(clientrect);
|
|
|
|
dc.SetWindowOrg(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
|
|
|
|
TWENUMPOS TE;
|
|
BOOL bNotDone = EnumTexturePositions(&TE, TRUE);
|
|
BOOL bFoundHighlight = FALSE;
|
|
rectHighlight.left = -1;
|
|
BOOL bFirst = TRUE;
|
|
char szDrawTexture[128];
|
|
char szFirstDrawnTexture[128];
|
|
|
|
while (bNotDone)
|
|
{
|
|
TE.pTex->GetShortName(szDrawTexture);
|
|
|
|
if (!strcmpi(szCurTexture, szDrawTexture))
|
|
{
|
|
rectHighlight = TE.texrect;
|
|
rectHighlight.InflateRect(2, 4);
|
|
bFoundHighlight = TRUE;
|
|
}
|
|
|
|
if (dc.RectVisible(&TE.texrect))
|
|
{
|
|
// ensure loaded
|
|
TE.pTex->Load();
|
|
|
|
CPalette *pOld = dc.SelectPalette(TE.pTex->HasPalette() ? TE.pTex->GetPalette() : g_pGameConfig->Palette, FALSE);
|
|
dc.RealizePalette();
|
|
|
|
int flags = drawCaption | drawIcons;
|
|
if (m_bShowErrors)
|
|
flags |= drawErrors;
|
|
|
|
DrawTexData_t DrawTexData;
|
|
DrawTexData.nFlags = flags | (m_pSpecificList ? drawUsageCount : 0);
|
|
DrawTexData.nUsageCount = TE.nUsageCount;
|
|
TE.pTex->Draw(&dc, TE.texrect, iTexNameFontHeight, iTexIconHeight, DrawTexData);
|
|
|
|
dc.SelectPalette(pOld, FALSE);
|
|
}
|
|
|
|
//
|
|
// Save the name of the first drawn texture in case we need to highlight it.
|
|
//
|
|
if (bFirst)
|
|
{
|
|
bFirst = FALSE;
|
|
strcpy(szFirstDrawnTexture, szDrawTexture);
|
|
}
|
|
|
|
// next texture & position
|
|
bNotDone = EnumTexturePositions(&TE);
|
|
}
|
|
|
|
if(bFoundHighlight)
|
|
{
|
|
HighlightCurTexture(&dc);
|
|
}
|
|
else
|
|
{
|
|
// select first texture
|
|
SelectTexture(szFirstDrawnTexture);
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nType -
|
|
// cx -
|
|
// cy -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CWnd::OnSize(nType, cx, cy);
|
|
UpdateScrollSizes();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nSBCode -
|
|
// nPos -
|
|
// pScrollBar -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
int iPos = int(nPos);
|
|
SCROLLINFO si;
|
|
|
|
GetScrollInfo(SB_HORZ, &si);
|
|
int iCurPos = GetScrollPos(SB_HORZ);
|
|
int iLimit = GetScrollLimit(SB_HORZ);
|
|
|
|
switch(nSBCode)
|
|
{
|
|
case SB_LINELEFT:
|
|
iPos = -int(si.nPage / 4);
|
|
break;
|
|
case SB_LINERIGHT:
|
|
iPos = int(si.nPage / 4);
|
|
break;
|
|
case SB_PAGELEFT:
|
|
iPos = -int(si.nPage / 2);
|
|
break;
|
|
case SB_PAGERIGHT:
|
|
iPos = int(si.nPage / 2);
|
|
break;
|
|
case SB_THUMBTRACK:
|
|
case SB_THUMBPOSITION:
|
|
iPos -= iCurPos;
|
|
break;
|
|
}
|
|
|
|
if(iCurPos + iPos < 0)
|
|
iPos = -iCurPos;
|
|
if(iCurPos + iPos > iLimit)
|
|
iPos = iLimit - iCurPos;
|
|
if(iPos)
|
|
{
|
|
SetScrollPos(SB_HORZ, iCurPos + iPos);
|
|
ScrollWindow(-iPos, 0);
|
|
UpdateWindow();
|
|
}
|
|
CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nSBCode -
|
|
// nPos -
|
|
// pScrollBar -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
SCROLLINFO si;
|
|
|
|
GetScrollInfo(SB_VERT, &si);
|
|
int iCurPos = GetScrollPos(SB_VERT);
|
|
int iLimit = GetScrollLimit(SB_VERT);
|
|
int iPos = int(si.nPos);
|
|
|
|
switch(nSBCode)
|
|
{
|
|
case SB_LINEUP:
|
|
iPos = -int(si.nPage / 4);
|
|
break;
|
|
case SB_LINEDOWN:
|
|
iPos = int(si.nPage / 4);
|
|
break;
|
|
case SB_PAGEUP:
|
|
iPos = -int(si.nPage / 2);
|
|
break;
|
|
case SB_PAGEDOWN:
|
|
iPos = int(si.nPage / 2);
|
|
break;
|
|
case SB_THUMBTRACK:
|
|
case SB_THUMBPOSITION:
|
|
iPos = si.nTrackPos - iCurPos;
|
|
break;
|
|
case SB_ENDSCROLL:
|
|
iPos = 0;
|
|
break;
|
|
}
|
|
|
|
if(iCurPos + iPos < 0)
|
|
iPos = -iCurPos;
|
|
if(iCurPos + iPos > iLimit)
|
|
iPos = iLimit - iCurPos;
|
|
if(iPos)
|
|
{
|
|
SetScrollPos(SB_VERT, iCurPos + iPos);
|
|
ScrollWindow(0, -iPos);
|
|
UpdateWindow();
|
|
}
|
|
|
|
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pDC -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::HighlightCurTexture(CDC *pDC)
|
|
{
|
|
CDC dc;
|
|
BOOL bMadeDC = FALSE;
|
|
|
|
// nothing to draw
|
|
if(rectHighlight.left < 0)
|
|
return;
|
|
|
|
if(!pDC)
|
|
{
|
|
dc.Attach(::GetDC(m_hWnd));
|
|
dc.SetWindowOrg(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
|
|
bMadeDC = TRUE;
|
|
pDC = &dc;
|
|
}
|
|
|
|
pDC->SelectStockObject(WHITE_PEN);
|
|
pDC->SelectStockObject(NULL_BRUSH);
|
|
pDC->SetROP2(R2_XORPEN);
|
|
pDC->Rectangle(rectHighlight);
|
|
|
|
if(bMadeDC)
|
|
::ReleaseDC(m_hWnd, dc.Detach());
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Selects a given texture by name, scrolling the window if necessary
|
|
// to make the selected texture visible.
|
|
// Input : pszTexture - Texture to select.
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::SelectTexture(LPCTSTR pszTexture, BOOL bAllowRedraw)
|
|
{
|
|
TWENUMPOS TE;
|
|
BOOL bNotDone = EnumTexturePositions(&TE, TRUE);
|
|
int iTextureIndex = 0;
|
|
|
|
IEditorTexture *pTex = g_Textures.FindActiveTexture(pszTexture);
|
|
|
|
CRect r(100, 100, 500, 500);
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
GetClientRect(r);
|
|
}
|
|
int iClientHeight = r.Height();
|
|
|
|
if (pTex == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
while (bNotDone)
|
|
{
|
|
if (pTex == TE.pTex)
|
|
{
|
|
// found it - make sure it's visible
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
int iScrollPos = GetScrollPos(SB_VERT);
|
|
if (iScrollPos + iClientHeight < TE.texrect.top || TE.texrect.bottom < iScrollPos)
|
|
{
|
|
SetScrollPos(SB_VERT, TE.texrect.top);
|
|
ScrollWindow(0, iScrollPos - TE.texrect.top);
|
|
|
|
if (bAllowRedraw)
|
|
{
|
|
RedrawWindow();
|
|
}
|
|
}
|
|
|
|
// first remove current highlight
|
|
HighlightCurTexture();
|
|
}
|
|
|
|
pTex->GetShortName(szCurTexture);
|
|
|
|
// highlight new texture
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
rectHighlight = CRect(&TE.texrect);
|
|
rectHighlight.InflateRect(2, 4);
|
|
HighlightCurTexture();
|
|
}
|
|
|
|
GetParent()->PostMessage(TWN_SELCHANGED);
|
|
|
|
return;
|
|
}
|
|
|
|
// next texture & position
|
|
bNotDone = EnumTexturePositions(&TE);
|
|
++iTextureIndex;
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nFlags -
|
|
// point -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
// find clicked texture
|
|
TWENUMPOS TE;
|
|
BOOL bNotDone = EnumTexturePositions(&TE, TRUE);
|
|
int iTextureIndex = 0;
|
|
|
|
int iHorzPos = GetScrollPos(SB_HORZ);
|
|
int iVertPos = GetScrollPos(SB_VERT);
|
|
|
|
char szNewTexture[128];
|
|
|
|
point += CPoint(iHorzPos, iVertPos);
|
|
|
|
while (bNotDone)
|
|
{
|
|
if (PtInRect(&TE.texrect, point))
|
|
{
|
|
TE.pTex->GetShortName(szNewTexture);
|
|
break;
|
|
}
|
|
|
|
// next texture & position
|
|
bNotDone = EnumTexturePositions(&TE);
|
|
++iTextureIndex;
|
|
}
|
|
|
|
if(!bNotDone)
|
|
{
|
|
// no texture was hit
|
|
return;
|
|
}
|
|
|
|
// first remove current highlight
|
|
HighlightCurTexture();
|
|
|
|
// highlight new texture
|
|
strcpy(szCurTexture, szNewTexture);
|
|
rectHighlight = CRect(&TE.texrect);
|
|
rectHighlight.InflateRect(2, 4);
|
|
HighlightCurTexture();
|
|
|
|
// tell parent we changed selection
|
|
GetParent()->PostMessage(TWN_SELCHANGED);
|
|
|
|
SetFocus();
|
|
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Notifies our parent window of a double-click event.
|
|
// Input : nFlags -
|
|
// point -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
{
|
|
GetParent()->PostMessage(TWN_LBUTTONDBLCLK);
|
|
CWnd::OnLButtonDblClk(nFlags, point);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nChar -
|
|
// nRepCnt -
|
|
// nFlags -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nFlags -
|
|
// zDelta -
|
|
// point -
|
|
// Output : Returns TRUE on success, FALSE on failure.
|
|
//-----------------------------------------------------------------------------
|
|
BOOL CTextureWindow::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
|
|
{
|
|
int nScrollCode;
|
|
|
|
if (zDelta > 0)
|
|
{
|
|
nScrollCode = SB_LINEUP;
|
|
}
|
|
else
|
|
{
|
|
nScrollCode = SB_LINEDOWN;
|
|
}
|
|
|
|
SCROLLINFO si;
|
|
GetScrollInfo(SB_VERT, &si);
|
|
int iCurPos = GetScrollPos(SB_VERT);
|
|
int iLimit = GetScrollLimit(SB_VERT);
|
|
int iPos = int(si.nPos);
|
|
|
|
switch (nScrollCode)
|
|
{
|
|
case SB_LINEUP:
|
|
{
|
|
iPos = -(int)si.nPage / 4;
|
|
break;
|
|
}
|
|
|
|
case SB_LINEDOWN:
|
|
{
|
|
iPos = si.nPage / 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (iCurPos + iPos < 0)
|
|
{
|
|
iPos = -iCurPos;
|
|
}
|
|
|
|
if (iCurPos + iPos > iLimit)
|
|
{
|
|
iPos = iLimit - iCurPos;
|
|
}
|
|
|
|
if (iPos)
|
|
{
|
|
SetScrollPos(SB_VERT, iCurPos + iPos);
|
|
ScrollWindow(0, -iPos);
|
|
UpdateWindow();
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : nChar -
|
|
// nRepCnt -
|
|
// nFlags -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CWnd::OnChar(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Sets the contents of the texture window to a specific list of textures.
|
|
// Input : pList - Textures with which to populate the texture window.
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::SetSpecificList(TextureWindowTexList *pList)
|
|
{
|
|
m_pSpecificList = pList;
|
|
|
|
if (m_hWnd != NULL)
|
|
{
|
|
UpdateScrollSizes();
|
|
SelectTexture(szCurTexture, FALSE);
|
|
RedrawWindow();
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : eTextureFormat -
|
|
//-----------------------------------------------------------------------------
|
|
void CTextureWindow::SetTextureFormat(TEXTUREFORMAT eTextureFormat)
|
|
{
|
|
m_eTextureFormat = eTextureFormat;
|
|
}
|
|
|
|
|