Serious-Engine/Sources/WorldEditor/DlgPgTexture.cpp

501 lines
17 KiB
C++
Raw Normal View History

2016-03-12 01:20:51 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2016-03-11 14:57:17 +01:00
// DlgPgTexture.cpp : implementation file
//
#include "stdafx.h"
#include "DlgPgTexture.h"
#ifdef _DEBUG
#undef new
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define DIFFERENT_TEXTURE "Different\ntextures"
#define NO_TEXTURE "No texture"
#define NO_SELECTION "Empty\nselection"
/////////////////////////////////////////////////////////////////////////////
// CDlgPgTexture property page
IMPLEMENT_DYNCREATE(CDlgPgTexture, CPropertyPage)
CDlgPgTexture::CDlgPgTexture() : CPropertyPage(CDlgPgTexture::IDD)
{
//{{AFX_DATA_INIT(CDlgPgTexture)
m_strTextureFile = _T("");
m_fOffsetV = 0.0f;
m_fOffsetU = 0.0f;
m_radioTexture = -1;
m_fRotationU = 0.0f;
m_fRotationV = 0.0f;
m_fStretchU = 0.0f;
m_fStretchV = 0.0f;
m_strTextureDim = _T("");
//}}AFX_DATA_INIT
m_ctrlCombineColor.SetPickerType( CColoredButton::PT_MFC);
}
CDlgPgTexture::~CDlgPgTexture()
{
}
void CDlgPgTexture::DoDataExchange(CDataExchange* pDX)
{
if( theApp.m_bDisableDataExchange) return;
CPropertyPage::DoDataExchange(pDX);
// mark that property page has been modified
SetModified( TRUE);
// obtain document
CWorldEditorDoc* pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
// polygon mode must be on
if( pDoc->GetEditingMode() != POLYGON_MODE) return;
// if dialog is receiving data and control windows are valid
if( (pDX->m_bSaveAndValidate == FALSE) && IsWindow( m_comboScroll.m_hWnd) )
{
m_comboScroll.ResetContent();
for(INDEX iScroll=0; iScroll<256; iScroll++)
{
CTString strScrollName = pDoc->m_woWorld.wo_attTextureTransformations[iScroll].tt_strName;
if( strScrollName != CTString("") ) m_comboScroll.AddString( CString(strScrollName));
}
m_comboBlend.ResetContent();
for(INDEX iBlend=0; iBlend<256; iBlend++)
{
CTString strBlendName = pDoc->m_woWorld.wo_atbTextureBlendings[iBlend].tb_strName;
if( strBlendName != CTString("") ) m_comboBlend.AddString( CString(strBlendName));
}
m_radioTexture = pDoc->m_iTexture;
m_udTextureData.MarkUpdated();
BOOL bSelectionExists = pDoc->m_selPolygonSelection.Count() != 0;
// controls for editing polygon mapping can exist only while one polygon is selected
GetDlgItem( IDC_STATIC_ROTATION_SHEAR)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_STATIC_STRETCH)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_ROTATION_U)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_ROTATION_V)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_STATIC_OFFSET)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_OFFSET_U)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_OFFSET_V)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_STRETCH_U)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_STRETCH_V)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_STATIC_BLEND)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_BLEND_TYPE)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_STATIC_SCROLL)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_SCROLL_COMBO)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_TEXTURE_FILE_T)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_BROWSE_TEXTURE)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_REMOVE_TEXTURE)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_CLAMP_U)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_CLAMP_V)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_REFLECTIVE)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_AFTER_SHADOW)->EnableWindow( bSelectionExists);
GetDlgItem( IDC_PREVIEW_FRAME)->EnableWindow( bSelectionExists);
m_ctrlCombineColor.EnableWindow( bSelectionExists);
m_comboScroll.EnableWindow( bSelectionExists);
m_comboBlend.EnableWindow( bSelectionExists);
GetDlgItem( IDC_RADIO_TEXTURE)->EnableWindow( TRUE);
GetDlgItem( IDC_TEXTURE_2)->EnableWindow( TRUE);
GetDlgItem( IDC_TEXTURE_3)->EnableWindow( TRUE);
if( !bSelectionExists)
{
m_strTextureFile = NO_SELECTION;
m_strTextureDim = "";
}
else
{
UBYTE ubFirstScroll;
BOOL bSameScroll = TRUE;
UBYTE ubFirstBlend;
BOOL bSameBlend = TRUE;
UBYTE ubFlagsOn = MAX_UBYTE;
UBYTE ubFlagsOff = MAX_UBYTE;
GetDlgItem( IDC_PREVIEW_FRAME)->EnableWindow( TRUE);
INDEX ctPolygons = 0;
// for each of the selected polygons
FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
{
CBrushPolygon &bpo = *itbpo;
ubFlagsOn &= bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubFlags;
ubFlagsOff &= ~bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubFlags;
CMappingDefinitionUI mdui;
bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.ToUI( mdui);
CTextureData *ptdTexture = (CTextureData *) bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData();
if( ptdTexture == NULL)
{
GetDlgItem( IDC_PREVIEW_FRAME)->EnableWindow( FALSE);
m_strTextureFile = NO_TEXTURE;
m_strTextureDim = "";
}
else
{
CTString strTexture = ptdTexture->GetName();
if( ctPolygons == 0)
{
m_ctrlCombineColor.SetColor( bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_colColor);
m_strTextureFile = strTexture;
m_strTextureDim = ptdTexture->GetDescription();
}
else
{
if( m_ctrlCombineColor.GetColor() != bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_colColor)
{
m_ctrlCombineColor.SetMixedColor();
}
if( m_strTextureFile != CString( strTexture))
{
GetDlgItem( IDC_PREVIEW_FRAME)->EnableWindow( FALSE);
m_strTextureFile = DIFFERENT_TEXTURE;
m_strTextureDim = "";
}
}
}
if( ctPolygons == 0)
{
m_fOffsetU = mdui.mdui_fUOffset; m_bOffsetU = TRUE;
m_fOffsetV = mdui.mdui_fVOffset; m_bOffsetV = TRUE;
m_fRotationU = mdui.mdui_aURotation;m_bRotationU = TRUE;
m_fRotationV = mdui.mdui_aVRotation;m_bRotationV = TRUE;
m_fStretchU = mdui.mdui_fUStretch; m_bStretchU = TRUE;
m_fStretchV = mdui.mdui_fVStretch; m_bStretchV = TRUE;
ubFirstScroll = bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubScroll;
ubFirstBlend = bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubBlend;
}
else
{
if( m_fOffsetU != mdui.mdui_fUOffset) m_bOffsetU = FALSE;
if( m_fOffsetV != mdui.mdui_fVOffset) m_bOffsetV = FALSE;
if( m_fRotationU != mdui.mdui_aURotation) m_bRotationU = FALSE;
if( m_fRotationV != mdui.mdui_aVRotation) m_bRotationV = FALSE;
if( m_fStretchU != mdui.mdui_fUStretch) m_bStretchU = FALSE;
if( m_fStretchV != mdui.mdui_fVStretch) m_bStretchV = FALSE;
if( bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubScroll != ubFirstScroll) bSameScroll = FALSE;
if( bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubBlend != ubFirstBlend) bSameBlend = FALSE;
}
ctPolygons++;
}
if( bSameScroll) m_comboScroll.SetCurSel( ubFirstScroll); else m_comboScroll.SetCurSel(-1);
if( bSameBlend) m_comboBlend.SetCurSel( ubFirstBlend); else m_comboBlend.SetCurSel(-1);
// set states of all flags using on and off masks
if((ubFlagsOn & BPTF_CLAMPU) && !(ubFlagsOff & BPTF_CLAMPU)) m_checkClampU.SetCheck( 1);
else if(!(ubFlagsOn & BPTF_CLAMPU) && (ubFlagsOff & BPTF_CLAMPU)) m_checkClampU.SetCheck( 0);
else m_checkClampU.SetCheck( 2);
if((ubFlagsOn & BPTF_CLAMPV) && !(ubFlagsOff & BPTF_CLAMPV)) m_checkClampV.SetCheck( 1);
else if(!(ubFlagsOn & BPTF_CLAMPV) && (ubFlagsOff & BPTF_CLAMPV)) m_checkClampV.SetCheck( 0);
else m_checkClampV.SetCheck( 2);
if((ubFlagsOn & BPTF_REFLECTION) && !(ubFlagsOff & BPTF_REFLECTION)) m_checkReflective.SetCheck( 1);
else if(!(ubFlagsOn & BPTF_REFLECTION) && (ubFlagsOff & BPTF_REFLECTION)) m_checkReflective.SetCheck( 0);
else m_checkReflective.SetCheck( 2);
if((ubFlagsOn & BPTF_AFTERSHADOW) && !(ubFlagsOff & BPTF_AFTERSHADOW)) m_checkAfterShadow.SetCheck( 1);
else if(!(ubFlagsOn & BPTF_AFTERSHADOW) && (ubFlagsOff & BPTF_AFTERSHADOW)) m_checkAfterShadow.SetCheck( 0);
else m_checkAfterShadow.SetCheck( 2);
}
}
//{{AFX_DATA_MAP(CDlgPgTexture)
DDX_Control(pDX, IDC_AFTER_SHADOW, m_checkAfterShadow);
DDX_Control(pDX, ID_COMBINE_COLOR, m_ctrlCombineColor);
DDX_Control(pDX, IDC_BLEND_TYPE, m_comboBlend);
DDX_Control(pDX, IDC_REFLECTIVE, m_checkReflective);
DDX_Control(pDX, IDC_CLAMP_V, m_checkClampV);
DDX_Control(pDX, IDC_CLAMP_U, m_checkClampU);
DDX_Control(pDX, IDC_SCROLL_COMBO, m_comboScroll);
DDX_Text(pDX, IDC_TEXTURE_FILE_T, m_strTextureFile);
DDX_Radio(pDX, IDC_RADIO_TEXTURE, m_radioTexture);
DDX_Text(pDX, IDC_TEXTURE_DIM_T, m_strTextureDim);
//}}AFX_DATA_MAP
DDX_SkyFloat(pDX, IDC_OFFSET_U, m_fOffsetU, m_bOffsetU);
DDX_SkyFloat(pDX, IDC_OFFSET_V, m_fOffsetV, m_bOffsetV);
DDX_SkyFloat(pDX, IDC_STRETCH_U, m_fStretchU, m_bStretchU);
DDX_SkyFloat(pDX, IDC_STRETCH_V, m_fStretchV, m_bStretchV);
DDX_SkyFloat(pDX, IDC_ROTATION_U, m_fRotationU, m_bRotationU);
DDX_SkyFloat(pDX, IDC_ROTATION_V, m_fRotationV, m_bRotationV);
// if dialog is giving data and control windows are valid
if( (pDX->m_bSaveAndValidate != FALSE) && IsWindow( m_comboScroll.m_hWnd) )
{
m_udTextureData.MarkUpdated();
// paste new active texture over polygon selection
if( (m_strTextureFile != DIFFERENT_TEXTURE) &&
(m_strTextureFile != NO_SELECTION) )
{
if( m_strTextureFile == NO_TEXTURE)
{
pDoc->PasteTextureOverSelection_t( CTString(""));
}
else
{
pDoc->PasteTextureOverSelection_t( CTString( CStringA(m_strTextureFile)));
}
}
// obtain masks for setting and clearing texture flags
ULONG ulBitsToClear = MAX_ULONG;
ULONG ulBitsToSet = 0;
if( m_checkClampU.GetCheck() == 0) ulBitsToClear &= ~BPTF_CLAMPU;
if( m_checkClampU.GetCheck() == 1) ulBitsToSet |= BPTF_CLAMPU;
if( m_checkClampV.GetCheck() == 0) ulBitsToClear &= ~BPTF_CLAMPV;
if( m_checkClampV.GetCheck() == 1) ulBitsToSet |= BPTF_CLAMPV;
if( m_checkReflective.GetCheck() == 0) ulBitsToClear &= ~BPTF_REFLECTION;
if( m_checkReflective.GetCheck() == 1) ulBitsToSet |= BPTF_REFLECTION;
if( m_checkAfterShadow.GetCheck() == 0) ulBitsToClear &= ~BPTF_AFTERSHADOW;
if( m_checkAfterShadow.GetCheck() == 1) ulBitsToSet |= BPTF_AFTERSHADOW;
// for each of the selected polygons
FOREACHINDYNAMICCONTAINER(pDoc->m_selPolygonSelection, CBrushPolygon, itbpo)
{
CBrushPolygon &bpo = *itbpo;
bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubFlags &= ulBitsToClear;
bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubFlags |= ulBitsToSet;
CMappingDefinitionUI mdui;
bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.ToUI( mdui);
if( m_bOffsetU) mdui.mdui_fUOffset = m_fOffsetU;
if( m_bOffsetV) mdui.mdui_fVOffset = m_fOffsetV;
if( m_bRotationU) mdui.mdui_aURotation = m_fRotationU;
if( m_bRotationV) mdui.mdui_aVRotation = m_fRotationV;
if( m_bStretchU) mdui.mdui_fUStretch = m_fStretchU;
if( m_bStretchV) mdui.mdui_fVStretch = m_fStretchV;
bpo.bpo_abptTextures[pDoc->m_iTexture].bpt_mdMapping.FromUI( mdui);
INDEX iScroll = m_comboScroll.GetCurSel();
if( iScroll != -1) bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubScroll = (UBYTE)iScroll;
INDEX iBlend = m_comboBlend.GetCurSel();
if( iBlend != -1) bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_ubBlend = (UBYTE)iBlend;
if( m_ctrlCombineColor.IsColorValid())
{
bpo.bpo_abptTextures[pDoc->m_iTexture].s.bpt_colColor = m_ctrlCombineColor.GetColor();
}
}
pDoc->UpdateAllViews( NULL);
pDoc->SetModifiedFlag( TRUE);
}
// set file name of texture for thumbnail window
CString strWindowText;
GetDlgItem( IDC_TEXTURE_FILE_T)->GetWindowText( strWindowText);
m_wndViewTexture.m_strTexture = CStringA(strWindowText);
if( IsWindow( m_wndViewTexture.m_hWnd))
{
m_wndViewTexture.Invalidate( FALSE);
}
}
BEGIN_MESSAGE_MAP(CDlgPgTexture, CPropertyPage)
//{{AFX_MSG_MAP(CDlgPgTexture)
ON_BN_CLICKED(IDC_BROWSE_TEXTURE, OnBrowseTexture)
ON_BN_CLICKED(IDC_RADIO_TEXTURE, OnRadioTexture)
ON_BN_CLICKED(IDC_TEXTURE_2, OnTexture2)
ON_BN_CLICKED(IDC_TEXTURE_3, OnTexture3)
ON_BN_CLICKED(IDC_REMOVE_TEXTURE, OnRemoveTexture)
ON_CBN_SELCHANGE(IDC_SCROLL_COMBO, OnSelchangeScrollCombo)
ON_WM_DROPFILES()
ON_CBN_SELCHANGE(IDC_BLEND_TYPE, OnSelchangeBlendType)
ON_CBN_DROPDOWN(IDC_SCROLL_COMBO, OnDropdownScrollCombo)
ON_CBN_DROPDOWN(IDC_BLEND_TYPE, OnDropdownBlendType)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgPgTexture message handlers
BOOL CDlgPgTexture::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// obtain document
CWorldEditorDoc* pDoc = theApp.GetDocument();
m_ctrlCombineColor.SetDialogPtr( this);
m_checkReflective.SetDialogPtr( this);
m_checkAfterShadow.SetDialogPtr( this);
m_checkClampV.SetDialogPtr( this);
m_checkClampU.SetDialogPtr( this);
PIX pixLeft = 0;
PIX pixTop = 30;
m_wndViewTexture.Create(NULL, NULL, WS_BORDER|WS_VISIBLE,
CRect( pixLeft, pixTop, pixLeft+64, pixTop+64),
this, IDW_SHOW_TEXTURE);
DragAcceptFiles();
if( pDoc == NULL)
{
m_radioTexture = 0;
}
else
{
m_radioTexture = pDoc->m_iTexture;
}
return TRUE;
}
BOOL CDlgPgTexture::OnIdle(LONG lCount)
{
CWorldEditorDoc* pDoc = theApp.GetDocument();
if( (pDoc == NULL) || !IsWindow(m_hWnd)) return FALSE;
// if polygon selection have been changed update dialog
if( !pDoc->m_chSelections.IsUpToDate( m_udTextureData))
{
UpdateData( FALSE);
}
return TRUE;
}
void CDlgPgTexture::OnBrowseTexture()
{
char achrDirectory[256], achrMessage[256];
if( &CDlgPgTexture::OnRadioTexture == 0)
{
strcpy( achrDirectory, "Hyper texture directory");
strcpy( achrMessage, "Browse hyper texture");
}
else
{
strcpy( achrDirectory, "Texture directory");
strcpy( achrMessage, "Browse texture");
}
CTFileName fnTexture = _EngineGUI.BrowseTexture( CTString(""), achrDirectory, achrMessage);
if( fnTexture != "")
{
GetDlgItem( IDC_TEXTURE_FILE_T)->SetWindowText( CString(fnTexture));
}
// to reflect data change
UpdateData( TRUE);
}
void CDlgPgTexture::OnRemoveTexture()
{
GetDlgItem( IDC_TEXTURE_FILE_T)->SetWindowText( L"No texture");
// apply data change
UpdateData( TRUE);
}
void CDlgPgTexture::OnRadioTexture()
{
CWorldEditorDoc* pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
pDoc->m_iTexture = 0;
UpdateData( FALSE);
}
void CDlgPgTexture::OnTexture2()
{
CWorldEditorDoc* pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
pDoc->m_iTexture = 1;
UpdateData( FALSE);
}
void CDlgPgTexture::OnTexture3()
{
CWorldEditorDoc* pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
pDoc->m_iTexture = 2;
UpdateData( FALSE);
}
void CDlgPgTexture::OnSelchangeScrollCombo()
{
UpdateData( TRUE);
}
void CDlgPgTexture::OnSelchangeBlendType()
{
UpdateData( TRUE);
}
void CDlgPgTexture::OnDropFiles(HDROP hDropInfo)
{
if( m_strTextureFile == NO_SELECTION)
{
return;
}
INDEX iNoOfFiles = DragQueryFile( hDropInfo, 0xFFFFFFFF, NULL, 0);
if( iNoOfFiles != 1)
{
AfxMessageBox( L"You can drop only one file at a time.");
return;
}
// buffer for dropped file name
char chrFile[ 256];
// place dropped file name into buffer
DragQueryFileA( hDropInfo, 0, chrFile, 256);
// create file name from buffer
CTFileName fnDropped = CTString(chrFile);
// if it is not texture, report error
if( fnDropped.FileExt() != ".tex" )
{
AfxMessageBox( L"You can only drop textures here.");
return;
}
try
{
fnDropped.RemoveApplicationPath_t();
GetDlgItem( IDC_TEXTURE_FILE_T)->SetWindowText( CString(fnDropped));
// apply data change
UpdateData( TRUE);
}
catch( char *err_str)
{
AfxMessageBox( CString(err_str));
}
}
BOOL CDlgPgTexture::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)
{
UpdateData( TRUE);
UpdateData( FALSE);
// the message is handled
return TRUE;
}
return CPropertyPage::PreTranslateMessage(pMsg);
}
void CDlgPgTexture::OnDropdownScrollCombo()
{
m_comboScroll.SetDroppedWidth(256);
}
void CDlgPgTexture::OnDropdownBlendType()
{
m_comboBlend.SetDroppedWidth(256);
}