summaryrefslogtreecommitdiff
path: root/hammer/texturewindow.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/texturewindow.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'hammer/texturewindow.cpp')
-rw-r--r--hammer/texturewindow.cpp937
1 files changed, 937 insertions, 0 deletions
diff --git a/hammer/texturewindow.cpp b/hammer/texturewindow.cpp
new file mode 100644
index 0000000..38acc0d
--- /dev/null
+++ b/hammer/texturewindow.cpp
@@ -0,0 +1,937 @@
+//========= 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;
+}
+
+