hello world

This commit is contained in:
Timothee 'TTimo' Besset
2011-11-22 15:28:15 -06:00
commit fb1609f554
2155 changed files with 1017022 additions and 0 deletions

View File

@@ -0,0 +1,299 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "ConsoleView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define EDIT_HEIGHT 25
IMPLEMENT_DYNCREATE(ConsoleView, CFormView)
BEGIN_MESSAGE_MAP(ConsoleView, CFormView)
ON_WM_SIZE()
END_MESSAGE_MAP()
/**
* Constructor for ConsoleView.
*/
ConsoleView::ConsoleView()
: CFormView(ConsoleView::IDD) {
}
/**
* Destructor for ConsoleView.
*/
ConsoleView::~ConsoleView() {
}
/**
* Adds text to the end of the console output window.
* @param msg The text to append.
* \todo: BMatt Nerve: Fix scroll code so the output window will scroll as text
* is added if the cursor is at the end of the window.
*/
void ConsoleView::AddText( const char *msg ) {
if(!editConsole.GetSafeHwnd())
return;
idStr work;
CString work2;
work = msg;
work.RemoveColors();
work = TranslateString( work.c_str() );
editConsole.GetWindowText( work2 );
int len = work2.GetLength();
if ( len + work.Length() > (int)editConsole.GetLimitText() ) {
work2 = work2.Right( editConsole.GetLimitText() * .75f );
len = work2.GetLength();
editConsole.SetWindowText(work2);
}
editConsole.SetSel( len, len );
editConsole.ReplaceSel( work );
//Hack: scrolls down a bit
editConsole.LineScroll(100);
}
/**
* Replaces the text in the console window with the specified text.
* @param text The text to place in the console window.
*/
void ConsoleView::SetConsoleText ( const idStr& text ) {
editInput.Clear ();
editInput.SetWindowText ( text.c_str() );
}
/**
* Executes the specified console command. If the command is passed
* as a parameter then it is executed otherwise the command in the
* input box is executed.
* @param cmd The text to execute. If this string is empty then the
* input edit box text is used.
*/
void ConsoleView::ExecuteCommand ( const idStr& cmd ) {
CString str;
if ( cmd.Length() > 0 ) {
str = cmd;
}
else {
editInput.GetWindowText(str);
}
if ( str != "" ) {
editInput.SetWindowText("");
common->Printf("%s\n", str.GetBuffer(0));
//avoid adding multiple identical commands in a row
int index = consoleHistory.Num ();
if ( index == 0 || str.GetBuffer(0) != consoleHistory[index-1]) {
//keep the history to 16 commands, removing the oldest command
if ( consoleHistory.Num () > 16 ) {
consoleHistory.RemoveIndex ( 0 );
}
currentHistoryPosition = consoleHistory.Append ( str.GetBuffer (0) );
}
else {
currentHistoryPosition = consoleHistory.Num () - 1;
}
currentCommand.Clear ();
bool propogateCommand = true;
//process some of our own special commands
if ( str.CompareNoCase ( "clear" ) == 0) {
editConsole.SetSel ( 0 , -1 );
editConsole.Clear ();
}
else if ( str.CompareNoCase ( "edit" ) == 0) {
propogateCommand = false;
}
if ( propogateCommand ) {
cmdSystem->BufferCommandText(CMD_EXEC_NOW, str);
}
}
}
/**
* Handles keyboard input to process the "Enter" key to execute
* commands and command history.
*/
BOOL ConsoleView::PreTranslateMessage(MSG* pMsg) {
if (pMsg->hwnd == editInput.GetSafeHwnd()) {
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
this->ExecuteCommand();
return TRUE;
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_UP ) {
//save off the current in-progress command so we can get back to it
if ( saveCurrentCommand == true ) {
CString str;
editInput.GetWindowText ( str );
currentCommand = str.GetBuffer ( 0 );
saveCurrentCommand = false;
}
if ( consoleHistory.Num () > 0 ) {
editInput.SetWindowText ( consoleHistory[currentHistoryPosition] );
int selLocation = consoleHistory[currentHistoryPosition].Length ();
editInput.SetSel ( selLocation , selLocation + 1);
}
if ( currentHistoryPosition > 0) {
--currentHistoryPosition;
}
return TRUE;
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DOWN ) {
int selLocation = 0;
if ( currentHistoryPosition < consoleHistory.Num () - 1 ) {
++currentHistoryPosition;
editInput.SetWindowText ( consoleHistory[currentHistoryPosition] );
selLocation = consoleHistory[currentHistoryPosition].Length ();
}
else {
editInput.SetWindowText ( currentCommand );
selLocation = currentCommand.Length ();
currentCommand.Clear ();
saveCurrentCommand = true;
}
editInput.SetSel ( selLocation , selLocation + 1);
return TRUE;
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB ) {
common->Printf ( "Command History\n----------------\n" );
for ( int i = 0 ; i < consoleHistory.Num ();i++ )
{
common->Printf ( "[cmd %d]: %s\n" , i , consoleHistory[i].c_str() );
}
common->Printf ( "----------------\n" );
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_NEXT) {
editConsole.LineScroll ( 10 );
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_PRIOR ) {
editConsole.LineScroll ( -10 );
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_HOME ) {
editConsole.LineScroll ( -editConsole.GetLineCount() );
}
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_END ) {
editConsole.LineScroll ( editConsole.GetLineCount() );
}
}
return CFormView::PreTranslateMessage(pMsg);
}
/**
* Transfers data to and from the controls in the console.
*/
void ConsoleView::DoDataExchange(CDataExchange* pDX) {
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CONSOLE_OUTPUT, editConsole);
DDX_Control(pDX, IDC_CONSOLE_EDIT, editInput);
}
/**
* Transfers data to and from the controls in the console.
*/
void ConsoleView::OnInitialUpdate() {
CFormView::OnInitialUpdate();
CRect rect;
GetWindowRect(rect);
if(editConsole.m_hWnd)
editConsole.MoveWindow(0, 0, rect.Width(), rect.Height()-EDIT_HEIGHT);
if(editInput.m_hWnd)
editInput.MoveWindow(0, rect.Height()-EDIT_HEIGHT, rect.Width(), EDIT_HEIGHT);
}
/**
* Windows message called when the window is resized.
*/
void ConsoleView::OnSize(UINT nType, int cx, int cy) {
CFormView::OnSize(nType, cx, cy);
//Move the edit windows around
if(editConsole.GetSafeHwnd())
editConsole.MoveWindow(0, 0, cx, cy-EDIT_HEIGHT);
if(editInput.GetSafeHwnd())
editInput.MoveWindow(0, cy-EDIT_HEIGHT, cx, EDIT_HEIGHT);
}
/**
* Replaces \\n with \\r\\n for carriage returns in an edit control.
*/
const char *ConsoleView::TranslateString(const char *buf) {
static char buf2[32768];
int i, l;
char *out;
l = strlen(buf);
out = buf2;
for (i = 0; i < l; i++) {
if (buf[i] == '\n') {
*out++ = '\r';
*out++ = '\n';
}
else {
*out++ = buf[i];
}
}
*out++ = 0;
return buf2;
}

View File

@@ -0,0 +1,78 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialEditor.h"
/**
* View in the Material Editor that functions as a Doom III
* console. It allows users to view console output as well as issue
* console commands to the engine.
*/
class ConsoleView : public CFormView
{
public:
enum{ IDD = IDD_CONSOLE_FORM };
CEdit editConsole;
CEdit editInput;
idStr consoleStr;
idStrList consoleHistory;
idStr currentCommand;
int currentHistoryPosition;
bool saveCurrentCommand;
public:
virtual ~ConsoleView();
//Public Operations
void AddText(const char *msg);
void SetConsoleText ( const idStr& text );
void ExecuteCommand ( const idStr& cmd = "" );
protected:
ConsoleView();
DECLARE_DYNCREATE(ConsoleView)
//CFormView Overrides
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void DoDataExchange(CDataExchange* pDX);
virtual void OnInitialUpdate();
//Message Handlers
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
//Protected Operations
const char* TranslateString(const char *buf);
};

View File

@@ -0,0 +1,145 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "FindDialog.h"
#include "MEMainFrame.h"
IMPLEMENT_DYNAMIC(FindDialog, CDialog)
BEGIN_MESSAGE_MAP(FindDialog, CDialog)
ON_BN_CLICKED(ID_FIND_NEXT, OnBnClickedFindNext)
END_MESSAGE_MAP()
/**
* Constructor for FindDialog.
*/
FindDialog::FindDialog(CWnd* pParent)
: CDialog(FindDialog::IDD, pParent) {
registry.Init("Software\\id Software\\DOOM3\\Tools\\MaterialEditor\\Find");
parent = (MEMainFrame*)pParent;
}
/**
* Destructor for FindDialog.
*/
FindDialog::~FindDialog() {
}
/**
* Creates and instance of the find dialog.
*/
BOOL FindDialog::Create() {
return CDialog::Create(FindDialog::IDD, parent);
}
/**
* Transfers data to and from the controls in the find dialog.
*/
void FindDialog::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
CString temp = searchData.searchText;
DDX_Text(pDX, IDC_EDIT_FINDTEXT, temp);
DDX_Check(pDX, IDC_CHECK_NAME_ONLY, searchData.nameOnly);
DDX_Radio(pDX, IDC_RADIO_SEARCHFILE, searchData.searchScope);
searchData.searchText = temp;
}
/**
* Called while the dialog is being initialized to load the find parameters
* from the registry and set the focus to the correct control.
*/
BOOL FindDialog::OnInitDialog() {
CDialog::OnInitDialog();
LoadFindSettings();
GetDlgItem(IDC_EDIT_FINDTEXT)->SetFocus();
return FALSE;
}
/**
* Triggers a search based on the parameters in the dialog.
*/
void FindDialog::OnBnClickedFindNext() {
UpdateData();
searchData.searched = false;
parent->FindNext(&searchData);
}
/**
* Saves the search parameters and closes the find dialog.
*/
void FindDialog::OnCancel()
{
SaveFindSettings();
parent->CloseFind();
DestroyWindow();
}
/**
* Loads the search parameters from the registry and makes sure the controls are properly
* initialized.
*/
void FindDialog::LoadFindSettings() {
registry.Load();
searchData.searchText = registry.GetString("searchText");
searchData.nameOnly = (int)registry.GetFloat("nameOnly");
searchData.searchScope = (int)registry.GetFloat("searchScope");
registry.GetWindowPlacement("findDialog", GetSafeHwnd());
UpdateData(FALSE);
}
/**
* Saves the search parameters to the registry.
*/
void FindDialog::SaveFindSettings() {
UpdateData();
registry.SetString("searchText", searchData.searchText);
registry.SetFloat("nameOnly", searchData.nameOnly);
registry.SetFloat("searchScope", searchData.searchScope);
registry.SetWindowPlacement("findDialog", GetSafeHwnd());
registry.Save();
}

View File

@@ -0,0 +1,72 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialEditor.h"
#include "../common/registryoptions.h"
class MEMainFrame;
/**
* Dialog that provides an input box and several checkboxes to define
* the parameters of a search. These parameters include: text string, search
* scope and search only name flag.
*/
class FindDialog : public CDialog
{
public:
enum { IDD = IDD_FIND };
public:
FindDialog(CWnd* pParent = NULL);
virtual ~FindDialog();
BOOL Create();
protected:
DECLARE_DYNAMIC(FindDialog)
//Overrides
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
//Messages
afx_msg void OnBnClickedFindNext();
virtual void OnCancel();
DECLARE_MESSAGE_MAP()
//Protected Operations
void LoadFindSettings();
void SaveFindSettings();
protected:
MEMainFrame* parent;
MaterialSearchData_t searchData;
rvRegistryOptions registry;
};

View File

@@ -0,0 +1,937 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialEditor.h"
#include "MEMainFrame.h"
#include "MaterialDef.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define TAB_CONTROL 0x1006
IMPLEMENT_DYNAMIC(MEMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(MEMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_SETFOCUS()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_NOTIFY(TCN_SELCHANGE, TAB_CONTROL, OnTcnSelChange)
ON_COMMAND(ID_ME_FILE_EXIT, OnFileExit)
ON_COMMAND(ID_ME_FILE_SAVEMATERIAL, OnFileSaveMaterial)
ON_COMMAND(ID_ME_FILE_SAVEFILE, OnFileSaveFile)
ON_COMMAND(ID_ME_FILE_SAVE, OnFileSaveAll)
ON_UPDATE_COMMAND_UI(ID_ME_FILE_SAVEMATERIAL, OnFileSaveMaterialUpdate )
ON_UPDATE_COMMAND_UI(ID_ME_FILE_SAVEFILE, OnFileSaveFileUpdate )
ON_UPDATE_COMMAND_UI(ID_ME_FILE_SAVE, OnFileSaveAllUpdate )
ON_COMMAND(ID_ME_PREVIEW_APPLYCHANGES, OnApplyMaterial)
ON_COMMAND(ID_ME_PREVIEW_APPLYFILE, OnApplyFile)
ON_COMMAND(ID_ME_PREVIEW_APPLYALL, OnApplyAll)
ON_UPDATE_COMMAND_UI(ID_ME_PREVIEW_APPLYCHANGES, OnApplyMaterialUpdate )
ON_UPDATE_COMMAND_UI(ID_ME_PREVIEW_APPLYFILE, OnApplyFileUpdate )
ON_UPDATE_COMMAND_UI(ID_ME_PREVIEW_APPLYALL, OnApplyAllUpdate )
ON_COMMAND(ID_ME_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_ME_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_ME_EDIT_PASTE, OnEditPaste)
ON_COMMAND(ID_ME_EDIT_DELETE, OnEditDelete)
ON_COMMAND(ID_ME_EDIT_RENAME, OnEditRename)
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_CUT, OnEditCutUpdate)
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_COPY, OnEditCopyUpdate)
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_PASTE, OnEditPasteUpdate)
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_DELETE, OnEditDeleteUpdate)
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_RENAME, OnEditRenameUpdate)
ON_COMMAND(ID_ME_EDIT_FIND, OnEditFind)
ON_COMMAND(ID_ME_EDIT_FIND_NEXT, OnEditFindNext)
ON_COMMAND(ID_ME_EDIT_UNDO, OnEditUndo)
ON_COMMAND(ID_ME_EDIT_REDO, OnEditRedo)
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_UNDO, OnEditUndoUpdate )
ON_UPDATE_COMMAND_UI(ID_ME_EDIT_REDO, OnEditRedoUpdate )
ON_COMMAND(ID_VIEW_INCLUDEFILENAME, OnViewIncludeFile)
ON_COMMAND(ID_PREVIEW_RELOADARBPROGRAMS, OnReloadArbPrograms)
ON_COMMAND(ID_PREVIEW_RELOADIMAGES, OnReloadImages )
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/**
* Constructor for MEMainFrame. Initialize some member data and load the options.
*/
MEMainFrame::MEMainFrame() {
currentDoc = NULL;
m_find = NULL;
searchData.searched = false;
options.Load();
}
/**
* Destructor for MEMainFrame.
*/
MEMainFrame::~MEMainFrame() {
}
/**
* Called to add console text to the console view.
* @param msg The text that is to be added to the console.
*/
void MEMainFrame::PrintConsoleMessage(const char *msg) {
m_consoleView->AddText(msg);
}
/**
* Sets a few window styles for the main window during the creation process.
*/
BOOL MEMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
return TRUE;
}
/**
* Called by the MFC framework to allow the window to create any client windows. This method
* creates all of the spliter windows and registers all of the views with the document manager.
*/
BOOL MEMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
CCreateContext consoleContext;
consoleContext.m_pNewViewClass = RUNTIME_CLASS(ConsoleView);
m_consoleView = (ConsoleView*)CreateView(&consoleContext);
m_consoleView->ShowWindow(SW_HIDE);
m_tabs.Create(TCS_BOTTOM | TCS_FLATBUTTONS | WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, TAB_CONTROL);
m_tabs.InsertItem(0, "Editor");
m_tabs.InsertItem(1, "Console");
m_tabs.SetFont(materialEditorFont);
m_splitterWnd.CreateStatic(this, 2, 1);
m_editSplitter.CreateStatic(&m_splitterWnd, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER, m_splitterWnd.IdFromRowCol(0, 0));
if(!m_editSplitter.CreateView(0, 0, RUNTIME_CLASS(MaterialTreeView), CSize(300, 200), pContext)) {
TRACE0("Failed to create material list pane\n");
return FALSE;
}
if(!m_editSplitter.CreateView(0, 1, RUNTIME_CLASS(MaterialEditView), CSize(200, 200), pContext)) {
TRACE0("Failed to create stage property pane\n");
return FALSE;
}
m_previewSplitter.CreateStatic(&m_splitterWnd, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER, m_splitterWnd.IdFromRowCol(1, 0));
if(!m_previewSplitter.CreateView(0, 0, RUNTIME_CLASS(MaterialPreviewPropView), CSize(300, 200), pContext)) {
TRACE0("Failed to create preview property pane\n");
return FALSE;
}
if(!m_previewSplitter.CreateView(0, 1, RUNTIME_CLASS(MaterialPreviewView), CSize(100, 200), pContext)) {
TRACE0("Failed to create preview pane\n");
return FALSE;
}
//Get references to all of the views
m_materialTreeView = (MaterialTreeView*)m_editSplitter.GetPane(0, 0);
m_previewPropertyView = (MaterialPreviewPropView*)m_previewSplitter.GetPane(0, 0);
m_materialPreviewView = (MaterialPreviewView*)m_previewSplitter.GetPane(0, 1);
m_materialEditView = (MaterialEditView*)m_editSplitter.GetPane(0, 1);
m_stageView = m_materialEditView->m_stageView;
m_materialPropertyView = m_materialEditView->m_materialPropertyView;
m_materialEditSplitter = &m_materialEditView->m_editSplitter;
//Load the splitter positions from the registry
int val = options.GetMaterialEditHeight();
if(val <= 0)
val = 300;
m_splitterWnd.SetRowInfo(0, val, 0);
val = options.GetMaterialTreeWidth();
if(val <= 0)
val = 300;
m_editSplitter.SetColumnInfo(0, val, 0);
val = options.GetStageWidth();
if(val <= 0)
val = 200;
m_materialEditSplitter->SetColumnInfo(0, val, 0);
val = options.GetPreviewPropertiesWidth();
if(val <= 0)
val = 300;
m_previewSplitter.SetColumnInfo(0, val, 0);
//Register the views with the document manager
materialDocManager.RegisterMaterialView(this);
materialDocManager.RegisterMaterialView(m_materialTreeView);
materialDocManager.RegisterMaterialView(m_stageView);
materialDocManager.RegisterMaterialView(m_materialPropertyView);
materialDocManager.RegisterMaterialView(m_materialPreviewView);
materialDocManager.RegisterMaterialView(m_materialEditView);
//Let the stage window know about the prop window
m_stageView->SetMaterialPropertyView(m_materialPropertyView);
//Let the preview props now about the preview window
m_previewPropertyView->RegisterPreviewView(m_materialPreviewView);
m_previewPropertyView->InitializePropTree();
m_previewPropertyView->GetPropertyTreeCtrl().SetColumn(120);
MaterialDefManager::InitializeMaterialDefLists();
//Some prop tree initialization
//m_materialPropertyView->InitializePropTreeDefs();
val = options.GetMaterialPropHeadingWidth();
if(val <= 0)
val = 200;
m_materialPropertyView->GetPropertyTreeCtrl().SetColumn(val);
m_materialPropertyView->LoadSettings();
val = options.GetPreviewPropHeadingWidth();
if(val <= 0)
val = 120;
m_previewPropertyView->GetPropertyTreeCtrl().SetColumn(val);
//Build the material list
m_materialTreeView->InitializeMaterialList(true);
SetActiveView(m_materialTreeView);
return CFrameWnd::OnCreateClient(lpcs, pContext);
}
/**
* Called by the framework while the window is being created. This methods
* creates the tool bars and status bars
* /todo Bmatt Nerve: Need to get the toolbars to work correctly.
*/
int MEMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_ME_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
//Load the window placement from the options
options.GetWindowPlacement ( "mainframe", m_hWnd );
return 0;
}
/**
* Called by the MFC framework while the window is being destroyed. This method
* saves the splitter and window positions.
*/
void MEMainFrame::OnDestroy() {
CFrameWnd::OnDestroy();
int cur;
int min;
m_splitterWnd.GetRowInfo(0, cur, min);
options.SetMaterialEditHeight(cur);
m_editSplitter.GetColumnInfo(0, cur, min);
options.SetMaterialTreeWidth(cur);
m_materialEditSplitter->GetColumnInfo(0, cur, min);
options.SetStageWidth(cur);
m_previewSplitter.GetColumnInfo(0, cur, min);
options.SetPreviewPropertiesWidth(cur);
cur = m_materialPropertyView->GetPropertyTreeCtrl().GetColumn();
options.SetMaterialPropHeadingWidth(cur);
cur = m_previewPropertyView->GetPropertyTreeCtrl().GetColumn();
options.SetPreviewPropHeadingWidth(cur);
options.SetWindowPlacement ( "mainframe", m_hWnd );
options.Save();
m_materialPropertyView->SaveSettings();
MaterialDefManager::DestroyMaterialDefLists();
AfxGetApp()->ExitInstance();
}
/**
* Called by the MFC framework when the window size is changed. This method adjusts the console view
* so that it is always at the bottom of the window and resizes the splitter window to fit
* the remaining space.
*/
void MEMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
CRect statusRect;
m_wndStatusBar.GetWindowRect(statusRect);
CRect toolbarRect;
m_wndToolBar.GetWindowRect(toolbarRect);
CRect tabRect;
m_tabs.GetItemRect(0, tabRect);
int tabHeight = tabRect.Height()+5;
m_splitterWnd.MoveWindow(0, toolbarRect.Height(), cx, cy-statusRect.Height()-toolbarRect.Height()-tabHeight);
m_tabs.MoveWindow(0, cy-statusRect.Height()-tabHeight, cx, tabHeight);
m_consoleView->MoveWindow(0, toolbarRect.Height(), cx, cy-statusRect.Height()-toolbarRect.Height()-tabHeight);
}
/**
* Called when the user changes the editor/console tab selection. This methods shows and hides
* the appropriate windows.
*/
void MEMainFrame::OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult) {
int sel = m_tabs.GetCurSel();
switch(sel) {
case 0:
m_splitterWnd.ShowWindow(SW_SHOW);
m_consoleView->ShowWindow(SW_HIDE);
break;
case 1:
m_splitterWnd.ShowWindow(SW_HIDE);
m_consoleView->ShowWindow(SW_SHOW);
CRect rect;
GetWindowRect(rect);
MoveWindow(rect);
break;
}
}
/**
* Shuts down the material editor.
* /todo BMatt Nerve: Need to warn the user if a file is modified.
*/
void MEMainFrame::OnFileExit() {
PostMessage(WM_DESTROY, 0, 0);
}
/**
* Saves the selected material.
*/
void MEMainFrame::OnFileSaveMaterial() {
MaterialDoc* material = materialDocManager.GetCurrentMaterialDoc();
if(material) {
materialDocManager.SaveMaterial(material);
}
}
/**
* Saves the selected file.
*/
void MEMainFrame::OnFileSaveFile() {
idStr filename = m_materialTreeView->GetSaveFilename();
if(filename.Length() > 0) {
materialDocManager.SaveFile(filename);
}
}
/**
* Saves all modified materials.
*/
void MEMainFrame::OnFileSaveAll() {
materialDocManager.SaveAllMaterials();
}
/**
* Enables the save material menu item if a material is selected and has been modified.
*/
void MEMainFrame::OnFileSaveMaterialUpdate(CCmdUI *pCmdUI) {
MaterialDoc* pDoc = materialDocManager.GetCurrentMaterialDoc();
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
if(pDoc && pDoc->modified) {
pCmdUI->Enable(TRUE);
} else {
pCmdUI->Enable(FALSE);
}
}
/**
* Enables the Save File menu item if the current file contains a modified material.
*/
void MEMainFrame::OnFileSaveFileUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
if(m_materialTreeView->CanSaveFile()) {
pCmdUI->Enable(TRUE);
} else {
pCmdUI->Enable(FALSE);
}
}
/**
* Enables the Save All menu item if there are any materials that have been modified.
*/
void MEMainFrame::OnFileSaveAllUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
if(materialDocManager.IsAnyModified()) {
pCmdUI->Enable(TRUE);
} else {
pCmdUI->Enable(FALSE);
}
}
/**
* Apply the selected material.
*/
void MEMainFrame::OnApplyMaterial() {
MaterialDoc* material = materialDocManager.GetCurrentMaterialDoc();
if(material) {
materialDocManager.ApplyMaterial(material);
}
}
/**
* Applies all modified materials in the selected file.
*/
void MEMainFrame::OnApplyFile() {
idStr filename = m_materialTreeView->GetSaveFilename();
if(filename.Length() > 0) {
materialDocManager.ApplyFile(filename);
}
}
/**
* Applies all modified materials.
*/
void MEMainFrame::OnApplyAll() {
materialDocManager.ApplyAll();
}
/**
* Enables the Apply Material menu item if the current material has an apply waiting.
*/
void MEMainFrame::OnApplyMaterialUpdate(CCmdUI *pCmdUI) {
MaterialDoc* pDoc = materialDocManager.GetCurrentMaterialDoc();
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
if(pDoc && pDoc->applyWaiting) {
pCmdUI->Enable(TRUE);
} else {
pCmdUI->Enable(FALSE);
}
}
/**
* Enables the apply file menu item if the current file contains any materials
* that need to be applied.
*/
void MEMainFrame::OnApplyFileUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
MaterialDoc* pDoc = materialDocManager.GetCurrentMaterialDoc();
if(pDoc && materialDocManager.DoesFileNeedApply(pDoc->renderMaterial->GetFileName())) {
pCmdUI->Enable(TRUE);
} else {
pCmdUI->Enable(FALSE);
}
}
/**
* Enables the apply all menu item if there are any materials that need
* to be applied.
*/
void MEMainFrame::OnApplyAllUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
if(materialDocManager.DoesAnyNeedApply()) {
pCmdUI->Enable(TRUE);
} else {
pCmdUI->Enable(FALSE);
}
}
/**
* Performs a cut operation on the selected material.
*/
void MEMainFrame::OnEditCut() {
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
m_materialTreeView->OnCut();
}
}
}
/**
* Performs a copy operation on the selected material or stage.
*/
void MEMainFrame::OnEditCopy() {
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
m_stageView->OnCopy();
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
m_materialTreeView->OnCopy();
}
}
}
/**
* Performs a paste operation on the selected material or stage.
*/
void MEMainFrame::OnEditPaste() {
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
m_stageView->OnPaste();
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
m_materialTreeView->OnPaste();
}
}
}
/**
* Performs a delete operation on the selected material or stage.
*/
void MEMainFrame::OnEditDelete() {
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
m_stageView->OnDeleteStage();
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
m_materialTreeView->OnDeleteMaterial();
}
}
}
/**
* Performs a rename operation on the selected material or stage.
*/
void MEMainFrame::OnEditRename() {
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
m_stageView->OnRenameStage();
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
m_materialTreeView->OnRenameMaterial();
}
}
}
/**
* Enable the cut menu item if a material is selected.
*/
void MEMainFrame::OnEditCutUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
BOOL enable = FALSE;
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
if(m_stageView->CanCut()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
if(m_materialTreeView->CanCut()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
enable = TRUE;
}
}
pCmdUI->Enable(enable);
}
/**
* Enables the copy menu item if a material or stage is selected.
*/
void MEMainFrame::OnEditCopyUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
BOOL enable = FALSE;
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
if(m_stageView->CanCopy()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
if(m_materialTreeView->CanCopy()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
enable = TRUE;
}
}
pCmdUI->Enable(enable);
}
/**
* Enables a paste operation when a material or stage has been copied.
*/
void MEMainFrame::OnEditPasteUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
BOOL enable = FALSE;
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
if(m_stageView->CanPaste()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
if(m_materialTreeView->CanPaste()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
enable = TRUE;
}
}
pCmdUI->Enable(enable);
}
/**
* Enables a delete operation when a material or stage is selected.
*/
void MEMainFrame::OnEditDeleteUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
BOOL enable = FALSE;
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
if(m_stageView->CanDelete()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
if(m_materialTreeView->CanDelete()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
enable = TRUE;
}
}
pCmdUI->Enable(enable);
}
/**
* Enables a rename operation when a material, folder or stage is selected.
*/
void MEMainFrame::OnEditRenameUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
BOOL enable = FALSE;
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(StageView))) {
if(m_stageView->CanRename()) {
enable = TRUE;
}
} else if (focus->IsKindOf(RUNTIME_CLASS(MaterialTreeView))) {
if(m_materialTreeView->CanRename()) {
enable = TRUE;
}
}
}
pCmdUI->Enable(enable);
}
/**
* Opens the find dialog.
*/
void MEMainFrame::OnEditFind() {
if (m_find== NULL)
{
m_find = new FindDialog(this);
m_find->Create();
m_find->ShowWindow(SW_SHOW);
}
else
m_find->SetActiveWindow();
}
/**
* Performs a search with the previously selected search parameters.
*/
void MEMainFrame::OnEditFindNext() {
FindNext(NULL);
}
/**
* Performs an undo operation.
*/
void MEMainFrame::OnEditUndo() {
//Check for undo operation on special windows
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
m_materialEditView->m_textView.Undo();
return;
}
}
materialDocManager.Undo();
}
/**
* Performs a redo operation.
*/
void MEMainFrame::OnEditRedo() {
//Check for redo operation on special windows
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
m_materialEditView->m_textView.Redo();
return;
}
}
materialDocManager.Redo();
}
/**
* Enables the undo menu item if an undo is available.
*/
void MEMainFrame::OnEditUndoUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
pCmdUI->Enable(m_materialEditView->m_textView.CanUndo());
return;
}
}
pCmdUI->Enable(materialDocManager.IsUndoAvailable());
}
/**
* Enables the redo menu item if a redo is available.
*/
void MEMainFrame::OnEditRedoUpdate(CCmdUI *pCmdUI) {
if(pCmdUI->m_pMenu == NULL) {
pCmdUI->Enable(TRUE);
return;
}
CWnd* focus = GetFocus();
if(focus) {
if (focus->IsKindOf(RUNTIME_CLASS(CRichEditCtrl))) {
pCmdUI->Enable(m_materialEditView->m_textView.CanRedo());
return;
}
}
pCmdUI->Enable(materialDocManager.IsRedoAvailable());
}
/**
* Toggles between including the file into the material list and not.
*/
void MEMainFrame::OnViewIncludeFile() {
CMenu* mmenu = GetMenu();
UINT state = mmenu->GetMenuState(ID_VIEW_INCLUDEFILENAME, MF_BYCOMMAND);
ASSERT(state != 0xFFFFFFFF);
if (state & MF_CHECKED) {
mmenu->CheckMenuItem(ID_VIEW_INCLUDEFILENAME, MF_UNCHECKED | MF_BYCOMMAND);
m_materialTreeView->InitializeMaterialList(false);
} else {
mmenu->CheckMenuItem(ID_VIEW_INCLUDEFILENAME, MF_CHECKED | MF_BYCOMMAND);
m_materialTreeView->InitializeMaterialList(true);
}
}
/**
* Executes the reloadARBPrograms console command for convinience.
*/
void MEMainFrame::OnReloadArbPrograms() {
cmdSystem->BufferCommandText(CMD_EXEC_NOW, "reloadARBprograms");
}
/**
* Executes the reloadImages command to reload images that have been changed outside
* of the editor.
*/
void MEMainFrame::OnReloadImages() {
cmdSystem->BufferCommandText(CMD_EXEC_NOW, "reloadImages");
}
/**
* Called by the find dialog when it is closing.
*/
void MEMainFrame::CloseFind() {
m_find = NULL;
}
/**
* Begins a search based on the provided parameters or the previously used
* parameters.
*/
void MEMainFrame::FindNext(MaterialSearchData_t* search) {
if(search) {
searchData = *search;
} else {
if(!searchData.searched) {
return;
}
}
//The material tree controls the searching
if(!m_materialTreeView->FindNextMaterial(&searchData)) {
MessageBox(va("Unable to find '%s'.", searchData.searchText.c_str()), "Find");
}
searchData.searched = true;
}
/**
* Called when the selected material has changed.
* @param pMaterial The newly selected material.
*/
void MEMainFrame::MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) {
}

View File

@@ -0,0 +1,154 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include <afxcview.h>
#include "MaterialEditor.h"
#include "MaterialTreeView.h"
#include "MaterialPropTreeView.h"
#include "MaterialPreviewView.h"
#include "StageView.h"
#include "MaterialPreviewPropView.h"
#include "MEOptions.h"
#include "ConsoleView.h"
#include "FindDialog.h"
#include "../common/PropTree/PropTreeView.h"
#include "MaterialDocManager.h"
#include "MaterialEditView.h"
/**
* The main window for the material editor.
*/
class MEMainFrame : public CFrameWnd, public MaterialView
{
public:
MEMainFrame();
virtual ~MEMainFrame();
//Public Operations
void PrintConsoleMessage(const char *msg);
protected:
DECLARE_DYNAMIC(MEMainFrame)
// Overrides
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
//Message Handlers
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult);
//Menu Message Handlers
afx_msg void OnFileExit();
afx_msg void OnFileSaveMaterial();
afx_msg void OnFileSaveFile();
afx_msg void OnFileSaveAll();
afx_msg void OnFileSaveMaterialUpdate(CCmdUI *pCmdUI);
afx_msg void OnFileSaveFileUpdate(CCmdUI *pCmdUI);
afx_msg void OnFileSaveAllUpdate(CCmdUI *pCmdUI);
afx_msg void OnApplyMaterial();
afx_msg void OnApplyFile();
afx_msg void OnApplyAll();
afx_msg void OnApplyMaterialUpdate(CCmdUI *pCmdUI);
afx_msg void OnApplyFileUpdate(CCmdUI *pCmdUI);
afx_msg void OnApplyAllUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditCut();
afx_msg void OnEditCopy();
afx_msg void OnEditPaste();
afx_msg void OnEditDelete();
afx_msg void OnEditRename();
afx_msg void OnEditCutUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditCopyUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditPasteUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditDeleteUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditRenameUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditFind();
afx_msg void OnEditFindNext();
afx_msg void OnEditUndo();
afx_msg void OnEditRedo();
afx_msg void OnEditUndoUpdate(CCmdUI *pCmdUI);
afx_msg void OnEditRedoUpdate(CCmdUI *pCmdUI);
afx_msg void OnViewIncludeFile();
afx_msg void OnReloadArbPrograms();
afx_msg void OnReloadImages();
DECLARE_MESSAGE_MAP()
//Methods for Find interactions
friend FindDialog;
void CloseFind();
void FindNext(MaterialSearchData_t* search);
//MaterialView Interface
virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial);
protected:
//Status and Toolbars
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
//Splitter windows
CTabCtrl m_tabs;
CSplitterWnd m_splitterWnd;
CSplitterWnd m_editSplitter;
CSplitterWnd m_previewSplitter;
CSplitterWnd* m_materialEditSplitter;
//Child Views
MaterialTreeView* m_materialTreeView;
StageView* m_stageView;
MaterialPropTreeView* m_materialPropertyView;
MaterialPreviewView* m_materialPreviewView;
MaterialPreviewPropView* m_previewPropertyView;
ConsoleView* m_consoleView;
MaterialEditView* m_materialEditView;
//Find Data
FindDialog* m_find;
MaterialSearchData_t searchData;
//Document Management
MaterialDocManager materialDocManager;
MaterialDoc* currentDoc;
//Options
MEOptions options;
};

View File

@@ -0,0 +1,88 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MEOptions.h"
/**
* Constructor for MEOptions.
*/
MEOptions::MEOptions ( ) {
registry.Init("Software\\id Software\\DOOM3\\Tools\\MaterialEditor");
materialTreeWidth = 0;
stageWidth = 0;
previewPropertiesWidth = 0;
materialEditHeight = 0;
materialPropHeadingWidth = 0;
previewPropHeadingWidth = 0;
}
/**
* Destructor for MEOptions.
*/
MEOptions::~MEOptions() {
}
/**
* Saves the material editor options to the registry.
*/
bool MEOptions::Save (void) {
registry.SetFloat("materialTreeWidth", materialTreeWidth);
registry.SetFloat("stageWidth", stageWidth);
registry.SetFloat("previewPropertiesWidth", previewPropertiesWidth);
registry.SetFloat("materialEditHeight", materialEditHeight);
registry.SetFloat("materialPropHeadingWidth", materialPropHeadingWidth);
registry.SetFloat("previewPropHeadingWidth", previewPropHeadingWidth);
return registry.Save();
}
/**
* Loads the material editor options from the registry.
*/
bool MEOptions::Load (void) {
if(!registry.Load()) {
return false;
}
materialTreeWidth = (int)registry.GetFloat("materialTreeWidth");
stageWidth = (int)registry.GetFloat("stageWidth");
previewPropertiesWidth = (int)registry.GetFloat("previewPropertiesWidth");
materialEditHeight = (int)registry.GetFloat("materialEditHeight");
materialPropHeadingWidth = (int)registry.GetFloat("materialPropHeadingWidth");
previewPropHeadingWidth = (int)registry.GetFloat("previewPropHeadingWidth");
return true;
}

View File

@@ -0,0 +1,152 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "../common/registryoptions.h"
/**
* Wrapper class that is responsible for reading and writing Material Editor
* settings to the registry. Settings are written to
* Software\\id Software\\DOOM3\\Tools\\MaterialEditor
*/
class MEOptions {
public:
MEOptions();
~MEOptions();
bool Save (void);
bool Load (void);
/**
* Sets the flag that determines if the settings need to be saved because
* they where modified.
*/
void SetModified(bool mod = true) { modified = mod; };
/**
* Get the flag that determines if the settings need to be saved because
* they where modified.
*/
bool GetModified() { return modified; };
void SetWindowPlacement ( const char* name, HWND hwnd );
bool GetWindowPlacement ( const char* name, HWND hwnd );
void SetMaterialTreeWidth(int width);
int GetMaterialTreeWidth();
void SetStageWidth(int width);
int GetStageWidth();
void SetPreviewPropertiesWidth(int width);
int GetPreviewPropertiesWidth();
void SetMaterialEditHeight(int height);
int GetMaterialEditHeight();
void SetMaterialPropHeadingWidth(int width);
int GetMaterialPropHeadingWidth();
void SetPreviewPropHeadingWidth(int width);
int GetPreviewPropHeadingWidth();
protected:
rvRegistryOptions registry;
bool modified;
int materialTreeWidth;
int stageWidth;
int previewPropertiesWidth;
int materialEditHeight;
int materialPropHeadingWidth;
int previewPropHeadingWidth;
};
ID_INLINE void MEOptions::SetWindowPlacement ( const char* name, HWND hwnd ) {
registry.SetWindowPlacement ( name, hwnd );
}
ID_INLINE bool MEOptions::GetWindowPlacement ( const char* name, HWND hwnd ) {
return registry.GetWindowPlacement ( name, hwnd );
}
ID_INLINE void MEOptions::SetMaterialTreeWidth(int width) {
materialTreeWidth = width;
SetModified(true);
}
ID_INLINE int MEOptions::GetMaterialTreeWidth() {
return materialTreeWidth;
}
ID_INLINE void MEOptions::SetStageWidth(int width) {
stageWidth = width;
SetModified(true);
}
ID_INLINE int MEOptions::GetStageWidth() {
return stageWidth;
}
ID_INLINE void MEOptions::SetPreviewPropertiesWidth(int width) {
previewPropertiesWidth = width;
SetModified(true);
}
ID_INLINE int MEOptions::GetPreviewPropertiesWidth() {
return previewPropertiesWidth;
}
ID_INLINE void MEOptions::SetMaterialEditHeight(int height) {
materialEditHeight = height;
SetModified(true);
}
ID_INLINE int MEOptions::GetMaterialEditHeight() {
return materialEditHeight;
}
ID_INLINE void MEOptions::SetMaterialPropHeadingWidth(int width) {
materialPropHeadingWidth = width;
SetModified(true);
}
ID_INLINE int MEOptions::GetMaterialPropHeadingWidth() {
return materialPropHeadingWidth;
}
ID_INLINE void MEOptions::SetPreviewPropHeadingWidth(int width) {
previewPropHeadingWidth = width;
SetModified(true);
}
ID_INLINE int MEOptions::GetPreviewPropHeadingWidth() {
return previewPropHeadingWidth;
}

View File

@@ -0,0 +1,199 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialDef.h"
/**
* Constructor.
*/
MaterialDef::MaterialDef(void) {
type = 0;
quotes = false;
}
/**
* Destructor.
*/
MaterialDef::~MaterialDef(void) {
}
/**
* Returns view specific data associated with the material definition.
*/
DWORD MaterialDef::GetViewData(const char* viewName) {
DWORD* value = NULL;
viewData.Get(viewName, &value);
return *value;
}
/**
* Sets view specific data for the material definition.
*/
void MaterialDef::SetViewData(const char* viewName, DWORD value) {
viewData.Set(viewName, value);
}
#define MATERIAL_DEF_FILE "MaterialEditorDefs.med"
MaterialDefList MaterialDefManager::materialDefs[MaterialDefManager::MATERIAL_DEF_NUM];
/**
* Loads the material definition file instatiates MaterialDef objects for each definition
* and groups the definitions.
*/
void MaterialDefManager::InitializeMaterialDefLists() {
char *buffer;
int length = fileSystem->ReadFile( MATERIAL_DEF_FILE, (void **)&buffer);
if ( length == -1 ) {
common->Error( "Couldn't load material editor definition: %s", MATERIAL_DEF_FILE );
return;
}
idLexer src;
if ( !src.LoadMemory( buffer, length, MATERIAL_DEF_FILE ) ) {
common->Error( "Couldn't parse %s", MATERIAL_DEF_FILE );
fileSystem->FreeFile(buffer);
}
InitializeMaterialDefList(&src, "materialprops", &materialDefs[MATERIAL_DEF_MATERIAL]);
InitializeMaterialDefList(&src, "stageprops", &materialDefs[MATERIAL_DEF_STAGE]);
InitializeMaterialDefList(&src, "specialmapstageprops", &materialDefs[MATERIAL_DEF_SPECIAL_STAGE]);
fileSystem->FreeFile(buffer);
}
/**
* Loads a single type of material attributes and adds them to the supplied MaterialDefList object.
* @param src The idLexer object that contains the file.
* @param typeName The name of the attribute grouping to search for in the file.
* @param list The MaterialDefList object to append the MaterialDef instances to.
*/
void MaterialDefManager::InitializeMaterialDefList(idLexer* src, const char* typeName, MaterialDefList* list) {
idToken token;
src->Reset();
src->SkipUntilString(typeName);
src->SkipUntilString("{");
while(1) {
if ( !src->ExpectAnyToken( &token ) ) {
//Todo: Add some error checking here
return;
}
if ( token == "}" ) {
break;
}
MaterialDef* newProp = new MaterialDef();
if(!token.Icmp("TYPE_GROUP")) {
newProp->type = MaterialDef::MATERIAL_DEF_TYPE_GROUP;
} else if(!token.Icmp("TYPE_BOOL")) {
newProp->type = MaterialDef::MATERIAL_DEF_TYPE_BOOL;
} else if(!token.Icmp("TYPE_STRING")) {
newProp->type = MaterialDef::MATERIAL_DEF_TYPE_STRING;
} else if(!token.Icmp("TYPE_FLOAT")) {
newProp->type = MaterialDef::MATERIAL_DEF_TYPE_FLOAT;
} else if(!token.Icmp("TYPE_INT")) {
newProp->type = MaterialDef::MATERIAL_DEF_TYPE_INT;
}
//Skip the ,
src->ReadToken(&token);
//Read Dict Name
src->ReadToken(&token);
newProp->dictName = token;
//Skip the ,
src->ReadToken(&token);
//Read Display Name
src->ReadToken(&token);
newProp->displayName = token;
//Skip the ,
src->ReadToken(&token);
//Read Display Info
src->ReadToken(&token);
newProp->displayInfo = token;
//Type Specific Data
if(newProp->type == MaterialDef::MATERIAL_DEF_TYPE_STRING) {
newProp->quotes = false;
//Skip the ,
src->ReadToken(&token);
//Read validate flag
src->ReadToken(&token);
if(token == "1") {
newProp->quotes = true;
}
}
src->SkipRestOfLine();
list->Append(newProp);
}
}
/**
* Destroys all MaterialDef instances and clears the material attribute grouping lists.
*/
void MaterialDefManager::DestroyMaterialDefLists() {
for(int i = 0; i < MATERIAL_DEF_NUM; i++) {
for(int j = 0; j < materialDefs[i].Num(); j++) {
delete materialDefs[i][j];
}
materialDefs[i].Clear();
}
}
/**
* Returns the MaterialDefList for the specified attribute grouping.
* @param type The attribute grouping for which to retreive the attribute list.
*/
MaterialDefList* MaterialDefManager::GetMaterialDefs(int type) {
if(type >= 0 && type < MATERIAL_DEF_NUM) {
return &materialDefs[type];
}
return NULL;
}

View File

@@ -0,0 +1,102 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
/**
* Represents a single attribute in a material. Represents material, stage
* and special stage attributes. The MaterialDef manager loads these
* definitions from the material definition file as the editor
* is being initialized.
*/
class MaterialDef {
public:
/**
* Defines possible attribute types.
*/
enum {
MATERIAL_DEF_TYPE_GROUP,
MATERIAL_DEF_TYPE_BOOL,
MATERIAL_DEF_TYPE_STRING,
MATERIAL_DEF_TYPE_FLOAT,
MATERIAL_DEF_TYPE_INT
};
int type;
idStr dictName;
idStr displayName;
idStr displayInfo;
bool quotes;
idHashTable<DWORD> viewData;
public:
MaterialDef(void);
virtual ~MaterialDef(void);
DWORD GetViewData(const char* viewName);
void SetViewData(const char* viewName, DWORD value);
};
/**
* A list of material attributes. Material, stage, and special stage attributes
* are grouped together during the load process for use by the different view and
* MaterialDoc.
*/
typedef idList<MaterialDef*> MaterialDefList;
/**
* This class contains static utility functions that view and MaterialDoc use
* to access the MaterialDef and MaterialDefList data that is loaded. This class
* is also responsible for loading and destroying the MaterialDef instances.
*/
class MaterialDefManager {
public:
/**
* Defines the groupings of material attributes.
*/
enum {
MATERIAL_DEF_MATERIAL = 0,
MATERIAL_DEF_STAGE,
MATERIAL_DEF_SPECIAL_STAGE,
MATERIAL_DEF_NUM
};
static void InitializeMaterialDefLists();
static void InitializeMaterialDefList(idLexer* src, const char* typeName, MaterialDefList* list);
static void DestroyMaterialDefLists();
static MaterialDefList* GetMaterialDefs(int type);
protected:
static MaterialDefList materialDefs[MATERIAL_DEF_NUM];
};

View File

@@ -0,0 +1,966 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialDoc.h"
#include "MaterialView.h"
/**
* Constructor for MaterialDoc.
*/
MaterialDoc::MaterialDoc(void) {
modified = false;
applyWaiting = false;
sourceModify = false;
}
/**
* Destructor for MaterialDoc.
*/
MaterialDoc::~MaterialDoc(void) {
ClearEditMaterial();
}
/**
* Initializes the MaterialDoc instance with a specific idMaterial. This method will
* parse the material into the internal dictionary representation and optionally
* allow the idMaterial object to reparse the source.
* @param material The idMaterial instance to use.
* @param parseMaterial Flag to determine if the material should be parsed into the editor representation.
* @param parseRenderMaterial Flag to determine if the idMaterial object should be reparsed.
*/
void MaterialDoc::SetRenderMaterial(idMaterial* material, bool parseMaterial, bool parseRenderMatierial) {
renderMaterial = material;
if(!parseMaterial || !renderMaterial)
return;
if(parseRenderMatierial) {
char *declText = (char *) _alloca( material->GetTextLength() + 1 );
material->GetText( declText );
renderMaterial->GetText(declText);
ParseMaterialText(declText);
}
ClearEditMaterial();
name = material->GetName();
idLexer src;
char *declText = (char *) _alloca( material->GetTextLength() + 1 );
material->GetText( declText );
renderMaterial->GetText(declText);
src.LoadMemory(declText, strlen(declText), "Material");
ParseMaterial(&src);
}
/**
* Returns the number of stages in this material.
*/
int MaterialDoc::GetStageCount() {
return editMaterial.stages.Num();
}
/**
* Returns the index of the stage with the specified type and name or -1
* if the stage does not exist.
* @param stageType The type of stage to find.
* @param name The name of the stage to find.
*/
int MaterialDoc::FindStage(int stageType, const char* name) {
for(int i = 0; i < editMaterial.stages.Num(); i++) {
int type = GetAttributeInt(i, "stagetype");
idStr localname = GetAttribute(i, "name");
if(stageType == type && !localname.Icmp(name))
return i;
}
return -1;
}
/**
* Returns a copy of the specified stage.
* @param stage The stage to return.
*/
MEStage_t MaterialDoc::GetStage(int stage) {
assert(stage >= 0 && stage < GetStageCount());
return *editMaterial.stages[stage];
}
/**
* Specifies the enabled state of a single stage.
* @param stage The stage to change.
* @param enabled The enabled state.
*/
void MaterialDoc::EnableStage(int stage, bool enabled) {
assert(stage >= 0 && stage < GetStageCount());
editMaterial.stages[stage]->enabled = enabled;
OnMaterialChanged();
}
/**
* Sets the enabled state of all stages.
* @param enabled The enabled state.
*/
void MaterialDoc::EnableAllStages(bool enabled) {
for(int i = 0; i < GetStageCount(); i++) {
editMaterial.stages[i]->enabled = enabled;
}
}
/**
* Returns the enabled state of a stage.
* @param stage The stage to check.
*/
bool MaterialDoc::IsStageEnabled(int stage) {
assert(stage >= 0 && stage < GetStageCount());
return editMaterial.stages[stage]->enabled;
}
/**
* Returns an attribute string from the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param defaultString The default value if the attribute is not specified.
*/
const char* MaterialDoc::GetAttribute(int stage, const char* attribName, const char* defaultString) {
if(stage == -1) {
return editMaterial.materialData.GetString(attribName, defaultString);
} else {
assert(stage >= 0 && stage < GetStageCount());
MEStage_t* pStage = editMaterial.stages[stage];
return pStage->stageData.GetString(attribName, defaultString);
}
}
/**
* Returns an attribute int from the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param defaultString The default value if the attribute is not specified.
*/
int MaterialDoc::GetAttributeInt(int stage, const char* attribName, const char* defaultString) {
if(stage == -1) {
return editMaterial.materialData.GetInt(attribName, defaultString);
} else {
assert(stage >= 0 && stage < GetStageCount());
MEStage_t* pStage = editMaterial.stages[stage];
return pStage->stageData.GetInt(attribName, defaultString);
}
}
/**
* Returns an attribute float from the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param defaultString The default value if the attribute is not specified.
*/
float MaterialDoc::GetAttributeFloat(int stage, const char* attribName, const char* defaultString) {
if(stage == -1) {
return editMaterial.materialData.GetFloat(attribName, defaultString);
} else {
assert(stage >= 0 && stage < GetStageCount());
MEStage_t* pStage = editMaterial.stages[stage];
return pStage->stageData.GetFloat(attribName, defaultString);
}
}
/**
* Returns an attribute bool from the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param defaultString The default value if the attribute is not specified.
*/
bool MaterialDoc::GetAttributeBool(int stage, const char* attribName, const char* defaultString) {
if(stage == -1) {
return editMaterial.materialData.GetBool(attribName, defaultString);
} else {
assert(stage >= 0 && stage < GetStageCount());
MEStage_t* pStage = editMaterial.stages[stage];
return pStage->stageData.GetBool(attribName, defaultString);
}
}
/**
* Sets an attribute string in the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param value The value to set.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::SetAttribute(int stage, const char* attribName, const char* value, bool addUndo) {
//Make sure we need to set the attribute
idStr orig = GetAttribute(stage, attribName);
if(orig.Icmp(value)) {
idDict* dict;
if(stage == -1) {
dict = &editMaterial.materialData;
} else {
assert(stage >= 0 && stage < GetStageCount());
dict = &editMaterial.stages[stage]->stageData;
}
if(addUndo) {
//Create a new Modifier for this change so we can undo and redo later
AttributeMaterialModifierString* mod = new AttributeMaterialModifierString(manager, name, stage, attribName, value, orig);
manager->AddMaterialUndoModifier(mod);
}
dict->Set(attribName, value);
manager->AttributeChanged(this, stage, attribName);
OnMaterialChanged();
}
}
/**
* Sets an attribute int in the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param value The value to set.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::SetAttributeInt(int stage, const char* attribName, int value, bool addUndo) {
//Make sure we need to set the attribute
int orig = GetAttributeInt(stage, attribName);
if(orig != value) {
idDict* dict;
if(stage == -1) {
dict = &editMaterial.materialData;
} else {
assert(stage >= 0 && stage < GetStageCount());
dict = &editMaterial.stages[stage]->stageData;
}
dict->SetInt(attribName, value);
manager->AttributeChanged(this, stage, attribName);
OnMaterialChanged();
}
}
/**
* Sets an attribute float in the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param value The value to set.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::SetAttributeFloat(int stage, const char* attribName, float value, bool addUndo) {
//Make sure we need to set the attribute
float orig = GetAttributeFloat(stage, attribName);
if(orig != value) {
idDict* dict;
if(stage == -1) {
dict = &editMaterial.materialData;
} else {
assert(stage >= 0 && stage < GetStageCount());
dict = &editMaterial.stages[stage]->stageData;
}
dict->SetFloat(attribName, value);
manager->AttributeChanged(this, stage, attribName);
OnMaterialChanged();
}
}
/**
* Sets an attribute bool in the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param value The value to set.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::SetAttributeBool(int stage, const char* attribName, bool value, bool addUndo) {
//Make sure we need to set the attribute
bool orig = GetAttributeBool(stage, attribName);
if(orig != value) {
idDict* dict;
if(stage == -1) {
dict = &editMaterial.materialData;
} else {
assert(stage >= 0 && stage < GetStageCount());
dict = &editMaterial.stages[stage]->stageData;
}
if(addUndo) {
//Create a new Modifier for this change so we can undo and redo later
AttributeMaterialModifierBool* mod = new AttributeMaterialModifierBool(manager, name, stage, attribName, value, orig);
manager->AddMaterialUndoModifier(mod);
}
dict->SetBool(attribName, value);
manager->AttributeChanged(this, stage, attribName);
OnMaterialChanged();
}
}
/**
* Sets the material name.
* @param materialName The new name of the material.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::SetMaterialName(const char* materialName, bool addUndo) {
idStr oldName = name;
declManager->RenameDecl(DECL_MATERIAL, oldName, materialName);
name = renderMaterial->GetName();
if(addUndo) {
RenameMaterialModifier* mod = new RenameMaterialModifier(manager, name, oldName);
manager->AddMaterialUndoModifier(mod);
}
manager->MaterialNameChanged(oldName, this);
OnMaterialChanged();
//Need to do an instant apply for material name changes
ApplyMaterialChanges();
}
/**
* Sets the entire dictionary for a material or stage
* @param stage The stage or -1 for the material.
* @param data The dictionary to copy.
*/
void MaterialDoc::SetData(int stage, idDict* data) {
idDict* dict;
if(stage == -1) {
dict = &editMaterial.materialData;
} else {
assert(stage >= 0 && stage < GetStageCount());
dict = &editMaterial.stages[stage]->stageData;
}
dict->Clear();
dict->Copy(*data);
}
/**
* Called when the editor modifies the source of the material.
* @param text The new source text.
*/
void MaterialDoc::SourceModify(SourceModifyOwner* owner) {
sourceModifyOwner = owner;
sourceModify = true;
OnMaterialChanged();
}
/**
* Returns true if the source text of this material has been edited.
*/
bool MaterialDoc::IsSourceModified() {
return sourceModify;
}
/**
* Applies any source changes to the edit representation of the material.
*/
void MaterialDoc::ApplySourceModify(idStr& text) {
if(sourceModify) {
//Changes in the source need to clear any undo redo buffer because we have no idea what has changed
manager->ClearUndo();
manager->ClearRedo();
ClearEditMaterial();
idLexer src;
src.LoadMemory(text, text.Length(), "Material");
src.SetFlags(
LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated
LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings
LEXFL_ALLOWPATHNAMES | // allow path seperators in names
LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals
LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated
LEXFL_NOFATALERRORS // just set a flag instead of fatal erroring
);
idToken token;
if(!src.ReadToken(&token)) {
src.Warning( "Missing decl name" );
return;
}
ParseMaterial(&src);
sourceModify = false;
//Check to see if the name has changed
if(token.Icmp(name)) {
SetMaterialName(token, false);
}
}
}
/**
* Returns the appropriate source for the editing
*/
const char* MaterialDoc::GetEditSourceText() {
return GenerateSourceText();
}
/**
* Adds a stage to the material.
* @param stageType The type of the stage: normal or special.
* @param stageName The name of the stage.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::AddStage(int stageType, const char* stageName, bool addUndo) {
MEStage_t* newStage = new MEStage_t();
int index = editMaterial.stages.Append(newStage);
newStage->stageData.Set("name", stageName);
newStage->stageData.SetInt("stagetype", stageType);
newStage->enabled = true;
if(addUndo) {
StageInsertModifier* mod = new StageInsertModifier(manager, name, index, stageType, stageName);
manager->AddMaterialUndoModifier(mod);
}
manager->StageAdded(this, index);
OnMaterialChanged();
}
/**
* Inserts a new stage to the material at a specified location.
* @param stage The location to insert the stage.
* @param stageType The type of the stage: normal or special.
* @param stageName The name of the stage.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::InsertStage(int stage, int stageType, const char* stageName, bool addUndo) {
MEStage_t* newStage = new MEStage_t();
editMaterial.stages.Insert(newStage, stage);
newStage->stageData.Set("name", stageName);
newStage->stageData.SetInt("stagetype", stageType);
newStage->enabled = true;
if(addUndo) {
StageInsertModifier* mod = new StageInsertModifier(manager, name, stage, stageType, stageName);
manager->AddMaterialUndoModifier(mod);
}
manager->StageAdded(this, stage);
OnMaterialChanged();
}
/**
* Removes a stage from the material.
* @param stage The stage to remove.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::RemoveStage(int stage, bool addUndo) {
assert(stage >= 0 && stage < GetStageCount());
if(addUndo) {
//Add modifier to undo this operation
StageDeleteModifier* mod = new StageDeleteModifier(manager, name, stage, editMaterial.stages[stage]->stageData);
manager->AddMaterialUndoModifier(mod);
}
//delete the stage and remove it from the list
delete editMaterial.stages[stage];
editMaterial.stages.RemoveIndex(stage);
manager->StageDeleted(this, stage);
OnMaterialChanged();
}
/**
* Removes all stages from the material.
*/
void MaterialDoc::ClearStages() {
//Delete each stage and clear the list
for(int i = GetStageCount() - 1; i >= 0; i--) {
RemoveStage(i);
}
}
/**
* Moves a stage from one location to another.
* @param from The original location of the stage.
* @param to The new location of the stage.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::MoveStage(int from, int to, bool addUndo) {
assert(from >= 0 && from < GetStageCount());
assert(to >= 0 && to < GetStageCount());
int origFrom = from;
int origTo = to;
if(from < to)
to++;
MEStage_t* pMove = editMaterial.stages[from];
editMaterial.stages.Insert(pMove, to);
if(from > to)
from++;
editMaterial.stages.RemoveIndex(from);
manager->StageMoved(this, origFrom, origTo);
if(addUndo) {
StageMoveModifier *mod = new StageMoveModifier(manager, name, origFrom, origTo);
manager->AddMaterialUndoModifier(mod);
}
OnMaterialChanged();
}
/**
* Applies any changes to the material
* @param force If true then the material will be applied regardless of the number of changes.
*/
void MaterialDoc::ApplyMaterialChanges(bool force) {
if(force || applyWaiting) {
if(sourceModify && sourceModifyOwner) {
idStr text = sourceModifyOwner->GetSourceText();
ApplySourceModify(text);
}
ReplaceSourceText();
char *declText = (char *) _alloca( renderMaterial->GetTextLength() + 1 );
renderMaterial->GetText( declText );
renderMaterial->GetText(declText);
ParseMaterialText(declText);
applyWaiting = false;
assert(manager);
manager->MaterialApplied(this);
}
}
/**
* Saves the material.
*/
void MaterialDoc::Save() {
EnableAllStages(true);
//Apply the material so that the renderMaterial has the source text
if(!deleted) {
ApplyMaterialChanges(true);
} else {
//Replace the text with nothing
renderMaterial->SetText(" ");
}
if(renderMaterial->Save()) {
modified = false;
//Notify the world
assert(manager);
manager->MaterialSaved(this);
} else {
MessageBox(GetMaterialEditorWindow(), va("Unable to save '%s'. It may be read-only", name.c_str()), "Save Error", MB_OK | MB_ICONERROR);
}
}
/**
* Deletes the material.
*/
void MaterialDoc::Delete() {
deleted = true;
OnMaterialChanged();
}
/**
* Sets the proper internal states and notifies the MaterialDocManager once a material has been changed.
*/
void MaterialDoc::OnMaterialChanged() {
modified = true;
applyWaiting = true;
assert(manager);
manager->MaterialChanged(this);
}
/**
* Passes text to a render material for parsing.
* @param source The text that sould be applied to the idMaterial.
*/
void MaterialDoc::ParseMaterialText(const char* source) {
/*idLexer src;
src.LoadMemory(source, strlen(source), "material");
src.SetFlags(
LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated
LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings
LEXFL_ALLOWPATHNAMES | // allow path seperators in names
LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals
LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated
LEXFL_NOFATALERRORS // just set a flag instead of fatal erroring
);
//Skip the name becuase the material parsing code expects it
src.SkipUntilString("{");*/
//Now let the material parse the text
renderMaterial->Parse(source, strlen(source));
}
/**
* Parses the source text from an idMaterial and initializes the editor dictionary representation
* of the material.
* @param src The idLexer object that contains the material text.
*/
void MaterialDoc::ParseMaterial(idLexer* src) {
idToken token;
//Parse past the name
src->SkipUntilString("{");
while ( 1 ) {
if ( !src->ExpectAnyToken( &token ) ) {
//Todo: Add some error checking here
return;
}
if ( token == "}" ) {
break;
}
if(ParseMaterialDef(&token, src, MaterialDefManager::MATERIAL_DEF_MATERIAL, &editMaterial.materialData)) {
continue;
}
if ( !token.Icmp( "diffusemap" ) ) {
//Added as a special stage
idStr str;
src->ReadRestOfLine( str );
AddSpecialMapStage("diffusemap", str);
}
else if ( !token.Icmp( "specularmap" ) ) {
idStr str;
src->ReadRestOfLine( str );
AddSpecialMapStage("specularmap", str);
}
else if ( !token.Icmp( "bumpmap" ) ) {
idStr str;
src->ReadRestOfLine( str );
AddSpecialMapStage("bumpmap", str);
}
else if( token == "{" ) {
ParseStage(src);
}
}
}
/**
* Parses a single stage from the source text from an idMaterial and initializes the editor dictionary
* representation of the material.
* @param src The idLexer object that contains the material text.
*/
void MaterialDoc::ParseStage(idLexer* src) {
MEStage_t* newStage = new MEStage_t();
int index = editMaterial.stages.Append(newStage);
newStage->stageData.SetInt("stagetype", STAGE_TYPE_NORMAL);
newStage->enabled = true;
idToken token;
while ( 1 ) {
if ( !src->ExpectAnyToken( &token ) ) {
//Todo: Add some error checking here
return;
}
if ( token == "}" ) {
break;
}
if(ParseMaterialDef(&token, src, MaterialDefManager::MATERIAL_DEF_STAGE, &newStage->stageData)) {
continue;
}
if(!token.Icmp("name")) {
idStr str;
src->ReadRestOfLine( str );
str.StripTrailing('\"');
str.StripLeading('\"');
newStage->stageData.Set("name", str);
continue;
}
}
idStr name;
newStage->stageData.GetString("name", "", name);
if(name.Length() <= 0)
newStage->stageData.Set("name", va("Stage %d", index+1));
}
/**
* Adds a special stage to the material.
* @param stageName The name of the special stage bumpmap, diffusemap or specularmap
* @param map The map for the special stage.
*/
void MaterialDoc::AddSpecialMapStage(const char* stageName, const char* map) {
MEStage_t* newStage = new MEStage_t();
int index = editMaterial.stages.Append(newStage);
newStage->stageData.Set("name", stageName);
newStage->stageData.Set("map", map);
newStage->stageData.SetInt("stagetype", STAGE_TYPE_SPECIALMAP);
newStage->enabled = true;
}
/**
* Finds the appropriate material definition for the supplied token and initializes the
* internal dictionary data.
* @param token The token to lookup
* @param src The idLexer that contains the material source text.
* @param type The type of attribute grouping to use material, stage or special stage.
* @param dict The dictionary to initialize.
*/
bool MaterialDoc::ParseMaterialDef(idToken* token, idLexer* src, int type, idDict* dict) {
MaterialDefList* defs = MaterialDefManager::GetMaterialDefs(type);
for(int i = 0; i < defs->Num(); i++) {
if(!token->Icmp((*defs)[i]->dictName)) {
switch((*defs)[i]->type) {
case MaterialDef::MATERIAL_DEF_TYPE_STRING:
{
idStr str;
src->ReadRestOfLine( str );
if((*defs)[i]->quotes) {
str.StripTrailing('\"');
str.StripLeading('\"');
}
dict->Set((*defs)[i]->dictName, str);
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_BOOL:
{
src->SkipRestOfLine();
dict->SetBool((*defs)[i]->dictName, true);
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_FLOAT:
{
idStr str;
src->ReadRestOfLine( str );
dict->Set((*defs)[i]->dictName, str);
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_INT:
{
idStr str;
src->ReadRestOfLine( str );
dict->Set((*defs)[i]->dictName, str);
}
break;
}
return true;
}
}
return false;
}
/**
* Cleans up the edit material by deleting the stage data structures.
*/
void MaterialDoc::ClearEditMaterial() {
for(int i = 0; i < GetStageCount(); i++) {
delete editMaterial.stages[i];
}
editMaterial.stages.Clear();
editMaterial.materialData.Clear();
}
/**
* Writes the internal dictionary data to the standard format.
*/
const char* MaterialDoc::GenerateSourceText() {
idFile_Memory f;
f.WriteFloatString("\n\n/*\n"
"\tGenerated by the Material Editor.\n"
"\tType 'materialeditor' at the console to launch the material editor.\n"
"*/\n" );
f.WriteFloatString("%s\n", name.c_str());
f.WriteFloatString( "{\n" );
WriteMaterialDef(-1, &f, MaterialDefManager::MATERIAL_DEF_MATERIAL, 1);
for(int i = 0; i < editMaterial.stages.Num(); i++) {
if(editMaterial.stages[i]->enabled) {
WriteStage(i, &f);
}
}
f.WriteFloatString( "}\n" );
return f.GetDataPtr();
}
/**
* Writes the internal dictionary data to the standard format and replaces the
* idMaterial source text with the newly generated text.
*/
void MaterialDoc::ReplaceSourceText() {
renderMaterial->SetText(GenerateSourceText());
}
/**
* Writes a single stage.
* @param stage The stage to write.
* @param file The file where the stage should be wirtten
*/
void MaterialDoc::WriteStage(int stage, idFile_Memory* file) {
//idStr stageName = GetAttribute(stage, "name");
int type = GetAttributeInt(stage, "stagetype");
//if(!stageName.Icmp("diffusemap") || !stageName.Icmp("specularmap") || !stageName.Icmp("bumpmap")) {
if(type == STAGE_TYPE_SPECIALMAP) {
WriteSpecialMapStage(stage, file);
return;
}
file->WriteFloatString( "\t{\n" );
idStr name = GetAttribute(stage, "name");
if(name.Length() > 0) {
file->WriteFloatString("\t\tname\t\"%s\"\n", name.c_str());
}
WriteMaterialDef(stage, file, MaterialDefManager::MATERIAL_DEF_STAGE, 2);
file->WriteFloatString( "\t}\n" );
}
/**
* Writes a single special stage.
* @param stage The stage to write.
* @param file The file where the stage should be wirtten
*/
void MaterialDoc::WriteSpecialMapStage(int stage, idFile_Memory* file) {
idStr stageName = GetAttribute(stage, "name");
idStr map = GetAttribute(stage, "map");
file->WriteFloatString( "\t%s\t%s\n", stageName.c_str(), map.c_str() );
}
/**
* Writes a set of material attributes to a file.
* @param stage The stage to write or -1 for the material.
* @param file The file where the stage should be wirtten.
* @param type The attribute grouping to use.
* @param indent The number of tabs to indent the text.
*/
void MaterialDoc::WriteMaterialDef(int stage, idFile_Memory* file, int type, int indent) {
idStr prefix = "";
for(int i = 0; i < indent; i++) {
prefix += "\t";
}
MaterialDefList* defs = MaterialDefManager::GetMaterialDefs(type);
for(int i = 0; i < defs->Num(); i++) {
switch((*defs)[i]->type) {
case MaterialDef::MATERIAL_DEF_TYPE_STRING:
{
idStr attrib = GetAttribute(stage, (*defs)[i]->dictName);
if(attrib.Length() > 0) {
if((*defs)[i]->quotes)
file->WriteFloatString("%s%s\t\"%s\"\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), attrib.c_str());
else
file->WriteFloatString("%s%s\t%s\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), attrib.c_str());
}
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_BOOL:
{
if(GetAttributeBool(stage, (*defs)[i]->dictName))
file->WriteFloatString("%s%s\t\n",prefix.c_str(), (*defs)[i]->dictName.c_str());
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_FLOAT:
{
float val = GetAttributeFloat(stage, (*defs)[i]->dictName);
file->WriteFloatString("%s%s\t%f\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), val);
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_INT:
{
int val = GetAttributeInt(stage, (*defs)[i]->dictName);
file->WriteFloatString("%s%s\t%d\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), val);
}
break;
}
}
}

View File

@@ -0,0 +1,156 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialEditor.h"
#include "MaterialModifier.h"
#include "MaterialDef.h"
/**
* Dictionary representation of a Material Stage.
*/
typedef struct {
idDict stageData;
bool enabled;
} MEStage_t;
/**
* Dictionary representation of a material.
*/
typedef struct {
idDict materialData;
idList<MEStage_t*> stages;
} MEMaterial_t;
/**
* Implemented by the edit window that is responsible for modifying the material source text.
*/
class SourceModifyOwner {
public:
SourceModifyOwner() {};
virtual ~SourceModifyOwner() {};
virtual idStr GetSourceText() { return ""; };
};
class MaterialDocManager;
/**
* Responsible for managing a single material that is being viewed and/or edited.
*/
class MaterialDoc {
public:
MaterialDocManager* manager;
idStr name;
idMaterial* renderMaterial;
MEMaterial_t editMaterial;
bool modified;
bool applyWaiting;
bool deleted;
bool sourceModify;
SourceModifyOwner* sourceModifyOwner;
public:
MaterialDoc(void);
~MaterialDoc(void);
/**
* Define the types of stages in a material.
*/
enum {
STAGE_TYPE_NORMAL,
STAGE_TYPE_SPECIALMAP
};
//Initialization Methods
void SetRenderMaterial(idMaterial* material, bool parseMaterial = true, bool parseRenderMatierial = false);
//Stage Info Methods
int GetStageCount();
int FindStage(int stageType, const char* name);
MEStage_t GetStage(int stage);
void EnableStage(int stage, bool enabled);
void EnableAllStages(bool enabled);
bool IsStageEnabled(int stage);
//Get Attributes
const char* GetAttribute(int stage, const char* attribName, const char* defaultString = "");
int GetAttributeInt(int stage, const char* attribName, const char* defaultString = "0");
float GetAttributeFloat(int stage, const char* attribName, const char* defaultString = "0");
bool GetAttributeBool(int stage, const char* attribName, const char* defaultString = "0");
//Set Attribute Methods
void SetAttribute(int stage, const char* attribName, const char* value, bool addUndo = true);
void SetAttributeInt(int stage, const char* attribName, int value, bool addUndo = true);
void SetAttributeFloat(int stage, const char* attribName, float value, bool addUndo = true);
void SetAttributeBool(int stage, const char* attribName, bool value, bool addUndo = true);
void SetMaterialName(const char* materialName, bool addUndo = true);
void SetData(int stage, idDict* data);
//Source Editing Methods
void SourceModify(SourceModifyOwner* owner);
bool IsSourceModified();
void ApplySourceModify(idStr& text);
const char* GetEditSourceText();
//Stage Modification Methods
void AddStage(int stageType, const char* stageName, bool addUndo = true);
void InsertStage(int stage, int stageType, const char* stageName, bool addUndo = true);
void RemoveStage(int stage, bool addUndo = true);
void ClearStages();
void MoveStage(int from, int to, bool addUndo = true);
void ApplyMaterialChanges(bool force = false);
void Save();
void Delete();
protected:
//Internal Notifications
void OnMaterialChanged();
//Load Material Methods
void ParseMaterialText(const char* source);
void ParseMaterial(idLexer* src);
void ParseStage(idLexer* src);
void AddSpecialMapStage(const char* stageName, const char* map);
bool ParseMaterialDef(idToken* token, idLexer* src, int type, idDict* dict);
void ClearEditMaterial();
//Save/Apply Material Methods
const char* GenerateSourceText();
void ReplaceSourceText();
void WriteStage(int stage, idFile_Memory* file);
void WriteSpecialMapStage(int stage, idFile_Memory* file);
void WriteMaterialDef(int stage, idFile_Memory* file, int type, int indent);
};

View File

@@ -0,0 +1,893 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialDocManager.h"
#include "MaterialView.h"
/**
* Constructor for MaterialDocManager.
*/
MaterialDocManager::MaterialDocManager(void) {
currentMaterial = NULL;
cutMaterial = false;
}
/**
* Destructor for MaterialDocManager.
*/
MaterialDocManager::~MaterialDocManager(void) {
UnRegisterAllMaterialViews();
ClearUndo();
ClearRedo();
}
/**
* Registers an object to receive notifications about changes made to materials.
* @param view The object that would like to receive material notifications.
*/
void MaterialDocManager::RegisterMaterialView(MaterialView* view) {
ASSERT(view);
UnRegisterMaterialView(view);
materialViews.Append(view);
//Notify the view of myself
view->SetMaterialDocManager(this);
}
/**
* Tells the MaterialDocManager to stop sending notifications to a view.
* @param view The view that no longer wants notifications.
*/
void MaterialDocManager::UnRegisterMaterialView(MaterialView* view) {
ASSERT(view);
materialViews.Remove(view);
//Remove the reference to myself
view->SetMaterialDocManager(NULL);
}
/**
* Unregisters all of the views that are registered to get material change
* notifications.
*/
void MaterialDocManager::UnRegisterAllMaterialViews() {
//Remove the reference to myself
int c = materialViews.Num();
for(int i = 0; i < c; i++) {
materialViews[i]->SetMaterialDocManager(NULL);
}
materialViews.Clear();
}
/**
* Tells the MaterialDocManager which material has been selected for editing.
* @param material The material that has been selected.
*/
void MaterialDocManager::SetSelectedMaterial(idMaterial* material) {
bool change = false;
//Do we need to change the material
if(material) {
if(currentMaterial) {
if(strcmp(material->GetName(), currentMaterial->renderMaterial->GetName())) {
change = true;
}
} else {
change = true;
}
} else {
if(currentMaterial) {
change = true;
}
}
//Now make the change
if(change) {
if(currentMaterial) {
//Delete the material unless it has been changed
if(!inProgressMaterials.Get(currentMaterial->name.c_str())) {
delete currentMaterial;
currentMaterial = NULL;
}
}
MaterialDoc** tempDoc;
if(material && inProgressMaterials.Get(material->GetName(), &tempDoc)) {
currentMaterial = *tempDoc;
} else {
currentMaterial = CreateMaterialDoc(material);
}
NotifyViews(currentMaterial, SELECTION_CHANGE);
}
}
/**
* Returns true if the specified file needs to be applied and false otherwise.
*/
bool MaterialDocManager::DoesFileNeedApply(const char* filename) {
for(int i = 0; i < inProgressMaterials.Num(); i++) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename) && (*pDoc)->applyWaiting)
return true;
}
return false;
}
/**
* Returns true if any material needs to be applied.
*/
bool MaterialDocManager::DoesAnyNeedApply() {
for(int i = 0; i < inProgressMaterials.Num(); i++) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
if((*pDoc)->applyWaiting)
return true;
}
return false;
}
/**
* Returns true if the specified file has been modified.
*/
bool MaterialDocManager::IsFileModified(const char* filename) {
for(int i = 0; i < inProgressMaterials.Num(); i++) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename))
return true;
}
return false;
}
/**
* Returns true if any material has been modified.
*/
bool MaterialDocManager::IsAnyModified() {
return (inProgressMaterials.Num() > 0);
}
/**
* Adds a material.
* @param name The name of the material.
* @param filename The file to place the material in.
* @param sourceText The initial material definition.
* @param addUndo Can this operation be undone.
*/
void MaterialDocManager::AddMaterial(const char* name, const char* filename, const char* sourceText, bool addUndo) {
if(addUndo) {
AddMaterialModifier* mod = new AddMaterialModifier(this, name, filename);
AddMaterialUndoModifier(mod);
}
MaterialDoc* newDoc = new MaterialDoc();
newDoc->manager = this;
newDoc->modified = true;
idMaterial* rendMat = (idMaterial*)declManager->CreateNewDecl(DECL_MATERIAL, name, filename);
if(sourceText) {
rendMat->SetText(sourceText);
}
newDoc->SetRenderMaterial(rendMat, true, sourceText ? true : false);
inProgressMaterials.Set(newDoc->name.c_str(), newDoc);
NotifyViews(newDoc, MATERIAL_ADD);
//Force an apply so the text will be generated to match the new file
newDoc->applyWaiting = true;
newDoc->ApplyMaterialChanges();
}
/**
* Used to redo an add material and undo a delete material.
* The undo for adding a material deletes the material. Instead of adding a completely
* new material RedoAddMaterial finds the one that was just deleted and uses that.
* @param name The name of the material that was added/deleted.
* @param clearData Should the material definition be reset to the default definition.
*/
void MaterialDocManager::RedoAddMaterial(const char* name, bool clearData) {
MaterialDoc* newDoc = new MaterialDoc();
newDoc->manager = this;
newDoc->modified = true;
idMaterial* rendMat = const_cast<idMaterial *>(declManager->FindMaterial(name, false));
if(clearData) {
rendMat->SetText(rendMat->DefaultDefinition());
}
newDoc->SetRenderMaterial(rendMat, true, true);
inProgressMaterials.Set(newDoc->name.c_str(), newDoc);
NotifyViews(newDoc, MATERIAL_ADD);
//Force an apply so the text will be generated to match the new file
newDoc->applyWaiting = true;
newDoc->ApplyMaterialChanges();
}
/**
* Deletes a material.
* @param material The material to be deleted.
* @param addUndo Can this operation be undone.
*/
void MaterialDocManager::DeleteMaterial(MaterialDoc* material, bool addUndo) {
assert(material);
//This will just flag for delete. The actual delete will happen during the save
material->Delete();
if(addUndo) {
DeleteMaterialModifier* mod = new DeleteMaterialModifier(this, material->name);
AddMaterialUndoModifier(mod);
}
NotifyViews(material, MATERIAL_DELETE);
}
/**
* Applys changes to a material.
* @param materialDoc The material to be applied.
*/
void MaterialDocManager::ApplyMaterial(MaterialDoc* materialDoc) {
assert(materialDoc);
materialDoc->ApplyMaterialChanges();
}
/**
* Applies all materials in the specified filename.
* @param filename The file to apply.
*/
void MaterialDocManager::ApplyFile(const char* filename) {
for(int i = 0; i < inProgressMaterials.Num(); i++) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename))
(*pDoc)->ApplyMaterialChanges();
}
}
/**
* Applies all materials that have been changed.
*/
void MaterialDocManager::ApplyAll() {
for(int i = 0; i < inProgressMaterials.Num(); i++) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
(*pDoc)->ApplyMaterialChanges();
}
}
/**
* Saves a single material.
* @param material The material to save.
*/
void MaterialDocManager::SaveMaterial(MaterialDoc* material) {
assert(material);
material->Save();
}
/**
* Saves all materials in the specified file.
* @param filename The file to save.
*/
void MaterialDocManager::SaveFile(const char* filename) {
for(int i = inProgressMaterials.Num()-1; i >= 0; i--) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename))
(*pDoc)->Save();
}
//Notify everyone
NotifyViews(NULL, MATERIAL_SAVE_FILE, filename);
}
/**
* Saves all materials that have been changed.
*/
void MaterialDocManager::SaveAllMaterials() {
for(int i = inProgressMaterials.Num()-1; i >= 0; i--) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
(*pDoc)->Save();
}
}
/**
* Reloads a specified file.
* @param filename The file to reload.
*/
void MaterialDocManager::ReloadFile(const char *filename) {
declManager->ReloadFile(filename, true);
//purge the changes of any in progress materials
for(int j = inProgressMaterials.Num()-1; j >= 0; j--) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(j);
if(!strcmp((*pDoc)->renderMaterial->GetFileName(), filename)) {
(*pDoc)->SetRenderMaterial((*pDoc)->renderMaterial);
inProgressMaterials.Remove((*pDoc)->name);
}
}
//Reparse the current material
if(currentMaterial) {
currentMaterial->SetRenderMaterial(currentMaterial->renderMaterial);
//Trigger all the views to refresh
NotifyViews(currentMaterial, SELECTION_CHANGE);
}
NotifyViews(NULL, FILE_RELOAD, filename);
}
/**
* Creates a MaterialDoc object for the specified material name. If a MaterialDoc
* object already exists then it is used.
* @param materialName The name of the material for which to create a MaterialDoc object.
*/
MaterialDoc* MaterialDocManager::CreateMaterialDoc(const char* materialName) {
const idMaterial* material = declManager->FindMaterial(materialName);
return CreateMaterialDoc(const_cast<idMaterial *>(material));
}
/**
* Creates a MaterialDoc object for the specified material. If a MaterialDoc
* object already exists then it is used.
* @param material The material for which to create a MaterialDoc object.
*/
MaterialDoc* MaterialDocManager::CreateMaterialDoc(idMaterial* material) {
MaterialDoc* existingDoc = GetInProgressDoc(material);
if(existingDoc) {
return existingDoc;
}
if(currentMaterial && material && !currentMaterial->name.Icmp(material->GetName())) {
return currentMaterial;
}
if(material) {
MaterialDoc* newDoc = new MaterialDoc();
newDoc->manager = this;
newDoc->SetRenderMaterial(material);
return newDoc;
}
return NULL;
}
/**
* Checks the current list of in progress MaterialDoc objects to see if
* a MaterialDoc object already exists.
* @param material The material to check for.
*/
MaterialDoc* MaterialDocManager::GetInProgressDoc(idMaterial* material) {
if(material) {
for(int i = 0; i < inProgressMaterials.Num(); i++) {
MaterialDoc** pDoc = inProgressMaterials.GetIndex(i);
if(!(*pDoc)->name.Icmp(material->GetName()))
return *pDoc;
}
}
return NULL;
}
/**
* Prepares a material for a copy/cut and paste operations.
* @param materialDoc The material to copy.
* @param cut Is this a cut operation.
*/
void MaterialDocManager::CopyMaterial(MaterialDoc* materialDoc, bool cut) {
cutMaterial = cut;
if(materialDoc)
copyMaterial = materialDoc->name;
else
ClearCopy();
}
/**
* Clears the copy buffer for a material.
*/
void MaterialDocManager::ClearCopy() {
copyMaterial.Empty();
}
/**
* Returns true if there is a material in the copy buffer.
*/
bool MaterialDocManager::IsCopyMaterial() {
return (copyMaterial.Length() ) ? true : false;
}
/**
* Returns the name of the material in the copy buffer.
*/
idStr MaterialDocManager::GetCopyMaterialName() {
return copyMaterial;
}
/**
* Performs a material paste operation for a material in the copy buffer.
* @param name The new name for the material that is being copied.
* @param filename The file to paste the material in.
*/
void MaterialDocManager::PasteMaterial(const char* name, const char* filename) {
if(!IsCopyMaterial()) {
return;
}
//Apply the material if there are some changes
MaterialDoc* copyMat = CreateMaterialDoc(copyMaterial);
if(copyMat->applyWaiting) {
copyMat->ApplyMaterialChanges();
}
//Paste the material
idMaterial* material = copyMat->renderMaterial;
//Add a material with the existing source text
char *declText = (char *) _alloca( material->GetTextLength() + 1 );
material->GetText( declText );
AddMaterial(name, filename, declText, !cutMaterial);
//If this is a cut then remove the original
if(cutMaterial) {
MaterialDoc* cutMaterial = CreateMaterialDoc(material);
DeleteMaterial(cutMaterial, false);
MoveMaterialModifier* mod = new MoveMaterialModifier(this, name, filename, copyMaterial);
AddMaterialUndoModifier(mod);
ClearCopy();
}
}
/**
* Prepares a material stage for a copy/paste operation.
* @param materialDoc The materialDoc that contains the stage to be copied.
* @param stageNum the stage to copy.
*/
void MaterialDocManager::CopyStage(MaterialDoc* materialDoc, int stageNum) {
assert(materialDoc);
copyStageMaterial = materialDoc->name;
copyStage = materialDoc->GetStage(stageNum);
idStr stageName = copyStage.stageData.GetString("name");
}
/**
* Clears the copy buffer for copied stages.
*/
void MaterialDocManager::ClearCopyStage() {
copyStageMaterial.Empty();
copyStage.stageData.Clear();
}
/**
* Returns true if there is a stage in the copy buffer.
*/
bool MaterialDocManager::IsCopyStage() {
return (copyStageMaterial.Length() ) ? true : false;
}
/**
* Performs a paste operation of the stage in the copy buffer.
* @param materialDoc The materialDoc to paste the stage in.
*/
void MaterialDocManager::PasteStage(MaterialDoc* materialDoc) {
assert(materialDoc);
int stageType = copyStage.stageData.GetInt("stagetype");
//Create a new stage and copy the data
materialDoc->AddStage(stageType, copyStage.stageData.GetString("name"));
materialDoc->SetData(materialDoc->GetStageCount()-1, &copyStage.stageData);
}
/**
* Returns information about the stage in the copy buffer.
* @param type Holds the type of the stage in the copy buffer.
* @param name Hold the name of the stage in the copy buffer.
*/
void MaterialDocManager::GetCopyStageInfo(int& type, idStr& name) {
if(IsCopyStage()) {
type = copyStage.stageData.GetInt("stagetype");
name = copyStage.stageData.GetString("name");
}
}
/**
* Performs the first available undo operation.
*/
void MaterialDocManager::Undo() {
if(IsUndoAvailable()) {
MaterialModifier* mod = undoModifiers[undoModifiers.Num()-1];
undoModifiers.RemoveIndex(undoModifiers.Num()-1);
mod->Undo();
//Add this modifier to the redo list
AddMaterialRedoModifier(mod);
}
}
/**
* Returns true if an undo operation is available.
*/
bool MaterialDocManager::IsUndoAvailable() {
return (undoModifiers.Num() > 0);
}
/**
* Clears the entire undo buffer.
*/
void MaterialDocManager::ClearUndo() {
int c = undoModifiers.Num();
for(int i = 0; i < c; i++) {
delete undoModifiers[i];
}
undoModifiers.Clear();
}
/**
* Performs the first available redo operation.
*/
void MaterialDocManager::Redo() {
if(IsRedoAvailable()) {
MaterialModifier* mod = redoModifiers[redoModifiers.Num()-1];
redoModifiers.RemoveIndex(redoModifiers.Num()-1);
mod->Redo();
//Done with the mod because the redo process will set
//attributes and create the appropriate redo modifier
AddMaterialUndoModifier(mod, false);
}
}
/**
* Returns true if a redo operation is available.
*/
bool MaterialDocManager::IsRedoAvailable() {
return (redoModifiers.Num() > 0);
}
/**
* Clears the redo buffer.
*/
void MaterialDocManager::ClearRedo() {
int c = redoModifiers.Num();
for(int i = 0; i < c; i++) {
delete redoModifiers[i];
}
redoModifiers.Clear();
}
/**
* Adds an undo operation to the undo buffer.
* @param mod The MaterialModifier object that contains the undo data.
* @param clearRedo Should we clear the redo buffer.
*/
void MaterialDocManager::AddMaterialUndoModifier(MaterialModifier* mod, bool clearRedo) {
undoModifiers.Append(mod);
while(undoModifiers.Num() > MAX_UNDOREDO) {
undoModifiers.RemoveIndex(0);
}
if(clearRedo) {
ClearRedo();
}
}
/**
* Adds a redo operation to the redo buffer.
* @param mod The MaterialModifier object that contains the redo data.
*/
void MaterialDocManager::AddMaterialRedoModifier(MaterialModifier* mod) {
redoModifiers.Append(mod);
while(redoModifiers.Num() > MAX_UNDOREDO) {
redoModifiers.RemoveIndex(0);
}
}
/**
* Searches for a material that matches the specified search data.
* @param name The name of the material to search.
* @param searchData The search parameters.
* @param checkName If true then the name of the material will be checked along with the material text.
*/
bool MaterialDocManager::FindMaterial(const char* name, MaterialSearchData_t* searchData, bool checkName) {
//Fast way of finding the material without parsing
const idMaterial* material = static_cast<const idMaterial *>(declManager->FindDeclWithoutParsing(DECL_MATERIAL, name, false));
if(material) {
int findPos;
if(checkName) {
//Check the name
idStr name = material->GetName();
findPos = name.Find(searchData->searchText, false);
if(findPos != -1) {
return true;
}
}
//Skip to the open braket so the name is not checked
char *declText = (char *) _alloca( material->GetTextLength() + 1 );
material->GetText( declText );
idStr text = declText;
int start = text.Find("{");
if(start != -1) {
text = text.Right(text.Length()-start);
}
findPos = text.Find(searchData->searchText, false);
if(findPos != -1) {
//Todo: Include match whole word
return true;
}
}
return false;
}
/**
* Returns a unique material name given a base name. This is used to resolve materials with the same name.
* @param name The base name of the material.
*/
idStr MaterialDocManager::GetUniqueMaterialName(idStr name) {
int num = 0;
while(1) {
idStr testName;
if(num == 0)
testName = name;
else
testName = va("%s%d", name.c_str(), num);
const idMaterial* mat = declManager->FindMaterial(testName.c_str(), false);
if(!mat) {
return testName;
} else {
//We can reuse delete material names
if(mat->GetTextLength() < 1)
return testName;
}
num++;
}
}
/**
* Notifies all registered views of a material event.
* @param materialDoc The material that has been affected.
* @param notifyType The type of event that has occured.
* @param ... Notification specific data. See MaterialView.
*/
void MaterialDocManager::NotifyViews(MaterialDoc* materialDoc, int notifyType, ... ) {
va_list argptr;
int c = materialViews.Num();
for(int i = 0; i < c; i++) {
va_start( argptr, notifyType );
switch(notifyType) {
case SELECTION_CHANGE:
materialViews[i]->MV_OnMaterialSelectionChange(materialDoc);
break;
case MATERIAL_CHANGE:
materialViews[i]->MV_OnMaterialChange(materialDoc);
break;
case MATERIAL_APPLY:
materialViews[i]->MV_OnMaterialApply(materialDoc);
break;
case MATERIAL_SAVE:
materialViews[i]->MV_OnMaterialSaved(materialDoc);
break;
case MATERIAL_SAVE_FILE:
materialViews[i]->MV_OnMaterialSaveFile(va_arg(argptr, const char*));
break;
case MATERIAL_ADD:
materialViews[i]->MV_OnMaterialAdd(materialDoc);
break;
case MATERIAL_DELETE:
materialViews[i]->MV_OnMaterialDelete(materialDoc);
break;
case MATERIAL_ADD_STAGE:
materialViews[i]->MV_OnMaterialStageAdd(materialDoc, va_arg(argptr, int));
break;
case MATERIAL_DELETE_STAGE:
materialViews[i]->MV_OnMaterialStageDelete(materialDoc, va_arg(argptr, int));
break;
case MATERIAL_MOVE_STAGE:
{
int from = va_arg(argptr, int);
int to = va_arg(argptr, int);
materialViews[i]->MV_OnMaterialStageMove(materialDoc, from, to);
}
break;
case MATERIAL_ATTRIBUTE_CHANGE:
{
int stage = va_arg(argptr, int);
const char* attribName = va_arg(argptr, const char*);
materialViews[i]->MV_OnMaterialAttributeChanged(materialDoc, stage, attribName);
}
break;
case MATERIAL_NAME_CHANGE:
{
const char* oldName = va_arg(argptr, const char*);
materialViews[i]->MV_OnMaterialNameChanged(materialDoc, oldName);
}
break;
case FILE_RELOAD:
{
const char* filename = va_arg(argptr, const char*);
materialViews[i]->MV_OnFileReload(filename);
}
break;
}
va_end( argptr );
}
}
/**
* Called when a material has been edited and notifies all views of the change.
* @param materialDoc The material that has changed.
*/
void MaterialDocManager::MaterialChanged(MaterialDoc* materialDoc) {
//Make sure this material is in our list of changed materials
if(!inProgressMaterials.Get(materialDoc->name.c_str())) {
inProgressMaterials.Set(materialDoc->name.c_str(), materialDoc);
}
//Notify everyone
NotifyViews(materialDoc, MATERIAL_CHANGE);
}
/**
* Called when a material has been applied and notifies all views of the apply.
* @param materialDoc The material that has been applied.
*/
void MaterialDocManager::MaterialApplied(MaterialDoc* materialDoc) {
//Notify everyone
NotifyViews(materialDoc, MATERIAL_APPLY);
}
/**
* Called when a material has been saved and notifies all views of the save.
* @param materialDoc The material that has been saved.
*/
void MaterialDocManager::MaterialSaved(MaterialDoc* materialDoc) {
MaterialDoc** tempDoc;
if(inProgressMaterials.Get(materialDoc->name.c_str(), &tempDoc)) {
idStr name = materialDoc->name.c_str();
//Remove this file from our in progress list
inProgressMaterials.Remove(name.c_str());
//Notify everyone
NotifyViews(materialDoc, MATERIAL_SAVE);
if(materialDoc != currentMaterial)
delete materialDoc;
}
}
/**
* Called when a material name has been changed and notifies all views of the change.
* @param materialDoc The material that has changed.
*/
void MaterialDocManager::MaterialNameChanged(const char* oldName, MaterialDoc* materialDoc) {
MaterialDoc** tempDoc;
if(inProgressMaterials.Get(oldName, &tempDoc)) {
inProgressMaterials.Set(materialDoc->name, *tempDoc);
inProgressMaterials.Remove(oldName);
}
NotifyViews(materialDoc, MATERIAL_NAME_CHANGE, oldName);
}
/**
* Called when a stage is added and notifies all views of the addition.
* @param materialDoc The material that has changed.
* @param stageNum The stage that was added.
*/
void MaterialDocManager::StageAdded(MaterialDoc* materialDoc, int stageNum) {
//Notify everyone
NotifyViews(materialDoc, MATERIAL_ADD_STAGE, stageNum);
}
/**
* Called when a stage has been deleted and notifies all views of the change.
* @param materialDoc The material that has changed.
* @param stageNum The stage that was deleted.
*/
void MaterialDocManager::StageDeleted(MaterialDoc* materialDoc, int stageNum) {
//Notify everyone
NotifyViews(materialDoc, MATERIAL_DELETE_STAGE, stageNum);
}
/**
* Called when a stage has been movied and notifies all views of the change.
* @param materialDoc The material that has changed.
* @param from The original position of the stage.
* @param to The new position of the stage.
*/
void MaterialDocManager::StageMoved(MaterialDoc* materialDoc, int from, int to) {
//Notify everyone
NotifyViews(materialDoc, MATERIAL_MOVE_STAGE, from, to);
}
/**
* Called when a material attribute has been edited and notifies all views of the change.
* @param materialDoc The material that has changed.
* @param stage The stage that contains the changed attribute.
* @param attribName The name of the attribute that changed.
*/
void MaterialDocManager::AttributeChanged(MaterialDoc* materialDoc, int stage, const char* attribName) {
//Notify everyone
NotifyViews(materialDoc, MATERIAL_ATTRIBUTE_CHANGE, stage, attribName);
}

View File

@@ -0,0 +1,163 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialEditor.h"
#include "MaterialModifier.h"
#include "MaterialDoc.h"
class MaterialView;
#define MAX_UNDOREDO 32
/**
* Responsible for managing the materials that are being viewed and/or edited.
*/
class MaterialDocManager {
public:
MaterialDocManager(void);
~MaterialDocManager(void);
//Reg/UnReg Material Views
void RegisterMaterialView(MaterialView* view);
void UnRegisterMaterialView(MaterialView* view);
void UnRegisterAllMaterialViews();
//Material Selection
void SetSelectedMaterial(idMaterial* material);
MaterialDoc* GetCurrentMaterialDoc() { return currentMaterial; };
//State Checking Methods
bool DoesFileNeedApply(const char* filename);
bool DoesAnyNeedApply();
bool IsFileModified(const char* filename);
bool IsAnyModified();
//Adding or deleting a material
void AddMaterial(const char* name, const char* filename, const char* sourceText = NULL, bool addUndo = true);
void RedoAddMaterial(const char* name, bool clearData = true);
void DeleteMaterial(MaterialDoc* material, bool addUndo = true);
//Applying
void ApplyMaterial(MaterialDoc* materialDoc);
void ApplyFile(const char* filename);
void ApplyAll();
//Saving
void SaveMaterial(MaterialDoc* material);
void SaveFile(const char* filename);
void SaveAllMaterials();
//File Reloading
void ReloadFile(const char *filename);
//Used to get and/or create a MaterialDoc object for editing
MaterialDoc* CreateMaterialDoc(const char* materialName);
MaterialDoc* CreateMaterialDoc(idMaterial* material);
MaterialDoc* GetInProgressDoc(idMaterial* material);
//Copy Paste
void CopyMaterial(MaterialDoc* materialDoc = NULL, bool cut = false);
void ClearCopy();
bool IsCopyMaterial();
idStr GetCopyMaterialName();
void PasteMaterial(const char* name, const char* filename);
void CopyStage(MaterialDoc* materialDoc, int stageNum);
void ClearCopyStage();
bool IsCopyStage();
void PasteStage(MaterialDoc* materialDoc);
void GetCopyStageInfo(int& type, idStr& name);
//Undo/Redo
void Undo();
bool IsUndoAvailable();
void ClearUndo();
void Redo();
bool IsRedoAvailable();
void ClearRedo();
void AddMaterialUndoModifier(MaterialModifier* mod, bool clearRedo = true);
void AddMaterialRedoModifier(MaterialModifier* mod);
//Searching
bool FindMaterial(const char* name, MaterialSearchData_t* searchData, bool checkName);
//Misc
idStr GetUniqueMaterialName(idStr name);
protected:
/**
* View notification types
*/
enum {
SELECTION_CHANGE,
MATERIAL_CHANGE,
MATERIAL_APPLY,
MATERIAL_SAVE,
MATERIAL_SAVE_FILE,
MATERIAL_ADD,
MATERIAL_DELETE,
MATERIAL_ADD_STAGE,
MATERIAL_DELETE_STAGE,
MATERIAL_MOVE_STAGE,
MATERIAL_ATTRIBUTE_CHANGE,
MATERIAL_NAME_CHANGE,
FILE_RELOAD
};
void NotifyViews(MaterialDoc* materialDoc, int notifyType, ... );
//Doc Notification members
friend MaterialDoc;
void MaterialChanged(MaterialDoc* materialDoc);
void MaterialApplied(MaterialDoc* materialDoc);
void MaterialSaved(MaterialDoc* materialDoc);
void MaterialNameChanged(const char* oldName, MaterialDoc* materialDoc);
void StageAdded(MaterialDoc* materialDoc, int stageNum);
void StageDeleted(MaterialDoc* materialDoc, int stageNum);
void StageMoved(MaterialDoc* materialDoc, int from, int to);
void AttributeChanged(MaterialDoc* materialDoc, int stage, const char* attribName);
protected:
idList<MaterialView*> materialViews;
MaterialDoc* currentMaterial;
idHashTable<MaterialDoc*> inProgressMaterials;
idList<MaterialModifier*> undoModifiers;
idList<MaterialModifier*> redoModifiers;
//Copy/Paste
bool cutMaterial;
idStr copyMaterial;
//Copy/Paste Stage
idStr copyStageMaterial;
MEStage_t copyStage;
};

View File

@@ -0,0 +1,308 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialEditView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define EDIT_HEIGHT 25
#define EDIT_TAB_CONTROL 0x2006
#define NAME_CONTROL 0x2007
IMPLEMENT_DYNCREATE(MaterialEditView, CFormView)
BEGIN_MESSAGE_MAP(MaterialEditView, CFormView)
ON_WM_SIZE()
ON_WM_CREATE()
ON_NOTIFY(TCN_SELCHANGE, EDIT_TAB_CONTROL, OnTcnSelChange)
ON_NOTIFY(EN_CHANGE, IDC_MATERIALEDITOR_EDIT_TEXT, OnEnChangeEdit)
END_MESSAGE_MAP()
/**
* Constructor for MaterialEditView.
*/
MaterialEditView::MaterialEditView()
: CFormView(MaterialEditView::IDD) {
initHack = false;
sourceInit = false;
sourceChanged = false;
}
/**
* Destructor for MaterialEditView.
*/
MaterialEditView::~MaterialEditView() {
}
/**
* Called when the selected material has changed.
* @param pMaterial The newly selected material.
*/
void MaterialEditView::MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) {
//Apply any text changes that have been made
ApplyMaterialSource();
if(pMaterial) {
m_nameEdit.SetWindowText(pMaterial->name);
m_textView.SetReadOnly(false);
//If the edit tab is selected then get the source
int sel = m_tabs.GetCurSel();
if (sel == 1) {
GetMaterialSource();
}
currentMaterialName = pMaterial->name;
} else {
m_nameEdit.SetWindowText("");
GetMaterialSource();
m_textView.SetReadOnly(true);
currentMaterialName = "";
}
}
void MaterialEditView::MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName) {
if(!currentMaterialName.Icmp(oldName)) {
currentMaterialName = pMaterial->name;
}
}
/**
* Returns the current source text in the source edit control.
*/
idStr MaterialEditView::GetSourceText() {
idStr text;
m_textView.GetText(text);
text.Replace( "\n", "" );
text.Replace( "\r", "\r\n" );
text.Replace( "\v", "\r\n" );
text.StripLeading( "\r\n" );
text.Insert( "\r\n\r\n", 0 );
text.StripTrailing( "\r\n" );
return text;
}
/**
* Gets the source of the current document and populates the
* source edit control.
*/
void MaterialEditView::GetMaterialSource() {
//Clear it
sourceInit = true;
m_textView.SetText("");
sourceInit = false;
if(materialDocManager) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(material) {
idStr text = material->GetEditSourceText();
// clean up new-line crapola
text.Replace( "\r", "" );
text.Replace( "\n", "\r" );
text.Replace( "\v", "\r" );
text.StripLeading( '\r' );
text.Append( "\r" );
sourceInit = true;
m_textView.SetText(text);
sourceInit = false;
}
}
}
/**
* Takes the source out of the edit control and applies it
* to the material.
*/
void MaterialEditView::ApplyMaterialSource() {
if(!sourceChanged)
return;
MaterialDoc* material = materialDocManager->CreateMaterialDoc(currentMaterialName);
if(material) {
idStr text = GetSourceText();
material->ApplySourceModify(text);
}
sourceChanged = false;
}
/**
* Transfers data to and from the controls in the console.
*/
void MaterialEditView::DoDataExchange(CDataExchange* pDX) {
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MATERIALEDITOR_EDIT_TEXT, m_textView);
}
/**
* Called by the MFC framework when the view is being created.
*/
void MaterialEditView::OnInitialUpdate() {
CFormView::OnInitialUpdate();
if(!initHack) {
initHack = true;
m_textView.Init();
m_textView.LoadKeyWordsFromFile( "editors/material.def" );
m_textView.ShowWindow(SW_HIDE);
m_textView.SetText("");
m_textView.SetReadOnly(true);
}
}
/**
* Called by the MFC framework when the view is being created.
*/
int MaterialEditView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;
m_nameEdit.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_READONLY, CRect(0,0,0,0), this, NAME_CONTROL);
m_editSplitter.CreateStatic(this, 1, 2);
if(!m_editSplitter.CreateView(0, 0, RUNTIME_CLASS(StageView), CSize(200, 200), NULL)) {
TRACE0("Failed to create stage property pane\n");
return -1;
}
if(!m_editSplitter.CreateView(0, 1, RUNTIME_CLASS(MaterialPropTreeView), CSize(500, 200), NULL)) {
TRACE0("Failed to create property pane\n");
return -1;
}
m_nameEdit.SetFont(materialEditorFont);
m_stageView = (StageView*)m_editSplitter.GetPane(0, 0);
m_materialPropertyView = (MaterialPropTreeView*)m_editSplitter.GetPane(0, 1);
m_tabs.Create(TCS_BOTTOM | TCS_FLATBUTTONS | WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, EDIT_TAB_CONTROL);
m_tabs.InsertItem(0, "Properties");
m_tabs.InsertItem(1, "Text");
m_tabs.SetFont(materialEditorFont);
return 0;
}
/**
* Windows message called when the window is resized.
*/
void MaterialEditView::OnSize(UINT nType, int cx, int cy) {
CFormView::OnSize(nType, cx, cy);
CRect tabRect;
m_tabs.GetItemRect(0, tabRect);
int tabHeight = tabRect.Height()+5;
//Hardcode the edit window height
if(m_nameEdit.GetSafeHwnd()) {
m_nameEdit.MoveWindow(1,1, cx-2, 20);
}
if(m_tabs.GetSafeHwnd()) {
m_tabs.MoveWindow(0, cy-tabHeight, cx, tabHeight);
}
if(m_editSplitter.GetSafeHwnd()) {
m_editSplitter.MoveWindow(1, 22, cx-2, cy-tabHeight-22);
}
if(m_textView.GetSafeHwnd()) {
m_textView.MoveWindow(1, 22, cx-2, cy-tabHeight-22);
}
}
/**
* Called when the user changes the properties/text tab selection. This methods shows and hides
* the appropriate windows.
*/
void MaterialEditView::OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult) {
int sel = m_tabs.GetCurSel();
switch(sel) {
case 0:
m_editSplitter.ShowWindow(SW_SHOW);
m_textView.ShowWindow(SW_HIDE);
ApplyMaterialSource();
m_stageView->RefreshStageList();
break;
case 1:
m_editSplitter.ShowWindow(SW_HIDE);
m_textView.ShowWindow(SW_SHOW);
GetMaterialSource();
m_textView.SetReadOnly(false);
}
}
/**
* Called when the user changes text in the edit control
*/
void MaterialEditView::OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult ) {
if(materialDocManager && !sourceInit) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(material && !material->IsSourceModified()) {
sourceChanged = true;
material->SourceModify(this);
}
}
}

View File

@@ -0,0 +1,87 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialEditor.h"
#include "MaterialPropTreeView.h"
#include "StageView.h"
#include "../comafx/CSyntaxRichEditCtrl.h"
/**
* View that contains the material edit controls. These controls include
* the stage view, the properties view and the source view.
*/
class MaterialEditView : public CFormView, public MaterialView, SourceModifyOwner {
public:
enum{ IDD = IDD_MATERIALEDIT_FORM };
CEdit m_nameEdit;
CSplitterWnd m_editSplitter;
StageView* m_stageView;
MaterialPropTreeView* m_materialPropertyView;
CTabCtrl m_tabs;
CSyntaxRichEditCtrl m_textView;
public:
virtual ~MaterialEditView();
//MaterialView Interface
virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial);
virtual void MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName);
//SourceModifyOwner Interface
virtual idStr GetSourceText();
protected:
MaterialEditView();
DECLARE_DYNCREATE(MaterialEditView)
void GetMaterialSource();
void ApplyMaterialSource();
//CFormView Overrides
virtual void DoDataExchange(CDataExchange* pDX);
virtual void OnInitialUpdate();
//Message Handlers
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnTcnSelChange(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnEnChangeEdit( NMHDR *pNMHDR, LRESULT *pResult );
DECLARE_MESSAGE_MAP()
protected:
bool initHack;
bool sourceInit;
bool sourceChanged;
idStr currentMaterialName;
};

View File

@@ -0,0 +1,176 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../../sys/win32/win_local.h"
#include "MaterialEditor.h"
#include "MEMainFrame.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
MEMainFrame* meMainFrame = NULL;
CFont* materialEditorFont = NULL;
/**
* Initializes the material editor tool.
*/
void MaterialEditorInit( void ) {
InitPropTree(win32.hInstance);
com_editors = EDITOR_MATERIAL;
Sys_GrabMouseCursor( false );
InitAfx();
InitCommonControls();
// Initialize OLE libraries
if (!AfxOleInit())
{
return;
}
AfxEnableControlContainer();
NONCLIENTMETRICS info;
info.cbSize = sizeof(info);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
LOGFONT lf;
memset(&lf, 0, sizeof (LOGFONT));
CWindowDC dc(NULL);
lf.lfCharSet = (BYTE)GetTextCharsetInfo(dc.GetSafeHdc(), NULL, 0);
lf.lfHeight = info.lfMenuFont.lfHeight;
lf.lfWeight = info.lfMenuFont.lfWeight;
lf.lfItalic = info.lfMenuFont.lfItalic;
// check if we should use system font
_tcscpy(lf.lfFaceName, info.lfMenuFont.lfFaceName);
materialEditorFont = new CFont;
materialEditorFont->CreateFontIndirect(&lf);
// To create the main window, this code creates a new frame window
// object and then sets it as the application's main window object
meMainFrame = new MEMainFrame;
// create and load the frame with its resources
meMainFrame->LoadFrame(IDR_ME_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);
// hide the doom window by default
::ShowWindow ( win32.hWnd, SW_HIDE );
// The one and only window has been initialized, so show and update it
meMainFrame->ShowWindow(SW_SHOW);
meMainFrame->UpdateWindow();
}
/**
* Called every frame by the doom engine to allow the material editor to process messages.
*/
void MaterialEditorRun( void ) {
MSG *msg = AfxGetCurrentMessage();
while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) {
// pump message
if ( !AfxGetApp()->PumpMessage() ) {
}
}
}
/**
* Called by the doom engine when the material editor needs to be destroyed.
*/
void MaterialEditorShutdown( void ) {
delete meMainFrame;
delete materialEditorFont;
meMainFrame = NULL;
}
/**
* Allows the doom engine to reflect console output to the material editors console.
*/
void MaterialEditorPrintConsole( const char *msg ) {
if(com_editors & EDITOR_MATERIAL)
meMainFrame->PrintConsoleMessage(msg);
}
/**
* Returns the handle to the main Material Editor Window
*/
HWND GetMaterialEditorWindow() {
return meMainFrame->GetSafeHwnd();
}
/**
* Simple about box for the material editor.
*/
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
enum { IDD = IDD_ME_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
/**
* Constructor for the about box.
*/
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) {
}
/**
* Called by the MFC framework to exchange data with the window controls.
*/
void CAboutDlg::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

View File

@@ -0,0 +1,45 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "../../sys/win32/rc/MaterialEditor_resource.h"
/**
* Structure used to store the user defined search parameters.
*/
typedef struct {
bool searched;
idStr searchText;
int nameOnly;
int searchScope;
} MaterialSearchData_t;
extern CFont* materialEditorFont;
extern HWND GetMaterialEditorWindow();

View File

@@ -0,0 +1,428 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialModifier.h"
#include "MaterialDocManager.h"
#include "MaterialTreeView.h"
//////////////////////////////////////////////////////////////////////////////
//MaterialModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for MaterialModifier
*/
MaterialModifier::MaterialModifier(MaterialDocManager* manager, const char* materialName) {
this->manager = manager;
this->materialName = materialName;
}
//////////////////////////////////////////////////////////////////////////////
//AttributeMaterialModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for AttributeMaterialModifier
*/
AttributeMaterialModifier::AttributeMaterialModifier(MaterialDocManager* manager, const char* materialName, int stage, const char* key)
: MaterialModifier(manager, materialName) {
this->stage = stage;
this->key = key;
}
//////////////////////////////////////////////////////////////////////////////
//AttributeMaterialModifierString
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for AttributeMaterialModifierString
*/
AttributeMaterialModifierString::AttributeMaterialModifierString(MaterialDocManager* manager, const char* materialName, int stage, const char* key, const char* value, const char* oldValue)
: AttributeMaterialModifier(manager, materialName, stage, key) {
this->value = value;
this->oldValue = oldValue;
}
/**
* Performs an undo operation of a string attribute change.
*/
void AttributeMaterialModifierString::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->SetAttribute(stage, key, oldValue, false);
}
/**
* Performs a redo operation of a string attribute change.
*/
void AttributeMaterialModifierString::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->SetAttribute(stage, key, value, false);
}
//////////////////////////////////////////////////////////////////////////////
//AttributeMaterialModifierBool
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for AttributeMaterialModifierBool
*/
AttributeMaterialModifierBool::AttributeMaterialModifierBool(MaterialDocManager* manager, const char* materialName, int stage, const char* key, bool value, bool oldValue)
: AttributeMaterialModifier(manager, materialName, stage, key) {
this->value = value;
this->oldValue = oldValue;
}
/**
* Performs an undo operation of a boolean attribute change.
*/
void AttributeMaterialModifierBool::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->SetAttributeBool(stage, key, oldValue, false);
}
/**
* Performs a redo operation of a boolean attribute change.
*/
void AttributeMaterialModifierBool::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->SetAttributeBool(stage, key, value, false);
}
//////////////////////////////////////////////////////////////////////////////
//StageMoveModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for StageMoveModifier
*/
StageMoveModifier::StageMoveModifier(MaterialDocManager* manager, const char* materialName, int from, int to)
: MaterialModifier(manager, materialName) {
this->from = from;
this->to = to;
}
/**
* Performs an undo operation of a stage move.
*/
void StageMoveModifier::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->MoveStage(to, from, false);
}
/**
* Performs a redo operation of a moved stage.
*/
void StageMoveModifier::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->MoveStage(from, to, false);
}
//////////////////////////////////////////////////////////////////////////////
//StageDeleteModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for StageDeleteModifier
*/
StageDeleteModifier::StageDeleteModifier(MaterialDocManager* manager, const char* materialName, int stageNum, idDict stageData)
: MaterialModifier(manager, materialName) {
this->stageNum = stageNum;
this->stageData = stageData;
}
/**
* Performs an undo operation of a deleted stage.
*/
void StageDeleteModifier::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->InsertStage(stageNum, stageData.GetInt("stagetype"), stageData.GetString("name"), false);
material->SetData(stageNum, &stageData);
}
/**
* Performs a redo operation of a deleted stage.
*/
void StageDeleteModifier::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->RemoveStage(stageNum, false);
}
//////////////////////////////////////////////////////////////////////////////
//StageInsertModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for StageInsertModifier
*/
StageInsertModifier::StageInsertModifier(MaterialDocManager* manager, const char* materialName, int stageNum, int stageType, const char* stageName)
: MaterialModifier(manager, materialName) {
this->stageNum = stageNum;
this->stageType = stageType;
this->stageName = stageName;
}
/**
* Performs an undo operation of an inserted stage.
*/
void StageInsertModifier::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->RemoveStage(stageNum, false);
}
/**
* Performs a redo operation of an inserted stage.
*/
void StageInsertModifier::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->InsertStage(stageNum, stageType, stageName, false);
}
//////////////////////////////////////////////////////////////////////////////
//AddMaterialModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for AddMaterialModifier
*/
AddMaterialModifier::AddMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile)
: MaterialModifier(manager, materialName) {
this->materialFile = materialFile;
}
/**
* Performs an undo operation of an added material.
*/
void AddMaterialModifier::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
manager->DeleteMaterial(material, false);
}
/**
* Performs a redo operation of an added material.
*/
void AddMaterialModifier::Redo() {
manager->RedoAddMaterial(materialName);
}
//////////////////////////////////////////////////////////////////////////////
//DeleteMaterialModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for DeleteMaterialModifier
*/
DeleteMaterialModifier::DeleteMaterialModifier(MaterialDocManager* manager, const char* materialName)
: MaterialModifier(manager, materialName) {
}
/**
* Performs an undo operation of a deleted material.
*/
void DeleteMaterialModifier::Undo() {
manager->RedoAddMaterial(materialName, false);
}
/**
* Performs a redo operation of a deleted material.
*/
void DeleteMaterialModifier::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
manager->DeleteMaterial(material, false);
}
//////////////////////////////////////////////////////////////////////////////
//MoveMaterialModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for MoveMaterialModifier
*/
MoveMaterialModifier::MoveMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile, const char* copyMaterial)
: MaterialModifier(manager, materialName) {
this->materialFile = materialFile;
this->copyMaterial = copyMaterial;
}
/**
* Performs an undo operation of a moved material
*/
void MoveMaterialModifier::Undo() {
//Delete New Material
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
manager->DeleteMaterial(material, false);
//RedoAdd Old Material
manager->RedoAddMaterial(copyMaterial, false);
}
/**
* Performs a redo operation of a moved material.
*/
void MoveMaterialModifier::Redo() {
//Delete Old Material
MaterialDoc* material = manager->CreateMaterialDoc(copyMaterial);
manager->DeleteMaterial(material, false);
//Redo Add New Material
manager->RedoAddMaterial(materialName, false);
}
//////////////////////////////////////////////////////////////////////////////
//RenameMaterialModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for RenameMaterialModifier
*/
RenameMaterialModifier::RenameMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* oldName)
: MaterialModifier(manager, materialName) {
this->oldName = oldName;
}
/**
* Performs an undo operation of a renamed material
*/
void RenameMaterialModifier::Undo() {
MaterialDoc* material = manager->CreateMaterialDoc(materialName);
material->SetMaterialName(oldName, false);
}
/**
* Performs a redo operation of a renamed material.
*/
void RenameMaterialModifier::Redo() {
MaterialDoc* material = manager->CreateMaterialDoc(oldName);
material->SetMaterialName(materialName, false);
}
//////////////////////////////////////////////////////////////////////////////
//AddMaterialFolderModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for AddMaterialFolderModifier
*/
AddMaterialFolderModifier::AddMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, HTREEITEM parent)
: MaterialModifier(manager, materialName) {
this->view = view;
this->item = item;
this->parent = parent;
}
/**
* Performs an undo operation of an added material folder.
*/
void AddMaterialFolderModifier::Undo() {
view->DeleteFolder(item, false);
}
/**
* Performs a redo operation of an added material folder.
*/
void AddMaterialFolderModifier::Redo() {
view->AddFolder(materialName, parent);
}
//////////////////////////////////////////////////////////////////////////////
//RenameMaterialFolderModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for RenameMaterialFolderModifier
*/
RenameMaterialFolderModifier::RenameMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, const char* oldName)
: MaterialModifier(manager, materialName) {
this->view = view;
this->item = item;
this->oldName = oldName;
}
/**
* Performs an undo operation of a renamed material folder.
*/
void RenameMaterialFolderModifier::Undo() {
view->RenameFolder(item, oldName);
}
/**
* Performs a redo operation of a renamed material folder.
*/
void RenameMaterialFolderModifier::Redo() {
view->RenameFolder(item, materialName);
}
//////////////////////////////////////////////////////////////////////////////
//DeleteMaterialFolderModifier
//////////////////////////////////////////////////////////////////////////////
/**
* Constructor for DeleteMaterialFolderModifier
*/
DeleteMaterialFolderModifier::DeleteMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM parent, idStrList* affectedMaterials)
: MaterialModifier(manager, materialName) {
this->view = view;
this->parent = parent;
this->affectedMaterials = *affectedMaterials;
}
/**
* Performs an undo operation of a deleted material folder.
*/
void DeleteMaterialFolderModifier::Undo() {
//Add the folder back and save the folder position for the redo
item = view->AddFolder(materialName, parent);
//Add each of the children back
for(int i = 0; i < affectedMaterials.Num(); i++) {
manager->RedoAddMaterial(affectedMaterials[i], false);
}
}
/**
* Performs a redo operation of a deleted material folder.
*/
void DeleteMaterialFolderModifier::Redo() {
view->DeleteFolder(item, false);
}

View File

@@ -0,0 +1,268 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialEditor.h"
class MaterialDocManager;
class MaterialTreeView;
/**
* Base class for modifications that can be made to a material that can be undone and redone.
*/
class MaterialModifier {
public:
MaterialModifier(MaterialDocManager* manager, const char* materialName);
virtual ~MaterialModifier() {};
virtual void Undo() = 0;
virtual void Redo() = 0;
protected:
MaterialDocManager* manager;
idStr materialName;
};
/**
* Base class for Undo/Redo operations for attribute changes
*/
class AttributeMaterialModifier : public MaterialModifier {
public:
AttributeMaterialModifier(MaterialDocManager* manager, const char* materialName, int stage, const char* key);
virtual ~AttributeMaterialModifier() {};
virtual void Undo() = 0;
virtual void Redo() = 0;
protected:
int stage;
idStr key;
};
/**
* Undo/Redo operation for string attribute changes
*/
class AttributeMaterialModifierString : public AttributeMaterialModifier {
public:
AttributeMaterialModifierString(MaterialDocManager* manager, const char* materialName, int stage, const char* key, const char* value, const char* oldValue);
virtual ~AttributeMaterialModifierString() {};
virtual void Undo();
virtual void Redo();
protected:
idStr value;
idStr oldValue;
};
/**
* Undo/Redo operation for boolean attribute changes
*/
class AttributeMaterialModifierBool : public AttributeMaterialModifier {
public:
AttributeMaterialModifierBool(MaterialDocManager* manager, const char* materialName, int stage, const char* key, bool value, bool oldValue);
virtual ~AttributeMaterialModifierBool() {};
virtual void Undo();
virtual void Redo();
protected:
bool value;
bool oldValue;
};
/**
* Undo/Redo operation for stage moves
*/
class StageMoveModifier : public MaterialModifier {
public:
StageMoveModifier(MaterialDocManager* manager, const char* materialName, int from, int to);
virtual ~StageMoveModifier() {};
virtual void Undo();
virtual void Redo();
protected:
int from;
int to;
};
/**
* Undo/Redo operation for stage deletes
*/
class StageDeleteModifier : public MaterialModifier {
public:
StageDeleteModifier(MaterialDocManager* manager, const char* materialName, int stageNum, idDict stageData);
virtual ~StageDeleteModifier() {};
virtual void Undo();
virtual void Redo();
protected:
int stageNum;
idDict stageData;
};
/**
* Undo/Redo operation for stage inserts
*/
class StageInsertModifier : public MaterialModifier {
public:
StageInsertModifier(MaterialDocManager* manager, const char* materialName, int stageNum, int stageType, const char* stageName);
virtual ~StageInsertModifier() {};
virtual void Undo();
virtual void Redo();
protected:
int stageNum;
int stageType;
idStr stageName;
};
/**
* Undo/Redo operation for adding materials
*/
class AddMaterialModifier : public MaterialModifier {
public:
AddMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile);
virtual ~AddMaterialModifier() {};
virtual void Undo();
virtual void Redo();
protected:
idStr materialFile;
};
/**
* Undo/Redo operation for deleting materials
*/
class DeleteMaterialModifier : public MaterialModifier {
public:
DeleteMaterialModifier(MaterialDocManager* manager, const char* materialName);
virtual ~DeleteMaterialModifier() {};
virtual void Undo();
virtual void Redo();
protected:
};
/**
* Undo/Redo operation for moving materials
*/
class MoveMaterialModifier : public MaterialModifier {
public:
MoveMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* materialFile, const char* copyMaterial);
virtual ~MoveMaterialModifier() {};
virtual void Undo();
virtual void Redo();
protected:
idStr materialFile;
idStr copyMaterial;
};
/**
* Undo/Redo operation for renaming materials
*/
class RenameMaterialModifier : public MaterialModifier {
public:
RenameMaterialModifier(MaterialDocManager* manager, const char* materialName, const char* oldName);
virtual ~RenameMaterialModifier() {};
virtual void Undo();
virtual void Redo();
protected:
idStr oldName;
};
/**
* Undo/Redo operation for adding material folders
*/
class AddMaterialFolderModifier : public MaterialModifier {
public:
AddMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, HTREEITEM parent);
virtual ~AddMaterialFolderModifier() {};
virtual void Undo();
virtual void Redo();
protected:
MaterialTreeView* view;
HTREEITEM item;
HTREEITEM parent;
};
/**
* Undo/Redo operation for renaming a material folder
*/
class RenameMaterialFolderModifier : public MaterialModifier {
public:
RenameMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM item, const char* oldName);
virtual ~RenameMaterialFolderModifier() {};
virtual void Undo();
virtual void Redo();
protected:
MaterialTreeView* view;
HTREEITEM item;
idStr oldName;
};
/**
* Undo/Redo operation for deleting a material folder
*/
class DeleteMaterialFolderModifier : public MaterialModifier {
public:
DeleteMaterialFolderModifier(MaterialDocManager* manager, const char* materialName, MaterialTreeView* view, HTREEITEM parent, idStrList* affectedMaterials);
virtual ~DeleteMaterialFolderModifier() {};
virtual void Undo();
virtual void Redo();
protected:
MaterialTreeView* view;
idStrList affectedMaterials;
HTREEITEM item;
HTREEITEM parent;
};

View File

@@ -0,0 +1,368 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialPreviewPropView.h"
// MaterialPropTreeView
IMPLEMENT_DYNCREATE(MaterialPreviewPropView, CPropTreeView)
MaterialPreviewPropView::MaterialPreviewPropView() {
numLights = 0;
materialPreview = NULL;
}
MaterialPreviewPropView::~MaterialPreviewPropView() {
}
BEGIN_MESSAGE_MAP(MaterialPreviewPropView, CPropTreeView)
ON_NOTIFY( PTN_ITEMCHANGED, IDC_PROPERTYTREE, OnPropertyChangeNotification )
ON_NOTIFY( PTN_ITEMBUTTONCLICK, IDC_PROPERTYTREE, OnPropertyButtonClick )
END_MESSAGE_MAP()
void MaterialPreviewPropView::AddLight( void ) {
int i, count, lightShaderIndex = 0;
const idMaterial *mat;
CPropTreeItemButton* pRoot;
CPropTreeItemCombo* pCombo;
CPropTreeItemColor* pColor;
CPropTreeItemCheck* pCheck;
CPropTreeItemEdit* pEdit;
//Increase the number of lights
numLights++;
pRoot = (CPropTreeItemButton*)m_Tree.InsertItem(new CPropTreeItemButton());
pRoot->SetLabelText(_T(va("Light #%d", numLights)));
pRoot->SetInfoText(_T(va("Parameters for light number %d.", numLights)));
pRoot->SetButtonText( "Remove" );
pRoot->SetCtrlID( numLights - 1 );
pRoot->Expand();
pCombo = (CPropTreeItemCombo*)m_Tree.InsertItem(new CPropTreeItemCombo(), pRoot);
pCombo->SetLabelText( _T("Shader") );
pCombo->SetInfoText( _T("Set the light shader.") );
pCombo->SetDropDownHeight( 200 );
pCombo->CreateComboBox();
// Add all light shaders to the combo box
count = declManager->GetNumDecls( DECL_MATERIAL );
for (i = 0; i < count; i++) {
mat = declManager->MaterialByIndex(i, false);
idStr materialName = mat->GetName();
materialName.ToLower();
if ( materialName.Left(7) == "lights/" || materialName.Left(5) == "fogs/" ) {
pCombo->InsertString( lightShaderIndex, materialName );
pCombo->SetItemData( lightShaderIndex, lightShaderIndex );
if ( materialName == "lights/defaultpointlight" ) {
pCombo->SetCurSel( lightShaderIndex );
}
lightShaderIndex++;
}
}
pColor = (CPropTreeItemColor*)m_Tree.InsertItem(new CPropTreeItemColor(), pRoot);
pColor->SetLabelText(_T("Color"));
pColor->SetInfoText(_T("Color of the light."));
pColor->SetItemValue((LPARAM)RGB(0xff, 0xff, 0xff)); // default as color white
pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pRoot);
pEdit->SetLabelText(_T("Radius"));
pEdit->SetInfoText(_T("Radius of the light."));
pEdit->SetItemValue( (LPARAM)_T("300.0") );
pCheck = (CPropTreeItemCheck*)m_Tree.InsertItem(new CPropTreeItemCheck(), pRoot);
pCheck->SetLabelText(_T("Move light"));
pCheck->SetInfoText(_T("When checked, allow light to move."));
pCheck->CreateCheckBox();
pCheck->SetCheckState( BST_CHECKED );
if ( materialPreview ) {
materialPreview->OnAddLight();
}
}
//Create sample data for the preview properties
void MaterialPreviewPropView::InitializePropTree( void ) {
int i;
CPropTreeItem *pRoot;
CPropTreeItem *pParmRoot;
CPropTreeItemCheck *pCheck;
CPropTreeItemEdit *pEdit;
pRoot = m_Tree.InsertItem(new CPropTreeItem());
pRoot->SetLabelText(_T("Preview Properties"));
pRoot->SetInfoText(_T("Properties for the preview window."));
pRoot->Expand(); // have this item expanded by default
CPropTreeItemCombo* pCombo;
pCombo = (CPropTreeItemCombo*)m_Tree.InsertItem(new CPropTreeItemCombo(), pRoot);
pCombo->SetLabelText(_T("Model Type"));
pCombo->SetInfoText(_T("Select the type of model on which to preview the material."));
pCombo->CreateComboBox();
pCombo->InsertString( 0, "Cube" );
pCombo->InsertString( 1, "Box - 2:1");
pCombo->InsertString( 2, "Box - 4:1");
pCombo->InsertString( 3, "Box - 1:2");
pCombo->InsertString( 4, "Box - 1:4");
pCombo->InsertString( 5, "Cylinder - V");
pCombo->InsertString( 6, "Cylinder - H");
pCombo->InsertString( 7, "Sphere");
pCombo->SetItemData( 0, 0 );
pCombo->SetItemData( 1, 1 );
pCombo->SetItemData( 2, 2 );
pCombo->SetItemData( 3, 3 );
pCombo->SetItemData( 4, 4 );
pCombo->SetItemData( 5, 5 );
pCombo->SetItemData( 6, 6 );
pCombo->SetItemData( 7, 7 );
pCombo->SetCurSel( 0 );
// Custom model entry
/*pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pRoot );
pEdit->SetLabelText(_T("Custom Model"));
pEdit->SetInfoText(_T("Specify any model to display the current material."));
pEdit->SetItemValue((LPARAM)_T(""));*/
CPropTreeItemEditButton *pCutomButton;
pCutomButton = (CPropTreeItemEditButton*)m_Tree.InsertItem(new CPropTreeItemEditButton(), pRoot );
pCutomButton->SetButtonText(_T("..."));
pCutomButton->SetLabelText(_T("Custom Model"));
pCutomButton->SetInfoText(_T("Specify any model to display the current material."));
pCutomButton->SetItemValue((LPARAM)_T(""));
// Checkbox for showing debug light spheres
pCheck = (CPropTreeItemCheck*)m_Tree.InsertItem( new CPropTreeItemCheck(), pRoot );
pCheck->SetLabelText(_T("Show Lights"));
pCheck->SetInfoText(_T("Show the light origin sphere and number in the preview."));
pCheck->CreateCheckBox();
pCheck->SetCheckState( BST_CHECKED );
// Local and Global shader parms
pParmRoot = m_Tree.InsertItem(new CPropTreeItem());
pParmRoot->SetLabelText(_T("Local Parms"));
pParmRoot->SetInfoText(_T("Local shaderparms for the model being displayed."));
pParmRoot->Expand( FALSE ); // have this item NOT expanded by default
for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) {
pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pParmRoot );
pEdit->SetLabelText(_T(va("parm%d", i)));
pEdit->SetInfoText(_T("Set the local shaderparm for the model"));
if ( i < 4 ) {
pEdit->SetItemValue((LPARAM)_T("1"));
} else {
pEdit->SetItemValue((LPARAM)_T("0"));
}
}
pParmRoot = m_Tree.InsertItem(new CPropTreeItem());
pParmRoot->SetLabelText(_T("Global Parms"));
pParmRoot->SetInfoText(_T("Global shaderparms for the renderworld being displayed."));
pParmRoot->Expand( FALSE ); // have this item NOT expanded by default
for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
pEdit = (CPropTreeItemEdit*)m_Tree.InsertItem( new CPropTreeItemEdit(), pParmRoot );
pEdit->SetLabelText(_T(va("global%d", i)));
pEdit->SetInfoText(_T("Set the global shaderparm for the renderworld"));
if ( i < 4 ) {
pEdit->SetItemValue((LPARAM)_T("1"));
} else {
pEdit->SetItemValue((LPARAM)_T("0"));
}
}
// Lights
pRoot = m_Tree.InsertItem(new CPropTreeItem());
pRoot->SetLabelText(_T(""));
pRoot->SetInfoText(_T(""));
CPropTreeItemButton *pButton;
pButton = (CPropTreeItemButton*)m_Tree.InsertItem(new CPropTreeItemButton());
pButton->SetButtonText(_T(" Add Light "));
pButton->SetLabelText(_T("Preview Lights"));
pButton->SetInfoText(_T("Test the button."));
pRoot = m_Tree.InsertItem(new CPropTreeItem());
pRoot->SetLabelText(_T(""));
pRoot->SetInfoText(_T(""));
AddLight();
}
// MaterialPreviewPropView drawing
void MaterialPreviewPropView::OnDraw(CDC* pDC)
{
// TODO: add draw code here
}
// MaterialPreviewPropView diagnostics
#ifdef _DEBUG
void MaterialPreviewPropView::AssertValid() const
{
CPropTreeView::AssertValid();
}
void MaterialPreviewPropView::Dump(CDumpContext& dc) const
{
CPropTreeView::Dump(dc);
}
#endif //_DEBUG
void MaterialPreviewPropView::RegisterPreviewView( MaterialPreviewView *view ) {
materialPreview = view;
}
// MaterialPreviewPropView message handlers
void MaterialPreviewPropView::OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult ) {
idVec3 testColor;
int lightId = 0;
COLORREF color;
NMPROPTREE *nmProp;
CPropTreeItem *item;
CPropTreeItem *parent;
nmProp = (NMPROPTREE *)nmhdr;
item = nmProp->pItem;
// Determine which light this item modifies
parent = item->GetParent();
if ( parent ) {
lightId = parent->GetCtrlID();
}
idStr itemLabel = item->GetLabelText();
if ( itemLabel == "Model Type" ) {
materialPreview->OnModelChange( item->GetItemValue() );
} else if ( itemLabel == "Custom Model" ) {
materialPreview->OnCustomModelChange( (const char *)item->GetItemValue() );
} else if ( itemLabel == "Show Lights" ) {
materialPreview->OnShowLightsChange( item->GetItemValue() ? true : false );
} else if ( itemLabel == "Shader" ) {
CPropTreeItemCombo *combo = (CPropTreeItemCombo *)item;
CString materialName;
combo->GetLBText( combo->GetCurSel(), materialName );
materialPreview->OnLightShaderChange( lightId, materialName.GetBuffer() );
} else if ( itemLabel == "Radius" ) {
materialPreview->OnLightRadiusChange( lightId, atof( (char *)item->GetItemValue() ) );
} else if ( itemLabel == "Color" ) {
color = item->GetItemValue();
testColor.x = (float)GetRValue( color ) * (float)( 1.f/255.f );
testColor.y = (float)GetGValue( color ) * (float)( 1.f/255.f );
testColor.z = (float)GetBValue( color ) * (float)( 1.f/255.f );
materialPreview->OnLightColorChange( lightId, testColor );
} else if ( itemLabel == "Move light" ) {
materialPreview->OnLightAllowMoveChange( lightId, item->GetItemValue() ? true : false );
} else if ( itemLabel.Left(4) == "parm" ) {
int index;
itemLabel.Strip( "parm" );
index = atoi( itemLabel.c_str() );
materialPreview->OnLocalParmChange( index, atof( (char *)item->GetItemValue() ) );
} else if ( itemLabel.Left(6) == "global" ) {
int index;
itemLabel.Strip( "global" );
index = atoi( itemLabel.c_str() );
materialPreview->OnGlobalParmChange( index, atof( (char *)item->GetItemValue() ) );
}
}
void MaterialPreviewPropView::OnPropertyButtonClick( NMHDR *nmhdr, LRESULT *lresult ) {
NMPROPTREE *nmProp;
CPropTreeItem *item;
nmProp = (NMPROPTREE *)nmhdr;
item = nmProp->pItem;
idStr itemLabel = item->GetLabelText();
if ( itemLabel == "Preview Lights" ) {
AddLight();
} else if ( itemLabel.Left(5) == "Light" ) {
CPropTreeItem *light;
int lightId = item->GetCtrlID();
int testLightNum = 0;
m_Tree.DeleteItem( item );
for( light = m_Tree.GetRootItem()->GetChild(); light != NULL; light = light->GetSibling() ) {
idStr label = light->GetLabelText();
if ( label.Left(5) == "Light" ) {
testLightNum++;
light->SetLabelText(_T(va("Light #%d", testLightNum)));
light->SetInfoText(_T(va("Parameters for light number %d.", testLightNum)));
light->SetCtrlID( testLightNum - 1 );
}
}
materialPreview->OnDeleteLight( lightId );
numLights--;
} else if ( itemLabel == "Custom Model" ) {
CFileDialog dlg(TRUE);
dlg.m_ofn.Flags |= OFN_FILEMUSTEXIST;
item->Check(FALSE);
if( dlg.DoModal()== IDOK) {
item->Check(FALSE);
item->SetItemValue((LPARAM)fileSystem->OSPathToRelativePath(dlg.m_ofn.lpstrFile));
m_Tree.SendNotify(PTN_ITEMCHANGED, item);
}
}
}

View File

@@ -0,0 +1,68 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "../common/PropTree/PropTreeView.h"
#include "MaterialPreviewView.h"
// MaterialPreviewPropView view
class MaterialPreviewPropView : public CPropTreeView
{
DECLARE_DYNCREATE(MaterialPreviewPropView)
protected:
MaterialPreviewPropView(); // protected constructor used by dynamic creation
virtual ~MaterialPreviewPropView();
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
afx_msg void OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult );
afx_msg void OnPropertyButtonClick( NMHDR *nmhdr, LRESULT *lresult );
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
void AddLight( void );
void InitializePropTree( void );
void RegisterPreviewView( MaterialPreviewView *view );
protected:
int numLights;
MaterialPreviewView *materialPreview;
DECLARE_MESSAGE_MAP()
};

View File

@@ -0,0 +1,655 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../../idlib/precompiled.h"
#pragma hdrstop
#include "../radiant/QE3.H"
#include "MaterialPreviewView.h"
// MaterialPreviewView
IMPLEMENT_DYNCREATE(MaterialPreviewView, CView)
MaterialPreviewView::MaterialPreviewView() {
// Initialize the rendered material
renderedView.setMedia( "_default" );
}
MaterialPreviewView::~MaterialPreviewView() {
}
BEGIN_MESSAGE_MAP(MaterialPreviewView, CView)
ON_WM_CREATE()
ON_WM_SIZE()
END_MESSAGE_MAP()
// MaterialPreviewView drawing
void MaterialPreviewView::OnDraw(CDC* pDC) {
}
// MaterialPreviewView diagnostics
#ifdef _DEBUG
void MaterialPreviewView::AssertValid() const {
CView::AssertValid();
}
void MaterialPreviewView::Dump(CDumpContext& dc) const {
CView::Dump(dc);
}
#endif //_DEBUG
// MaterialPreviewView message handlers
int MaterialPreviewView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
DWORD dwStyle;
CRect rc;
dwStyle = WS_CHILD|WS_VISIBLE;
// Init the control's size to cover the entire client area
GetClientRect(rc);
// Initialize the rendered window and material
renderWindow.Create( NULL, "renderWindow", dwStyle, rc, this, 1010 );
renderWindow.setDrawable( &renderedView );
renderWindow.SetWindowPos(NULL, 0, 0, rc.Width(), rc.Height(), SWP_SHOWWINDOW);
return 0;
}
void MaterialPreviewView::OnSize(UINT nType, int cx, int cy)
{
CRect rc;
CView::OnSize( nType, cx, cy );
GetClientRect( rc );
renderWindow.SetWindowPos(NULL, 0, 0, rc.Width(), rc.Height(), SWP_SHOWWINDOW);
renderWindow.Invalidate();
renderWindow.RedrawWindow();
}
void MaterialPreviewView::MV_OnMaterialSelectionChange( MaterialDoc *pMaterial )
{
if ( pMaterial && pMaterial->renderMaterial ) {
currentMaterial = pMaterial->renderMaterial->GetName();
renderedView.setMedia( currentMaterial );
renderWindow.Invalidate();
renderWindow.RedrawWindow();
}
}
void MaterialPreviewView::OnLocalParmChange( int parmNum, float value ) {
renderedView.setLocalParm( parmNum, value );
}
void MaterialPreviewView::OnGlobalParmChange( int parmNum, float value ) {
renderedView.setGlobalParm( parmNum, value );
}
void MaterialPreviewView::OnLightShaderChange( int lightId, idStr shaderName ) {
renderedView.setLightShader( lightId, shaderName );
}
void MaterialPreviewView::OnLightColorChange( int lightId, idVec3 &color ) {
renderedView.setLightColor( lightId, color );
}
void MaterialPreviewView::OnLightRadiusChange( int lightId, float radius ) {
renderedView.setLightRadius( lightId, radius );
}
void MaterialPreviewView::OnLightAllowMoveChange( int lightId, bool move ) {
renderedView.setLightAllowMove( lightId, move );
}
void MaterialPreviewView::OnAddLight( void ) {
renderedView.addLight();
}
void MaterialPreviewView::OnDeleteLight( int lightId ) {
renderedView.deleteLight( lightId );
}
void MaterialPreviewView::OnModelChange( int modelId ) {
renderedView.setObject( modelId );
}
void MaterialPreviewView::OnCustomModelChange( idStr modelName ) {
renderedView.setCustomModel( modelName );
}
void MaterialPreviewView::OnShowLightsChange( bool showLights ) {
renderedView.setShowLights( showLights );
}
/*
=============================================================================
=============================================================================
=============================================================================
*/
extern bool Sys_KeyDown(int key);
extern float fDiff(float f1, float f2);
idGLDrawableView::idGLDrawableView() {
material = NULL;
modelDefHandle = -1;
objectId = 0;
showLights = true;
realTime = 16;
viewOrigin.Set( 0.f, 0.f, 0.f );
viewRotation.Set( 0.f, 0.f, 0.f );
viewDistance = -196.f;
world = NULL;
worldModel = NULL;
ResetView();
}
idGLDrawableView::~idGLDrawableView() {
delete world;
delete worldModel;
}
void idGLDrawableView::ResetView( void ) {
idDict spawnArgs;
InitWorld();
memset( &worldEntity, 0, sizeof( worldEntity ) );
spawnArgs.Clear();
spawnArgs.Set("classname", "func_static");
spawnArgs.Set("name", spawnArgs.GetString("model"));
spawnArgs.Set("origin", "0 0 0");
gameEdit->ParseSpawnArgsToRenderEntity(&spawnArgs, &worldEntity);
// load a model and set the current material as its customshader
worldModel = renderModelManager->FindModel("models/materialeditor/cube128.ase");
worldEntity.hModel = worldModel;
// current material
worldEntity.customShader = material;
// current rotation
worldEntity.axis = mat3_identity;
// set global shader parms
memset( globalParms, 0, sizeof( globalParms ) );
globalParms[0] = globalParms[1] = globalParms[2] = globalParms[3] = 1.f;
worldEntity.shaderParms[0] = 1.f;
worldEntity.shaderParms[1] = 1.f;
worldEntity.shaderParms[2] = 1.f;
worldEntity.shaderParms[3] = 1.f;
modelDefHandle = world->AddEntityDef( &worldEntity );
}
void idGLDrawableView::InitWorld() {
if ( world == NULL ) {
world = renderSystem->AllocRenderWorld();
}
if ( worldModel == NULL ) {
worldModel = renderModelManager->AllocModel();
}
world->InitFromMap( NULL );
worldModel->InitEmpty( "GLWorldModel" );
viewLights.Clear();
}
void idGLDrawableView::buttonDown(int _button, float x, float y) {
pressX = x;
pressY = y;
button = _button;
if ( button == MK_RBUTTON || button == MK_LBUTTON || button == MK_MBUTTON ) {
handleMove = true;
}
}
void idGLDrawableView::mouseMove(float x, float y) {
bool doZoom;
float sensitivity = 0.5f;
if (handleMove) {
// Left mouse button rotates and zooms the view
if (button == MK_LBUTTON) {
doZoom = Sys_KeyDown(VK_MENU);
if (doZoom) {
if ( y != pressY ) {
viewDistance -= ( y - pressY );
pressY = y;
}
} else {
float xo = 0.f;
float yo = 0.f;
if (x != pressX) {
xo = (x - pressX);
pressX = x;
}
if (y != pressY) {
yo = (y - pressY);
pressY = y;
}
viewRotation.yaw += -(xo * sensitivity);
viewRotation.pitch += (yo * sensitivity);
viewRotation.pitch = idMath::ClampFloat( -89.9f, 89.9f, viewRotation.pitch );
}
// Right mouse button moves lights in the view plane
} else if (button == MK_RBUTTON) {
int i;
float lightMovement = 0;
idVec3 lightForward, lightRight, lightUp;
idVec3 lightMove;
lightMove.Zero();
viewRotation.ToVectors( &lightForward, &lightRight, &lightUp );
doZoom = Sys_KeyDown(VK_MENU);
if (doZoom) {
if ( y != pressY ) {
lightMovement = -( y - pressY ) * sensitivity;
pressY = y;
lightMovement = idMath::ClampFloat( -32.f, 32.f, lightMovement );
lightMove = lightForward * lightMovement;
}
} else {
if (x != pressX) {
lightMovement = (x - pressX) * sensitivity;
pressX = x;
lightMovement = idMath::ClampFloat( -32.f, 32.f, lightMovement );
lightMove = lightRight * lightMovement;
}
if (y != pressY) {
lightMovement = -(y - pressY) * sensitivity;
pressY = y;
lightMovement = idMath::ClampFloat( -32.f, 32.f, lightMovement );
lightMove += lightUp * lightMovement;
}
}
// Go through the lights and move the ones that are set to allow movement
for ( i = 0; i < viewLights.Num(); i++ ) {
lightInfo_t *vLight = &viewLights[i];
if ( vLight->allowMove ) {
vLight->origin += lightMove;
}
}
// Middle mouse button moves object up and down
} else if ( button == MK_MBUTTON ) {
float yo = 0.f;
if (y != pressY) {
yo = (y - pressY);
pressY = y;
}
viewOrigin.z -= yo;
UpdateModel();
}
}
}
void idGLDrawableView::addLight( void ) {
int lightId;
idStr str;
lightInfo_t viewLight;
idDict spawnArgs;
lightId = viewLights.Num();
spawnArgs.Set( "classname", "light" );
spawnArgs.Set( "name", va( "light_%d", lightId ) );
spawnArgs.Set( "origin", va( "-128 0 %d", (lightId * 16) ) );
spawnArgs.Set( "light", "300" );
spawnArgs.Set( "texture", "lights/defaultPointLight" );
sprintf( str, "%f %f %f", 1.f, 1.f, 1.f );
spawnArgs.Set( "_color", str );
gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &viewLight.renderLight );
viewLight.lightDefHandle = world->AddLightDef( &viewLight.renderLight );
viewLight.origin = viewLight.renderLight.origin;
viewLight.shader = declManager->FindMaterial( "lights/defaultPointLight", false );
viewLight.color.x = viewLight.renderLight.shaderParms[ SHADERPARM_RED ];
viewLight.color.y = viewLight.renderLight.shaderParms[ SHADERPARM_GREEN ];
viewLight.color.z = viewLight.renderLight.shaderParms[ SHADERPARM_BLUE ];
viewLight.radius = 300.f;
viewLight.allowMove = true;
// Add light to the list
viewLights.Append( viewLight );
}
void idGLDrawableView::deleteLight( const int lightId ) {
if ( lightId < viewLights.Num() ) {
world->FreeLightDef( viewLights[lightId].lightDefHandle );
viewLights.RemoveIndex( lightId );
}
}
void idGLDrawableView::UpdateCamera( renderView_t *refdef ) {
idVec3 pos, dir;
idAngles angs;
// Set the camera origin
pos = viewRotation.ToForward();
pos *= viewDistance;
refdef->vieworg = pos;
// Set the view to point back at the origin
dir = vec3_origin - pos;
angs = dir.ToAngles();
refdef->viewaxis = angs.ToMat3();
}
void idGLDrawableView::UpdateModel( void ) {
switch( objectId ) {
case 0:
worldModel = renderModelManager->FindModel("models/materialeditor/cube128.ase");
break;
case 1:
worldModel = renderModelManager->FindModel("models/materialeditor/box128x64.ase");
break;
case 2:
worldModel = renderModelManager->FindModel("models/materialeditor/box128x32.ase");
break;
case 3:
worldModel = renderModelManager->FindModel("models/materialeditor/box64x128.ase");
break;
case 4:
worldModel = renderModelManager->FindModel("models/materialeditor/box32x128.ase");
break;
case 5:
worldModel = renderModelManager->FindModel("models/materialeditor/cylinder_v.ase");
break;
case 6:
worldModel = renderModelManager->FindModel("models/materialeditor/cylinder_h.ase");
break;
case 7:
worldModel = renderModelManager->FindModel("models/materialeditor/sphere64.ase");
break;
case -1:
worldModel = renderModelManager->FindModel( customModelName.c_str() );
break;
default:
worldModel = renderModelManager->FindModel("models/materialeditor/cube128.ase");
break;
};
worldEntity.hModel = worldModel;
// current material
worldEntity.customShader = material;
// current rotation
worldEntity.origin = viewOrigin;
worldEntity.axis = mat3_identity;
world->UpdateEntityDef( modelDefHandle, &worldEntity );
}
void idGLDrawableView::UpdateLights( void ) {
int i;
for ( i = 0; i < viewLights.Num(); i++ ) {
lightInfo_t *vLight = &viewLights[i];
vLight->renderLight.shader = vLight->shader;
vLight->renderLight.shaderParms[ SHADERPARM_RED ] = vLight->color.x;
vLight->renderLight.shaderParms[ SHADERPARM_GREEN ] = vLight->color.y;
vLight->renderLight.shaderParms[ SHADERPARM_BLUE ] = vLight->color.z;
vLight->renderLight.lightRadius[0] = vLight->renderLight.lightRadius[1] =
vLight->renderLight.lightRadius[2] = vLight->radius;
vLight->renderLight.origin = vLight->origin;
world->UpdateLightDef( vLight->lightDefHandle, &vLight->renderLight );
}
}
void idGLDrawableView::drawLights( renderView_t *refdef ) {
int i;
for ( i=0; i < viewLights.Num(); i++ ) {
lightInfo_t *vLight = &viewLights[i];
idVec4 lColor;
lColor.x = vLight->color.x;
lColor.y = vLight->color.y;
lColor.z = vLight->color.z;
lColor.w = 1.f;
idSphere sphere(vLight->renderLight.origin, 4);
session->rw->DebugSphere( lColor, sphere, 0, true );
session->rw->DrawText( va( "%d", i+1 ), vLight->renderLight.origin + idVec3(0,0,5), 0.25f, idVec4(1,1,0,1), refdef->viewaxis, 1, 0, true );
}
}
void idGLDrawableView::draw(int x, int y, int w, int h) {
int i;
renderView_t refdef;
const idMaterial *mat = material;
if (mat) {
qglViewport(x, y, w, h);
qglScissor(x, y, w, h);
qglMatrixMode(GL_PROJECTION);
qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
qglClear(GL_COLOR_BUFFER_BIT);
UpdateLights();
// render it
renderSystem->BeginFrame(w, h);
memset( &refdef, 0, sizeof( refdef ) );
UpdateCamera( &refdef );
// Copy global shaderparms to view
for( i = 0; i < MAX_GLOBAL_SHADER_PARMS; i++ ) {
refdef.shaderParms[ i ] = globalParms[ i ];
}
refdef.width = SCREEN_WIDTH;
refdef.height = SCREEN_HEIGHT;
refdef.fov_x = 90;
refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;
refdef.time = eventLoop->Milliseconds();
world->RenderScene( &refdef );
if ( showLights ) {
drawLights( &refdef );
}
renderSystem->EndFrame( NULL, NULL );
world->DebugClearLines( refdef.time );
qglMatrixMode( GL_MODELVIEW );
qglLoadIdentity();
}
}
// ============================
// Interface to PropTree Window
// ============================
void idGLDrawableView::setMedia(const char *name) {
float ratio = 1;
if (name && *name) {
material = declManager->FindMaterial(name);
} else {
material = NULL;
}
if ( material->GetNumStages() == 0 ) {
material = declManager->FindMaterial( "_default" );
}
if ( material->GetStage(0)->texture.image ) {
ratio = (float)((float)material->GetImageWidth() / (float)material->GetImageHeight());
}
if ( objectId == -1 ) {
// Don't change a custom model
} else if ( ratio == 1 ) {
objectId = 0;
} else if ( ratio == 2 ) {
objectId = 1;
} else if ( ratio == 4 ) {
objectId = 2;
} else if ( ratio == 0.5 ) {
objectId = 3;
} else if ( ratio == 0.25 ) {
objectId = 4;
}
UpdateModel();
}
void idGLDrawableView::setLocalParm( int parmNum, float value ) {
if ( parmNum < 0 || parmNum >= MAX_ENTITY_SHADER_PARMS ) {
return;
}
worldEntity.shaderParms[ parmNum ] = value;
UpdateModel();
}
void idGLDrawableView::setGlobalParm( int parmNum, float value ) {
if ( parmNum < 0 || parmNum >= MAX_GLOBAL_SHADER_PARMS ) {
return;
}
globalParms[ parmNum ] = value;
}
void idGLDrawableView::setLightShader( const int lightId, const idStr shaderName ) {
if ( lightId < viewLights.Num() ) {
viewLights[ lightId ].shader = declManager->FindMaterial( shaderName, false );
}
}
void idGLDrawableView::setLightColor( const int lightId, const idVec3 &value ) {
if ( lightId < viewLights.Num() ) {
// Update this lights color
viewLights[ lightId ].color = value;
}
}
void idGLDrawableView::setLightRadius( const int lightId, const float radius ) {
if ( lightId < viewLights.Num() ) {
viewLights[ lightId ].radius = radius;
}
}
void idGLDrawableView::setLightAllowMove( const int lightId, const bool move ) {
if ( lightId < viewLights.Num() ) {
viewLights[ lightId ].allowMove = move;
}
}
void idGLDrawableView::setObject( int Id ) {
objectId = Id;
UpdateModel();
}
void idGLDrawableView::setCustomModel( const idStr modelName ) {
if ( modelName.Length() ) {
objectId = -1;
} else {
objectId = 0;
}
customModelName = modelName;
UpdateModel();
}
void idGLDrawableView::setShowLights( bool _showLights ) {
showLights = _showLights;
}

View File

@@ -0,0 +1,149 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialView.h"
#include "../radiant/GLWidget.h"
class idGLDrawableView : public idGLDrawable {
public:
idGLDrawableView();
~idGLDrawableView();
virtual void setMedia(const char *name);
virtual void draw(int x, int y, int w, int h);
virtual void buttonUp(int button){}
virtual void buttonDown(int _button, float x, float y);
virtual void mouseMove(float x, float y);
virtual void Update() {};
void UpdateCamera( renderView_t *refdef );
void UpdateModel( void );
void UpdateLights( void );
void addLight( void );
void deleteLight( const int lightId );
void drawLights( renderView_t *refdef );
void InitWorld();
void ResetView( void );
void setLightShader( const int lightId, const idStr shaderName );
void setLightColor( const int lightId, const idVec3 &value );
void setLightRadius( const int lightId, const float radius );
void setLightAllowMove( const int lightId, const bool move );
void setObject( int Id );
void setCustomModel( const idStr modelName );
void setShowLights( bool _showLights );
void setLocalParm( int parmNum, float value );
void setGlobalParm( int parmNum, float value );
protected:
idRenderWorld *world;
idRenderModel *worldModel;
const idMaterial *material;
bool showLights;
idVec3 viewOrigin;
idAngles viewRotation;
float viewDistance;
renderEntity_t worldEntity;
qhandle_t modelDefHandle;
int objectId;
idStr customModelName;
float globalParms[MAX_GLOBAL_SHADER_PARMS];
typedef struct {
renderLight_t renderLight;
qhandle_t lightDefHandle;
idVec3 origin;
const idMaterial *shader;
float radius;
idVec3 color;
bool allowMove;
} lightInfo_t;
idList<lightInfo_t> viewLights;
};
// ==================================================================
// ==================================================================
class MaterialPreviewView : public CView, public MaterialView
{
DECLARE_DYNCREATE(MaterialPreviewView)
protected:
MaterialPreviewView();
virtual ~MaterialPreviewView();
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial);
void OnModelChange( int modelId );
void OnCustomModelChange( idStr modelName );
void OnShowLightsChange( bool showLights );
void OnLocalParmChange( int parmNum, float value );
void OnGlobalParmChange( int parmNum, float value );
void OnLightShaderChange( int lightId, idStr shaderName );
void OnLightRadiusChange( int lightId, float radius );
void OnLightColorChange( int lightId, idVec3 &color );
void OnLightAllowMoveChange( int lightId, bool move );
void OnAddLight( void );
void OnDeleteLight( int lightId );
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
idGLWidget renderWindow;
idGLDrawableView renderedView;
idStr currentMaterial;
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
};

View File

@@ -0,0 +1,248 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "MaterialPropTreeView.h"
#define PROP_TREE_VIEW "PropTreeView"
IMPLEMENT_DYNCREATE(MaterialPropTreeView, CPropTreeView)
BEGIN_MESSAGE_MAP(MaterialPropTreeView, CPropTreeView)
ON_NOTIFY( PTN_ITEMCHANGED, IDC_PROPERTYTREE, OnPropertyChangeNotification )
ON_NOTIFY( PTN_ITEMEXPANDING, IDC_PROPERTYTREE, OnPropertyItemExpanding )
END_MESSAGE_MAP()
/**
* Constructor for MaterialPropTreeView.
*/
MaterialPropTreeView::MaterialPropTreeView() {
registry.Init("Software\\id Software\\DOOM3\\Tools\\MaterialEditor\\PropertySettings");
internalChange = false;
}
/**
* Destructor for MaterialPropTreeView.
*/
MaterialPropTreeView::~MaterialPropTreeView() {
}
/**
* Initializes the list of properties based on the type (material, stage, special stage).
* @param listType The type of list (material, stage, special stage)
* @param stageNum The stage from which to get the attributes.
*/
void MaterialPropTreeView::SetPropertyListType(int listType, int stageNum) {
currentListType = listType;
currentStage = stageNum;
m_Tree.DeleteAllItems();
//idList<MaterialProp_t*>* propList = NULL;
MaterialDefList* propList = MaterialDefManager::GetMaterialDefs(currentListType);
currentPropDefs = propList;
if(!propList)
return;
CPropTreeItem* pCurrentGroup = NULL;
CPropTreeItem* pCurrentNode = NULL;
for(int i = 0; i < propList->Num(); i++) {
switch((*propList)[i]->type) {
case MaterialDef::MATERIAL_DEF_TYPE_GROUP:
{
pCurrentGroup = m_Tree.InsertItem(new CPropTreeItem());
pCurrentNode = pCurrentGroup;
if(!registry.GetBool(va("Expand%d%s", currentListType, (*propList)[i]->displayName.c_str())))
pCurrentGroup->Expand();
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_BOOL:
{
CPropTreeItemCheck* pCheck;
pCheck = (CPropTreeItemCheck*)m_Tree.InsertItem(new CPropTreeItemCheck(), pCurrentGroup);
pCheck->CreateCheckBox();
pCurrentNode = pCheck;
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_STRING:
{
//pCurrentNode = m_Tree.InsertItem(new CPropTreeItemEdit(), pCurrentGroup);
pCurrentNode = m_Tree.InsertItem(new CPropTreeItemFileEdit(), pCurrentGroup);
}
break;
}
if(pCurrentNode) {
(*propList)[i]->SetViewData(PROP_TREE_VIEW, pCurrentNode->GetCtrlID());
pCurrentNode->SetLabelText((*propList)[i]->displayName);
pCurrentNode->SetInfoText((*propList)[i]->displayInfo);
}
}
RefreshProperties();
}
/**
* Loads the property view settings from the registry.
*/
void MaterialPropTreeView::LoadSettings() {
registry.Load();
}
/**
* Saves the property view settings to the registry.
*/
void MaterialPropTreeView::SaveSettings() {
registry.Save();
}
/**
* Called when the material has changed but not applied.
* @param pMaterial The selected material.
*/
void MaterialPropTreeView::MV_OnMaterialChange(MaterialDoc* pMaterial) {
if(materialDocManager->GetCurrentMaterialDoc()) {
idStr currentName = materialDocManager->GetCurrentMaterialDoc()->name;
if(!internalChange && !pMaterial->name.Icmp(currentName)) {
RefreshProperties();
}
}
}
/**
* Updated the material when an attribute has been changed.
*/
void MaterialPropTreeView::OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult ) {
NMPROPTREE *nmProp = (NMPROPTREE *)nmhdr;
CPropTreeItem *item = nmProp->pItem;
internalChange = true;
MaterialDef* propItem = FindDefForTreeID(item->GetCtrlID());
if(propItem) {
MaterialDoc* materialDoc = materialDocManager->GetCurrentMaterialDoc();
switch(propItem->type) {
case MaterialDef::MATERIAL_DEF_TYPE_BOOL:
{
BOOL val = item->GetItemValue();
materialDoc->SetAttributeBool(currentStage, propItem->dictName, val ? true : false);
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_STRING:
{
idStr val = (LPCTSTR)item->GetItemValue();
materialDoc->SetAttribute(currentStage, propItem->dictName, val);
}
break;
}
}
internalChange = false;
*lresult = 0;
}
/**
* Changes the property setting of a group when is expanding.
*/
void MaterialPropTreeView::OnPropertyItemExpanding( NMHDR *nmhdr, LRESULT *lresult ) {
NMPROPTREE *nmProp = (NMPROPTREE *)nmhdr;
CPropTreeItem *item = nmProp->pItem;
//The item isn't toggled till after this returns so use the opposite of the current state.
registry.SetBool(va("Expand%d%s", currentListType, item->GetLabelText()), item->IsExpanded() ? true : false);
registry.Save();
*lresult = 0;
}
/**
* Returns the MeterialDef for a given property tree item.
* @param treeID The id of the tree item in question.
*/
MaterialDef* MaterialPropTreeView::FindDefForTreeID(UINT treeID) {
int c = currentPropDefs->Num();
for(int i = 0; i < c; i++) {
if((*currentPropDefs)[i]->GetViewData(PROP_TREE_VIEW) == treeID)
return (*currentPropDefs)[i];
}
return NULL;
}
/**
* Initializes the property tree with the data from the currently selected material.
*/
void MaterialPropTreeView::RefreshProperties() {
MaterialDefList* propList = MaterialDefManager::GetMaterialDefs(currentListType);
if(!propList)
return;
MaterialDoc* materialDoc = materialDocManager->GetCurrentMaterialDoc();
for(int i = 0; i < propList->Num(); i++) {
switch((*propList)[i]->type) {
case MaterialDef::MATERIAL_DEF_TYPE_BOOL:
{
bool val = materialDoc->GetAttributeBool(currentStage, (*propList)[i]->dictName);
CPropTreeItemCheck* item = (CPropTreeItemCheck*)m_Tree.FindItem((*propList)[i]->GetViewData(PROP_TREE_VIEW));
item->SetCheckState(val ? TRUE:FALSE);
}
break;
case MaterialDef::MATERIAL_DEF_TYPE_STRING:
{
idStr val = materialDoc->GetAttribute(currentStage, (*propList)[i]->dictName);
CPropTreeItemEdit* item = (CPropTreeItemEdit*)m_Tree.FindItem((*propList)[i]->GetViewData(PROP_TREE_VIEW));
item->SetItemValue((LPARAM)val.c_str());
}
break;
}
}
Invalidate();
}

View File

@@ -0,0 +1,74 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "../common/PropTree/PropTreeView.h"
#include "MaterialView.h"
#include "../common/registryoptions.h"
#include "MaterialDef.h"
/**
* View that displays material and stage properties and allows the user to edit the properties.
*/
class MaterialPropTreeView : public CPropTreeView, public MaterialView {
public:
virtual ~MaterialPropTreeView();
void SetPropertyListType(int listType, int stageNum = -1);
void LoadSettings();
void SaveSettings();
//Material Interface
virtual void MV_OnMaterialChange(MaterialDoc* pMaterial);
protected:
MaterialPropTreeView();
DECLARE_DYNCREATE(MaterialPropTreeView)
afx_msg void OnPropertyChangeNotification( NMHDR *nmhdr, LRESULT *lresult );
afx_msg void OnPropertyItemExpanding( NMHDR *nmhdr, LRESULT *lresult );
DECLARE_MESSAGE_MAP()
MaterialDef* FindDefForTreeID(UINT treeID);
void RefreshProperties();
protected:
MaterialDoc* currentMaterial;
int currentListType;
int currentStage;
MaterialDefList* currentPropDefs;
rvRegistryOptions registry;
bool internalChange;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include <afxcview.h>
#include "../common/PropTree/PropTreeView.h"
#include "MaterialEditor.h"
#include "MaterialView.h"
/**
* Structure used associate a material name with a tree item.
*/
typedef struct {
idStr materialName;
HTREEITEM treeItem;
} MaterialTreeItem_t;
/**
* A tree view of all the materials that have been defined.
*/
class MaterialTreeView : public CTreeView, public MaterialView {
public:
virtual ~MaterialTreeView();
void InitializeMaterialList(bool includeFile = true, const char* filename = NULL);
void BuildMaterialList(bool includeFile = true, const char* filename = NULL);
//Material Interface
virtual void MV_OnMaterialChange(MaterialDoc* pMaterial);
virtual void MV_OnMaterialApply(MaterialDoc* pMaterial);
virtual void MV_OnMaterialSaved(MaterialDoc* pMaterial);
virtual void MV_OnMaterialAdd(MaterialDoc* pMaterial);
virtual void MV_OnMaterialDelete(MaterialDoc* pMaterial);
virtual void MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName);
virtual void MV_OnFileReload(const char* filename);
bool CanCopy();
bool CanPaste();
bool CanCut();
bool CanDelete();
bool CanRename();
bool CanSaveFile();
idStr GetSaveFilename();
bool FindNextMaterial(MaterialSearchData_t* searchData);
HTREEITEM FindNextMaterial(HTREEITEM item, MaterialSearchData_t* searchData);
HTREEITEM GetNextSeachItem(HTREEITEM item, bool stayInFile);
void DeleteFolder(HTREEITEM item, bool addUndo = true);
HTREEITEM AddFolder(const char* name, HTREEITEM parent);
void RenameFolder(HTREEITEM item, const char* name);
protected:
MaterialTreeView();
DECLARE_DYNCREATE(MaterialTreeView)
/**
* List of tree item types
*/
enum {
TYPE_ROOT = 0,
TYPE_FOLDER,
TYPE_FILE,
TYPE_MATERIAL_FOLDER,
TYPE_MATERIAL
};
//Overrides
virtual BOOL PreTranslateMessage(MSG* pMsg);
//Window Messages
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//Menu Commands
afx_msg void OnApplyMaterial();
afx_msg void OnApplyFile();
afx_msg void OnApplyAll();
afx_msg void OnSaveMaterial();
afx_msg void OnSaveFile();
afx_msg void OnSaveAll();
afx_msg void OnRenameMaterial();
afx_msg void OnAddMaterial();
afx_msg void OnAddFolder();
afx_msg void OnDeleteMaterial();
afx_msg void OnReloadFile();
afx_msg void OnCut();
afx_msg void OnCopy();
afx_msg void OnPaste();
//Internal Messages
afx_msg LRESULT OnRenameFolderComplete(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnRenameMaterialComplete(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
//Utility methods
void RenameMaterial(HTREEITEM item, const char* originalName);
bool GetFileName(HTREEITEM item, idStr& out);
idStr GetMediaPath(HTREEITEM item, DWORD type);
void GetMaterialPaths(HTREEITEM item, idList<MaterialTreeItem_t>* list);
void AddStrList(const char *root, idStrList *list, bool includeFile);
void PopupMenu(CPoint* pt);
void SetItemImage(HTREEITEM item, bool mod, bool apply, bool children);
//Methods for working with the quicktree
void CleanLookupTrees(HTREEITEM item);
void BuildLookupTrees(HTREEITEM item);
idStr GetQuicktreePath(HTREEITEM item);
protected:
CImageList m_image;
bool treeWithFile;
//Hashtables for quick lookups
idHashTable<HTREEITEM> quickTree;
idHashTable<HTREEITEM> materialToTree;
idHashTable<HTREEITEM> fileToTree;
//Member variables for renaming folders
HTREEITEM renamedFolder;
idList<MaterialTreeItem_t> affectedMaterials;
CImageList* dragImage;
bool bDragging;
CPoint dropPoint;
HTREEITEM dragItem;
//Hover Expand
HTREEITEM hoverItem;
DWORD hoverStartTime;
bool internalChange;
};

View File

@@ -0,0 +1,32 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "materialview.h"

View File

@@ -0,0 +1,148 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include "MaterialDocManager.h"
/**
* MaterialView Interface. Interface to be implemented by classes that want
* notifications of material changes. Classes that implement this interface
* must register themself with the MaterialDocManager class with the
* RegisterView method.
*/
class MaterialView {
public:
/**
* Constructor.
*/
MaterialView(void) { materialDocManager = NULL; };
/**
* Destructor.
*/
virtual ~MaterialView(void) {};
//////////////////////////////////////////////////////////////////////////
//Public Interface to be implemented by subclasses
//////////////////////////////////////////////////////////////////////////
/**
* Sets the material document manager for this view instance.
* @param docManager The material document manager for this view instance.
*/
virtual void SetMaterialDocManager(MaterialDocManager* docManager) { materialDocManager = docManager; };
/**
* Called when the selected material has changed.
* @param pMaterial The newly selected material.
*/
virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) {};
/**
* Called when the material has changed but not applied.
* @param pMaterial The selected material.
*/
virtual void MV_OnMaterialChange(MaterialDoc* pMaterial) {};
/**
* Called when the material changes have been applied.
* @param pMaterial The selected material.
*/
virtual void MV_OnMaterialApply(MaterialDoc* pMaterial) {};
/**
* Called when the material changes have been saved.
* @param pMaterial The saved material.
*/
virtual void MV_OnMaterialSaved(MaterialDoc* pMaterial) {};
/**
* Called when a material file has been saved
* @param filename path of the file that was saved.
*/
virtual void MV_OnMaterialSaveFile(const char* filename) {};
/**
* Called when a material is added
* @param pMaterial The material that was added.
*/
virtual void MV_OnMaterialAdd(MaterialDoc* pMaterial) {};
/**
* Called when a material is deleted
* @param pMaterial The material that was deleted.
*/
virtual void MV_OnMaterialDelete(MaterialDoc* pMaterial) {};
/**
* Called when a stage is added
* @param pMaterial The material that was affected.
* @param stageNum The index of the stage that was added
*/
virtual void MV_OnMaterialStageAdd(MaterialDoc* pMaterial, int stageNum) {};
/**
* Called when a stage is deleted
* @param pMaterial The material that was affected.
* @param stageNum The index of the stage that was deleted
*/
virtual void MV_OnMaterialStageDelete(MaterialDoc* pMaterial, int stageNum) {};
/**
* Called when a stage is moved
* @param pMaterial The material that was deleted.
* @param from The from index
* @param to The to index
*/
virtual void MV_OnMaterialStageMove(MaterialDoc* pMaterial, int from, int to) {};
/**
* Called when an attribute is changed
* @param pMaterial The material that was deleted.
* @param stage The stage that contains the change.
* @param attribName The attribute that has changed.
*/
virtual void MV_OnMaterialAttributeChanged(MaterialDoc* pMaterial, int stage, const char* attribName) {};
/**
* Called when the material name has changed
* @param pMaterial The material that was deleted.
* @param oldName The old name of the material.
*/
virtual void MV_OnMaterialNameChanged(MaterialDoc* pMaterial, const char* oldName) {};
/**
* Called when a file has been reloaded
* @param filename The file that was reloaded.
*/
virtual void MV_OnFileReload(const char* filename) {};
protected:
MaterialDocManager* materialDocManager;
};

View File

@@ -0,0 +1,828 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "StageView.h"
IMPLEMENT_DYNCREATE(StageView, ToggleListView)
BEGIN_MESSAGE_MAP(StageView, ToggleListView)
ON_WM_CREATE()
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnLvnItemchanged)
ON_NOTIFY_REFLECT(LVN_DELETEALLITEMS, OnLvnDeleteallitems)
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnLvnBegindrag)
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_NOTIFY_REFLECT(NM_RCLICK, OnNMRclick)
ON_COMMAND(ID_STAGEPOPUP_RENAMESTAGE, OnRenameStage)
ON_COMMAND(ID_STAGEPOPUP_DELETESTAGE, OnDeleteStage)
ON_COMMAND(ID_STAGEPOPUP_DELETEALLSTAGES, OnDeleteAllStages)
ON_COMMAND(ID_STAGEPOPUP_ADDSTAGE, OnAddStage)
ON_COMMAND(ID_STAGEPOPUP_ADDBUMPMAP, OnAddBumpmapStage)
ON_COMMAND(ID_STAGEPOPUP_ADDDIFFUSEMAP, OnAddDiffuseStage)
ON_COMMAND(ID_STAGEPOPUP_ADDSPECULAR, OnAddSpecualarStage)
ON_COMMAND(ID_STAGEPOPUP_COPY, OnCopy)
ON_COMMAND(ID_STAGEPOPUP_PASTE, OnPaste)
ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnLvnBeginlabeledit)
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnLvnEndlabeledit)
ON_WM_CHAR()
END_MESSAGE_MAP()
/**
* Constructor for StageView.
*/
StageView::StageView() {
currentMaterial = NULL;
bDragging = false;
internalChange = false;
}
/**
* Destructor for StageView.
*/
StageView::~StageView() {
}
/**
* Called when the selected material has changed.
* @param pMaterial The newly selected material.
*/
void StageView::MV_OnMaterialSelectionChange(MaterialDoc* pMaterial) {
currentMaterial = pMaterial;
RefreshStageList();
}
/**
* Called when the material changes have been saved.
* @param pMaterial The saved material.
*/
void StageView::MV_OnMaterialSaved(MaterialDoc* pMaterial) {
CListCtrl& list = GetListCtrl();
//Saving a material reenables all of the stages
if(pMaterial == currentMaterial) {
for(int i = 1; i < list.GetItemCount(); i++) {
SetToggleState(i, ToggleListView::TOGGLE_STATE_ON);
}
}
}
/**
* Called when a stage is added
* @param pMaterial The material that was affected.
* @param stageNum The index of the stage that was added
*/
void StageView::MV_OnMaterialStageAdd(MaterialDoc* pMaterial, int stageNum) {
CListCtrl& list = GetListCtrl();
idStr name = pMaterial->GetAttribute(stageNum, "name");
int index = list.InsertItem(stageNum+1, name.c_str());
SetToggleState(index, ToggleListView::TOGGLE_STATE_ON);
}
/**
* Called when a stage is deleted
* @param pMaterial The material that was affected.
* @param stageNum The index of the stage that was deleted
*/
void StageView::MV_OnMaterialStageDelete(MaterialDoc* pMaterial, int stageNum) {
CListCtrl& list = GetListCtrl();
list.DeleteItem(stageNum+1);
}
/**
* Called when a stage is moved
* @param pMaterial The material that was deleted.
* @param from The from index
* @param to The to index
*/
void StageView::MV_OnMaterialStageMove(MaterialDoc* pMaterial, int from, int to) {
if(!internalChange) {
from++;
to++;
CListCtrl& list = GetListCtrl();
char szLabel[256];
LV_ITEM lvi;
ZeroMemory(&lvi, sizeof(LV_ITEM));
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED;
lvi.pszText = szLabel;
lvi.iItem = from;
lvi.cchTextMax = 255;
list.GetItem(&lvi);
//Delete the original item
list.DeleteItem(from);
//Insert the item
lvi.iItem = to;
list.InsertItem(&lvi);
int type = -1;
int stageType = currentMaterial->GetAttributeInt(to-1, "stagetype");
switch(stageType) {
case MaterialDoc::STAGE_TYPE_NORMAL:
type = MaterialDefManager::MATERIAL_DEF_STAGE;
break;
case MaterialDoc::STAGE_TYPE_SPECIALMAP:
type = MaterialDefManager::MATERIAL_DEF_SPECIAL_STAGE;
break;
}
m_propView->SetPropertyListType(type, to-1);
Invalidate();
}
}
/**
* Called when an attribute is changed
* @param pMaterial The material that was deleted.
* @param stage The stage that contains the change.
* @param attribName The attribute that has changed.
*/
void StageView::MV_OnMaterialAttributeChanged(MaterialDoc* pMaterial, int stage, const char* attribName) {
//Refresh this stage list if a material name has changed
if(!internalChange && currentMaterial == pMaterial && stage >= 0 && attribName && !strcmp(attribName, "name") ) {
CListCtrl& list = GetListCtrl();
list.SetItemText(stage+1, 0, currentMaterial->GetAttribute(stage, attribName));
}
}
/**
* Returns true if the current state of the stage view will allow a copy operation
*/
bool StageView::CanCopy() {
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos)
nItem = list.GetNextSelectedItem(pos);
if(nItem > 0) {
return true;
} else {
return false;
}
}
/**
* Returns true if the current state of the stage view will allow a paste operation
*/
bool StageView::CanPaste() {
return materialDocManager->IsCopyStage();
}
/**
* Cut is not supported for stages.
*/
bool StageView::CanCut() {
//No cut for stages
return false;
}
/**
* Returns true if the current state of the stage view will allow a delete operation
*/
bool StageView::CanDelete() {
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos) {
nItem = list.GetNextSelectedItem(pos);
}
if(nItem > 0)
return true;
return false;
}
/**
* Returns true if the current state of the stage view will allow a rename operation
*/
bool StageView::CanRename() {
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos) {
nItem = list.GetNextSelectedItem(pos);
}
if(nItem > 0) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(nItem > 0 && material->GetAttributeInt(nItem-1, "stagetype") == MaterialDoc::STAGE_TYPE_NORMAL) {
return true;
}
}
return false;
}
/**
* Rebuilds the list of stages based on the currently selected material
*/
void StageView::RefreshStageList() {
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int selectedItem = -1;
if(pos)
selectedItem = list.GetNextSelectedItem(pos);
list.DeleteAllItems();
if(currentMaterial) {
//Always add the material item for the main material properties
list.InsertItem(0, "Material");
SetToggleState(0, ToggleListView::TOGGLE_STATE_DISABLED);
//Get the stage info
int stageCount = currentMaterial->GetStageCount();
for(int i = 0; i < stageCount; i++) {
const char* name = currentMaterial->GetAttribute(i, "name");
int itemNum = list.InsertItem(list.GetItemCount(), name);
if(currentMaterial->IsStageEnabled(i)) {
SetToggleState(itemNum, ToggleListView::TOGGLE_STATE_ON);
} else {
SetToggleState(itemNum, ToggleListView::TOGGLE_STATE_OFF);
}
}
if(selectedItem < 0) {
//Select the material
list.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
} else {
list.SetItemState(selectedItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
}
}
/**
* Called by the MFC framework when the view is being created.
*/
int StageView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (ToggleListView::OnCreate(lpCreateStruct) == -1)
return -1;
SetToggleIcons(MAKEINTRESOURCE(IDI_ME_DISABLED_ICON), MAKEINTRESOURCE(IDI_ME_ON_ICON), MAKEINTRESOURCE(IDI_ME_OFF_ICON));
return 0;
}
/**
* Called when the user changes the selection in the list box. This method will notify the
* property view of the change so that it can display the appropriate properties.
*/
void StageView::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult) {
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
if(!bDragging) {
//The state has changed and changed to selected
if(pNMLV->uChanged && LVIF_STATE && pNMLV->uNewState & LVIS_SELECTED) {
int type = -1;
if(pNMLV->iItem >= 0) {
if(pNMLV->iItem == 0)
type = MaterialDefManager::MATERIAL_DEF_MATERIAL;
else {
int stageType = currentMaterial->GetAttributeInt(pNMLV->iItem-1, "stagetype");
switch(stageType) {
case MaterialDoc::STAGE_TYPE_NORMAL:
type = MaterialDefManager::MATERIAL_DEF_STAGE;
break;
case MaterialDoc::STAGE_TYPE_SPECIALMAP:
type = MaterialDefManager::MATERIAL_DEF_SPECIAL_STAGE;
break;
}
}
}
m_propView->SetPropertyListType(type, pNMLV->iItem-1);
}
if(pNMLV->uChanged && LVIF_STATE && pNMLV->uOldState & LVIS_SELECTED && !(pNMLV->uNewState & LVIS_SELECTED)) {
//This item was deselected.
//If there is no item selected then clear the prop list
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
if(!pos)
m_propView->SetPropertyListType(-1);
}
}
*pResult = 0;
}
/**
* Notifies the property view that all stages have been removed.
*/
void StageView::OnLvnDeleteallitems(NMHDR *pNMHDR, LRESULT *pResult) {
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
//The list has been cleared so clear the prop view
m_propView->SetPropertyListType(-1);
*pResult = 0;
}
/**
* Starts the stage drag operation.
*/
void StageView::OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult) {
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
CListCtrl& list = GetListCtrl();
//Start a drag if the item isn't the material
if(pNMLV->iItem > 0) {
dragIndex = pNMLV->iItem;
//Trun off ownerdrawn to create the drag image correctly
list.ModifyStyle(LVS_OWNERDRAWFIXED, 0);
//Create the drag image
POINT pt;
pt.x = 8;
pt.y = 8;
dragImage = list.CreateDragImage(dragIndex, &pt);
dragImage->BeginDrag(0, CPoint (8, 8));
dragImage->DragEnter(GetDesktopWindow(), pNMLV->ptAction);
//Turn the owner draw back on
list.ModifyStyle(0, LVS_OWNERDRAWFIXED);
//Drag is in progress
bDragging = true;
dropIndex = -1;
dropWnd = &list;
//Capture the messages
SetCapture();
}
*pResult = 0;
}
/**
* Finishes a stage drag operation of the user was dragging a stage.
*/
void StageView::OnLButtonUp(UINT nFlags, CPoint point) {
if( bDragging ) {
//Release mouse capture
ReleaseCapture();
//Delete the drag image
dragImage->DragLeave(GetDesktopWindow());
dragImage->EndDrag();
//Where did we drop
CPoint pt(point);
ClientToScreen(&pt);
dropWnd = WindowFromPoint(pt);
if( dropWnd->IsKindOf(RUNTIME_CLASS(StageView)) )
DropItemOnList();
bDragging = false;
}
ToggleListView::OnLButtonUp(nFlags, point);
}
/**
* Handles drawing the drag image when a user is draging a stage.
*/
void StageView::OnMouseMove(UINT nFlags, CPoint point) {
if( bDragging ) {
dropPoint = point;
ClientToScreen(&dropPoint);
//Move the drag image
dragImage->DragMove(dropPoint);
dragImage->DragShowNolock(FALSE);
dropWnd = WindowFromPoint(dropPoint);
dropWnd->ScreenToClient(&dropPoint);
dragImage->DragShowNolock(TRUE);
}
ToggleListView::OnMouseMove(nFlags, point);
}
/**
* Displays the popup menu when the user performs a right mouse click.
*/
void StageView::OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult) {
if(materialDocManager->GetCurrentMaterialDoc()) {
CListCtrl& list = GetListCtrl();
DWORD dwPos = GetMessagePos();
CPoint pt( LOWORD( dwPos ), HIWORD ( dwPos ) );
CPoint spt = pt;
list.ScreenToClient( &spt );
PopupMenu(&spt);
}
*pResult = 0;
}
/**
* Begins a label edit when the user selects the rename menu option.
*/
void StageView::OnRenameStage() {
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos) {
nItem = list.GetNextSelectedItem(pos);
list.EditLabel(nItem);
}
}
/**
* Deletes the selected stage when the user selects the delete menu option.
*/
void StageView::OnDeleteStage() {
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos) {
nItem = list.GetNextSelectedItem(pos);
if(nItem > 0) {
int result = MessageBox("Are you sure you want to delete this stage?", "Delete?", MB_ICONQUESTION | MB_YESNO);
if(result == IDYES) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
material->RemoveStage(nItem-1);
}
}
}
}
/**
* Conforms the user wants to delete all stages and then performs the operation.
*/
void StageView::OnDeleteAllStages() {
int result = MessageBox("Are you sure you want to delete all stages?", "Delete?", MB_ICONQUESTION | MB_YESNO);
if(result == IDYES) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
material->ClearStages();
}
}
/**
* Adds a new stage when the user selects the menu option.
*/
void StageView::OnAddStage() {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
idStr name = va("Stage %d", material->GetStageCount()+1);
material->AddStage(MaterialDoc::STAGE_TYPE_NORMAL, name.c_str());
}
/**
* Adds a new bumpmap stage when the user selects the menu option.
*/
void StageView::OnAddBumpmapStage() {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
material->AddStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "bumpmap");
}
/**
* Adds a new diffusemap stage when the user selects the menu option.
*/
void StageView::OnAddDiffuseStage() {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
material->AddStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "diffusemap");
}
/**
* Adds a new specularmap stage when the user selects the menu option.
*/
void StageView::OnAddSpecualarStage() {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
material->AddStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "specularmap");
}
/**
* Performs a copy operation when the user selects the menu option.
*/
void StageView::OnCopy() {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
CListCtrl& list = GetListCtrl();
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos)
nItem = list.GetNextSelectedItem(pos);
if(nItem > 0) {
materialDocManager->CopyStage(material, nItem-1);
}
}
/**
* Performs a paste operation when the user selects the menu option.
*/
void StageView::OnPaste() {
if(materialDocManager->IsCopyStage()) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
int type;
idStr name;
materialDocManager->GetCopyStageInfo(type, name);
int existingIndex = material->FindStage(type, name);
if(type != MaterialDoc::STAGE_TYPE_SPECIALMAP || existingIndex == -1) {
materialDocManager->PasteStage(material);
} else {
if(MessageBox(va("Do you want to replace '%s' stage?", name.c_str()), "Replace?", MB_ICONQUESTION | MB_YESNO) == IDYES) {
material->RemoveStage(existingIndex);
materialDocManager->PasteStage(material);
}
}
}
}
/**
* Determines is a label edit can be performed on the selected stage.
*/
void StageView::OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult) {
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
//if this is a special stage then don't allow edit
int index = pDispInfo->item.iItem;
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(index <= 0 || material->GetAttributeInt(index-1, "stagetype") != MaterialDoc::STAGE_TYPE_NORMAL)
{
*pResult = 1;
return;
}
//ToDo: Can we move the edit box
/*HWND edit = ListView_GetEditControl(m_hWnd);
CWnd* editWnd = CWnd::FromHandle(edit);
CRect rect;
editWnd->GetWindowRect(rect);
rect.left += 22;
rect.right += 22;
editWnd->MoveWindow(rect);*/
*pResult = 0;
}
/**
* Performs the stage name change after the label edit is done.
*/
void StageView::OnLvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult) {
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
if(pDispInfo->item.pszText) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
internalChange = true;
material->SetAttribute(pDispInfo->item.iItem-1, "name", pDispInfo->item.pszText);
internalChange = false;
*pResult = 1;
} else {
*pResult = 0;
}
}
/**
* Handles keyboard shortcuts for copy and paste operations.
*/
void StageView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
if(nChar == 3 && GetKeyState(VK_CONTROL)) {
OnCopy();
}
if(nChar == 22 && GetKeyState(VK_CONTROL)) {
OnPaste();
}
ToggleListView::OnChar(nChar, nRepCnt, nFlags);
}
/**
* Handles keyboard shortcut for the delete operations.
*/
BOOL StageView::PreTranslateMessage(MSG* pMsg) {
CListCtrl& list = GetListCtrl();
if (pMsg->hwnd == list.GetSafeHwnd()) {
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE) {
OnDeleteStage();
return TRUE;
}
}
return FALSE;
}
/**
* Sets window styles before the window is created.
*/
BOOL StageView::PreCreateWindow(CREATESTRUCT& cs) {
cs.style &= ~LVS_TYPEMASK;
cs.style |= LVS_SINGLESEL | LVS_EDITLABELS;
return ToggleListView::PreCreateWindow(cs);
}
/**
* Called by the ToggleListView when the toggle state has changed.
*/
void StageView::OnStateChanged(int index, int toggleState) {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(material && index > 0) {
if (toggleState == ToggleListView::TOGGLE_STATE_ON) {
material->EnableStage(index-1, true);
} else if (toggleState == ToggleListView::TOGGLE_STATE_OFF) {
material->EnableStage(index-1, false);
}
}
}
/**
* Dispalys the popup menu with the appropriate menu items enabled.
*/
void StageView::PopupMenu(CPoint* pt) {
//Determine the type of object clicked on
CListCtrl& list = GetListCtrl();
ClientToScreen (pt);
CMenu FloatingMenu;
VERIFY(FloatingMenu.LoadMenu(IDR_ME_STAGELIST_POPUP));
CMenu* pPopupMenu = FloatingMenu.GetSubMenu (0);
ASSERT(pPopupMenu != NULL);
POSITION pos = list.GetFirstSelectedItemPosition();
int nItem = -1;
if(pos)
nItem = list.GetNextSelectedItem(pos);
if(nItem <= 0) {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_RENAMESTAGE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_DELETESTAGE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
} else {
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(material->GetAttributeInt(nItem-1, "stagetype") != MaterialDoc::STAGE_TYPE_NORMAL) {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_RENAMESTAGE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
}
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
if(material->FindStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "bumpmap") >= 0) {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_ADDBUMPMAP, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
if(material->FindStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "diffusemap") >= 0) {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_ADDDIFFUSEMAP, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
if(material->FindStage(MaterialDoc::STAGE_TYPE_SPECIALMAP, "specularmap") >= 0) {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_ADDSPECULAR, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
if(materialDocManager->IsCopyStage()) {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_PASTE, MF_BYCOMMAND | MF_ENABLED);
} else {
pPopupMenu->EnableMenuItem(ID_STAGEPOPUP_PASTE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt->x, pt->y, &list);
}
/**
* Performs the stage move when the user has dragged and dropped a stage.
*/
void StageView::DropItemOnList() {
CListCtrl& list = GetListCtrl();
int toStage;
//Get and adjust the drop index based on the direction of the move
dropIndex = list.HitTest(dropPoint);
if(dropIndex < 0) dropIndex = list.GetItemCount()-1;
//Ignore the drop if the index is the same or they are droping on the material
if(dropIndex == dragIndex || dropIndex == 0)
return;
//Move the stage data
MaterialDoc* material = materialDocManager->GetCurrentMaterialDoc();
internalChange = true;
toStage = dropIndex-1;
material->MoveStage(dragIndex-1, dropIndex-1);
internalChange = false;
if(dragIndex < dropIndex) {
dropIndex++;
}
//Get the item
char szLabel[256];
LV_ITEM lvi;
ZeroMemory(&lvi, sizeof(LV_ITEM));
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED;
lvi.pszText = szLabel;
lvi.iItem = dragIndex;
lvi.cchTextMax = 255;
list.GetItem(&lvi);
//Insert the item
lvi.iItem = dropIndex;
list.InsertItem(&lvi);
//Adjust the drag index if the move was up in the list
if(dragIndex > dropIndex) {
dragIndex++;
}
//Delete the original item
list.DeleteItem(dragIndex);
int type = -1;
int stageType = currentMaterial->GetAttributeInt(toStage, "stagetype");
switch(stageType) {
case MaterialDoc::STAGE_TYPE_NORMAL:
type = MaterialDefManager::MATERIAL_DEF_STAGE;
break;
case MaterialDoc::STAGE_TYPE_SPECIALMAP:
type = MaterialDefManager::MATERIAL_DEF_SPECIAL_STAGE;
break;
}
m_propView->SetPropertyListType(type, toStage);
}

View File

@@ -0,0 +1,132 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include <afxcview.h>
#include <afxole.h>
#include "MaterialEditor.h"
#include "ToggleListView.h"
#include "MaterialView.h"
#include "MaterialPropTreeView.h"
/**
* View that handles managing the material stages.
*/
class StageView : public ToggleListView, public MaterialView
{
public:
virtual ~StageView();
/**
* Defines the type of stages
*/
enum {
STAGE_TYPE_MATERIAL,
STAGE_TYPE_STAGE,
STAGE_TYPE_SPECIAL_MAP_STAGE
};
//Associates a property view with this stage view
void SetMaterialPropertyView(MaterialPropTreeView* propView) { m_propView = propView; };
//MaterialView Interface
virtual void MV_OnMaterialSelectionChange(MaterialDoc* pMaterial);
virtual void MV_OnMaterialStageAdd(MaterialDoc* pMaterial, int stageNum);
virtual void MV_OnMaterialStageDelete(MaterialDoc* pMaterial, int stageNum);
virtual void MV_OnMaterialStageMove(MaterialDoc* pMaterial, int from, int to);
virtual void MV_OnMaterialAttributeChanged(MaterialDoc* pMaterial, int stage, const char* attribName);
virtual void MV_OnMaterialSaved(MaterialDoc* pMaterial);
//Edit Operation Tests
bool CanCopy();
bool CanPaste();
bool CanCut();
bool CanDelete();
bool CanRename();
//Refresh the stage list
void RefreshStageList();
protected:
StageView();
DECLARE_DYNCREATE(StageView)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnLvnDeleteallitems(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnRenameStage();
afx_msg void OnDeleteStage();
afx_msg void OnDeleteAllStages();
afx_msg void OnAddStage();
afx_msg void OnAddBumpmapStage();
afx_msg void OnAddDiffuseStage();
afx_msg void OnAddSpecualarStage();
afx_msg void OnCopy();
afx_msg void OnPaste();
afx_msg void OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnLvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
DECLARE_MESSAGE_MAP()
//Overrides
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//Toggle List View Interface
virtual void OnStateChanged(int index, int toggleState);
void PopupMenu(CPoint* pt);
void DropItemOnList();
protected:
MaterialPropTreeView* m_propView;
MaterialDoc* currentMaterial;
//Manual handing of the row dragging
CImageList* dragImage;
bool bDragging;
int dragIndex;
int dropIndex;
CWnd* dropWnd;
CPoint dropPoint;
bool internalChange;
};

View File

@@ -0,0 +1,306 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "ToggleListView.h"
#define TOGGLELIST_ITEMHEIGHT 22
#define TEXT_OFFSET 6
IMPLEMENT_DYNCREATE(ToggleListView, CListView)
BEGIN_MESSAGE_MAP(ToggleListView, CListView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_MEASUREITEM_REFLECT()
ON_NOTIFY_REFLECT(NM_CLICK, OnNMClick)
END_MESSAGE_MAP()
/**
* Protected constructor used by dynamic creation.
*/
ToggleListView::ToggleListView() {
onIcon = NULL;
offIcon = NULL;
disabledIcon = NULL;
}
/**
* Destructor.
*/
ToggleListView::~ToggleListView() {
}
/**
* Sets the tree icons to dispay for each of the three states. Sets the
* icons to display for each of the three states. The values passed in
* are the resource name that can be generated using MAKEINTRESOUCE. If
* the value passed in is NULL then an icon will not be drawn for that
* state.
* @param disabled The icon to draw when the state is TOGGLE_STATE_DISABLED.
* @param on The icon to draw when the state is TOGGLE_STATE_ON.
* @param off The icon to draw when the state is TOGGLE_STATE_OFF.
*/
void ToggleListView::SetToggleIcons(LPCSTR disabled, LPCSTR on, LPCSTR off) {
if(on) {
onIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), on, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
} else {
onIcon = NULL;
}
if(off) {
offIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), off, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
} else {
offIcon = NULL;
}
if(disabled) {
disabledIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), disabled, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
} else {
disabledIcon = NULL;
}
}
/**
* Sets the state of an item in the list.
* @param index Index of the item whose state should be changed.
* @param toggleState The state to set
* @param notify Determines if the notification method OnStateChanged should
* be called. OnStateChanged will also not be called if the state has not changed.
*/
void ToggleListView::SetToggleState(int index, int toggleState, bool notify) {
CListCtrl& list = GetListCtrl();
assert(index >= 0 && index < list.GetItemCount());
int oldState = GetToggleState(index);
list.SetItemData(index, toggleState);
if(notify && oldState != toggleState)
OnStateChanged(index, toggleState);
}
/**
* Gets the state of an item in the list
* @param index Index of the item of which to retreive the state.
*/
int ToggleListView::GetToggleState(int index) {
CListCtrl& list = GetListCtrl();
assert(index >= 0 && index < list.GetItemCount());
DWORD data = list.GetItemData(index);
return data;
}
/**
* Called as the window is being created and initializes icons and window styles
*/
int ToggleListView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
CListCtrl& list = GetListCtrl();
list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
//Turn off the horizontal scroll bar
//Todo: Figure out why the damn scroll bar pops up
list.ModifyStyle(WS_HSCROLL, 0L);
//Insert the one column
LVCOLUMN col;
col.mask = 0;
list.InsertColumn(0, &col);
SetToggleIcons();
return 0;
}
/**
* Called when the window is being resized.
*/
void ToggleListView::OnSize(UINT nType, int cx, int cy) {
CListView::OnSize(nType, cx, cy);
CListCtrl& list = GetListCtrl();
list.SetColumnWidth(0, cx-1);
}
/**
* Returns the size of each item in the toggle list.
*/
void ToggleListView::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
lpMeasureItemStruct->itemHeight = TOGGLELIST_ITEMHEIGHT;
}
/**
* Toggles the state of an item when the user clicks in the window.
*/
void ToggleListView::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) {
CListCtrl& list = GetListCtrl();
DWORD dwpos = GetMessagePos();
LVHITTESTINFO info;
info.pt.x = LOWORD(dwpos);
info.pt.y = HIWORD(dwpos);
::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &info.pt, 1);
int index = list.HitTest(&info);
if ( index != -1 ) {
int toggleState = GetToggleState(index);
if(toggleState != TOGGLE_STATE_DISABLED) {
RECT rItem;
list.GetItemRect(index, &rItem, LVIR_BOUNDS);
if ( info.pt.x < TOGGLELIST_ITEMHEIGHT ) {
if(toggleState == TOGGLE_STATE_ON) {
SetToggleState(index, TOGGLE_STATE_OFF, true);
} else {
SetToggleState(index, TOGGLE_STATE_ON, true);
}
}
}
}
*pResult = 0;
}
/**
* Sets some window styles before the window is created.
*/
BOOL ToggleListView::PreCreateWindow(CREATESTRUCT& cs) {
//Set the required style for the toggle view
cs.style &= ~LVS_TYPEMASK;
cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS;
return CListView::PreCreateWindow(cs);
}
/**
* Responsible for drawing each list item.
*/
void ToggleListView::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
CListCtrl& ListCtrl=GetListCtrl();
int nItem = lpDrawItemStruct->itemID;
// get item data
LV_ITEM lvi;
_TCHAR szBuff[MAX_PATH];
memset(&lvi, 0, sizeof(LV_ITEM));
lvi.mask = LVIF_TEXT;
lvi.iItem = nItem;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
ListCtrl.GetItem(&lvi);
RECT rDraw;
CopyRect ( &rDraw, &lpDrawItemStruct->rcItem );
rDraw.right = rDraw.left + TOGGLELIST_ITEMHEIGHT;
rDraw.top ++;
rDraw.right ++;
FrameRect ( lpDrawItemStruct->hDC, &rDraw, (HBRUSH)GetStockObject ( BLACK_BRUSH ) );
rDraw.right --;
FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DFACE ) );
Draw3dRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DHILIGHT ), GetSysColorBrush ( COLOR_3DSHADOW ) );
InflateRect ( &rDraw, -3, -3 );
Draw3dRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DSHADOW ), GetSysColorBrush ( COLOR_3DHILIGHT ) );
switch(GetToggleState(lvi.iItem)) {
case TOGGLE_STATE_DISABLED:
if(disabledIcon) {
DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, disabledIcon, 16, 16,0, NULL, DI_NORMAL );
}
break;
case TOGGLE_STATE_ON:
if(onIcon) {
DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, onIcon, 16, 16,0, NULL, DI_NORMAL );
}
break;
case TOGGLE_STATE_OFF:
if(offIcon) {
DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, offIcon, 16, 16,0, NULL, DI_NORMAL );
}
break;
};
CopyRect ( &rDraw, &lpDrawItemStruct->rcItem );
rDraw.left += TOGGLELIST_ITEMHEIGHT;
rDraw.left += 1;
if ( lpDrawItemStruct->itemState & ODS_SELECTED ) {
FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_HIGHLIGHT ) );
} else {
FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_WINDOW ) );
}
rDraw.left += TEXT_OFFSET;
int colorIndex = ( (lpDrawItemStruct->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT );
SetTextColor ( lpDrawItemStruct->hDC, GetSysColor ( colorIndex ) );
DrawText ( lpDrawItemStruct->hDC, szBuff, strlen(szBuff), &rDraw, DT_LEFT|DT_VCENTER|DT_SINGLELINE );
}
/**
* Draws a 3d rectangle using the given brushes this code was taken from the gui editor
*/
void ToggleListView::Draw3dRect (HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight) {
RECT rOut;
SetRect ( &rOut, rect->left, rect->top, rect->right - 1, rect->top + 1 );
FillRect ( hDC,&rOut, topLeft );
SetRect ( &rOut, rect->left, rect->top, rect->left + 1, rect->bottom );
FillRect( hDC,&rOut, topLeft );
SetRect ( &rOut, rect->right, rect->top, rect->right -1, rect->bottom );
FillRect( hDC,&rOut, bottomRight );
SetRect ( &rOut, rect->left, rect->bottom, rect->right, rect->bottom - 1 );
FillRect( hDC,&rOut, bottomRight );
}

View File

@@ -0,0 +1,87 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma once
#include <afxcview.h>
/**
* A simple list view that supports a toggle button. ToggleListView is a simple extension
* to the CListView class that support a toggle button. It is limited to a single column
* and always uses full row select. The toggle state is stored in the data for each item
* so users of this class should not attempt to use the data field for storage. lparam can
* be used instead.
*/
class ToggleListView : public CListView {
public:
/**
* Enumeration that defines the possible states of the toggle button.
*/
enum {
TOGGLE_STATE_DISABLED = 0,
TOGGLE_STATE_ON,
TOGGLE_STATE_OFF
};
public:
void SetToggleIcons(LPCSTR disabled = NULL, LPCSTR on = NULL, LPCSTR off = NULL);
void SetToggleState(int index, int toggleState, bool notify = false);
int GetToggleState(int index);
//Windows messages
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
afx_msg void OnNMClick(NMHDR *pNMHDR, LRESULT *pResult);
DECLARE_MESSAGE_MAP()
protected:
ToggleListView();
virtual ~ToggleListView();
DECLARE_DYNCREATE(ToggleListView)
//Overrides
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//Virtual Event Methods for sub-classes
virtual void OnStateChanged(int index, int toggleState) {};
void Draw3dRect(HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight);
protected:
HICON onIcon;
HICON offIcon;
HICON disabledIcon;
};