You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
937 lines
21 KiB
937 lines
21 KiB
//========= 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; |
|
} |
|
|
|
|
|
|