Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Code/wwui/Debug/mapctrl.sbr Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Code/wwui/Debug/tabctrl.sbr Normal file

Binary file not shown.

Binary file not shown.

BIN
Code/wwui/Debug/tooltip.sbr Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Code/wwui/Debug/wwui.pch Normal file

Binary file not shown.

Binary file not shown.

546
Code/wwui/IMECandidate.cpp Normal file
View File

@@ -0,0 +1,546 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/******************************************************************************
*
* FILE
* $Archive: /Commando/Code/wwui/IMECandidate.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 1/12/02 9:43p $
*
******************************************************************************/
#include "IMECandidate.h"
#include "WWDebug.h"
namespace IME {
/******************************************************************************
*
* NAME
* IMECandidate::IMECandidate
*
* DESCRIPTION
* Default constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
IMECandidate::IMECandidate() :
mCandidateSize(0),
mCandidates(NULL)
{
Close();
}
/******************************************************************************
*
* NAME
* IMECandidate::~IMECandidate
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
IMECandidate::~IMECandidate()
{
if (mCandidates)
{
delete[] mCandidates;
}
}
/******************************************************************************
*
* NAME
* IMECandidate::Open
*
* DESCRIPTION
*
* INPUTS
* Index - Candidate Index ID
* HWND - Window IME is associated with
* CodePage - Code page for current input mode.
* Unicode - If true, process IME as unicode; if false, process as MBCS
* StartFrom1 - If true, candidates should be displayed starting from 1
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidate::Open(int id, HWND hwnd, UINT codepage, bool unicode, bool startFrom1)
{
mIndex = id;
mHWND = hwnd;
mCodePage = codepage;
mUseUnicode = unicode;
mStartFrom1 = startFrom1;
}
/******************************************************************************
*
* NAME
* IMECandidate::Read
*
* DESCRIPTION
* Read the candidate list from IMM
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidate::Read(void)
{
HIMC imc = ImmGetContext(mHWND);
if (imc)
{
DWORD size = 0;
// Get the size of the candidate list
if (mUseUnicode)
{
size = ImmGetCandidateListW(imc, mIndex, NULL, 0);
}
else
{
size = ImmGetCandidateList(imc, mIndex, NULL, 0);
}
// Allocate space to hold candidates
if ((mCandidates == NULL) || (size > mCandidateSize))
{
// Free the existing candidate buffer
if (mCandidates != NULL)
{
delete[] mCandidates;
}
// Allocate a new buffer to hold the candidates
mCandidates = (CANDIDATELIST*)(new unsigned char[size]);
mCandidateSize = size;
}
if (mCandidates != NULL)
{
if (mUseUnicode)
{
ImmGetCandidateListW(imc, mIndex, mCandidates, mCandidateSize);
}
else
{
ImmGetCandidateList(imc, mIndex, mCandidates, mCandidateSize);
}
WWDEBUG_SAY(("IMECandidate: Index %d, Style %08lX, Selection %d, PageStart %d, PageSize %d, Count %d\n",
mIndex, GetStyle(), GetSelection(), GetPageStart(), GetPageSize(), GetCount()));
}
ImmReleaseContext(mHWND, imc);
}
}
/******************************************************************************
*
* NAME
* IMECandidate::Close
*
* DESCRIPTION
* Close the candidate.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidate::Close(void)
{
mIndex = -1;
mHWND = NULL;
mCodePage = CP_ACP;
mUseUnicode = true;
mStartFrom1 = true;
if (mCandidates)
{
memset(mCandidates, 0, sizeof(CANDIDATELIST));
}
}
/******************************************************************************
*
* NAME
* IMECandidate::IsValid
*
* DESCRIPTION
* Check if the candidate data is valid.
*
* INPUTS
* NONE
*
* RESULT
* True if valid
*
******************************************************************************/
bool IMECandidate::IsValid(void) const
{
return ((-1 != mIndex) && (mCandidates != NULL));
}
/******************************************************************************
*
* NAME
* IMECandidate::GetIndex
*
* DESCRIPTION
* Get the candidate index ID
*
* INPUTS
* NONE
*
* RESULT
* Candidate index ID
*
******************************************************************************/
int IMECandidate::GetIndex(void) const
{
return mIndex;
}
/******************************************************************************
*
* NAME
* IMECandidate::GetStyle
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
unsigned long IMECandidate::GetStyle(void) const
{
WWASSERT(mCandidates != NULL);
return mCandidates->dwStyle;
}
/******************************************************************************
*
* NAME
* IMECandidate::GetPageStart
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
unsigned long IMECandidate::GetPageStart(void) const
{
WWASSERT(mCandidates != NULL);
return mCandidates->dwPageStart;
}
/******************************************************************************
*
* NAME
* IMECandidate::SetPageStart
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidate::SetPageStart(unsigned long start)
{
WWASSERT((start >=0) && (start < GetCount()));
if ((start >=0) && (start < GetCount()))
{
HIMC imc = ImmGetContext(mHWND);
if (imc)
{
// The IMM documentation says that the candidate list index must
// be in the range of 0 - 3 for NI_SETCANDIDATE_PAGESTART
WWASSERT((mIndex >= 0 && mIndex <= 3) && "IMM parameter error");
ImmNotifyIME(imc, NI_SETCANDIDATE_PAGESTART, mIndex, start);
ImmReleaseContext(mHWND, imc);
}
}
}
/******************************************************************************
*
* NAME
* IMECandidate::GetPageSize
*
* DESCRIPTION
* Get the number of candidates per page.
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
unsigned long IMECandidate::GetPageSize(void) const
{
WWASSERT(mCandidates != NULL);
return mCandidates->dwPageSize;
}
/******************************************************************************
*
* NAME
* IMECandidate::GetCount
*
* DESCRIPTION
* Get the total number of candidates.
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
// Get the number of candidates in the list.
unsigned long IMECandidate::GetCount(void) const
{
if (mCandidates)
{
return mCandidates->dwCount;
}
return 0;
}
/******************************************************************************
*
* NAME
* IMECandidate::GetSelection
*
* DESCRIPTION
* Get the index of the currently selected candidate.
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
unsigned long IMECandidate::GetSelection(void) const
{
WWASSERT(mCandidates != NULL);
return mCandidates->dwSelection;
}
/******************************************************************************
*
* NAME
* IMECandidate::IsStartFrom1
*
* DESCRIPTION
* Check if the candidates should be listed as starting from 1 or 0
*
* INPUTS
* NONE
*
* RESULT
*
******************************************************************************/
bool IMECandidate::IsStartFrom1(void) const
{
return mStartFrom1;
}
/******************************************************************************
*
* NAME
* IMECandidate::GetCandidate
*
* DESCRIPTION
* Get a candidate string.
*
* INPUTS
* Index of the candidate string to get.
*
* RESULT
* String
*
******************************************************************************/
const wchar_t* IMECandidate::GetCandidate(unsigned long index)
{
if (index < GetCount())
{
// For the IME_CAND_CODE style, the candidate list has a special structure
// depending on the value of the dwCount member. If dwCount is 1, the dwOffset
// member contains a single DBCS character rather than an offset, and no
// candidate string is provided. If the dwCount member is greater than 1,
// the dwOffset member contains valid offsets, and the candidate strings are
// text representations of individual DBCS character values in hexadecimal notation.
if ((IME_CAND_CODE == GetStyle()) && (1 == GetCount()))
{
unsigned long dbcs = mCandidates->dwOffset[0];
// If this char has a lead byte then it is double byte. Swap the bytes
// for generate string order
if (dbcs & 0xFF00)
{
dbcs = (((dbcs & 0xFF) << 8) | (dbcs >> 8));
}
// Convert char to unicode
MultiByteToWideChar(mCodePage, 0, (const char*)&dbcs, -1, mTempString, 1);
mTempString[1] = 0;
return mTempString;
}
DWORD offset = mCandidates->dwOffset[index];
const char* candString = ((const char*)mCandidates + offset);
if (mUseUnicode)
{
return ((const wchar_t*)candString);
}
MultiByteToWideChar(mCodePage, 0, candString, -1, mTempString, (sizeof(mTempString) / sizeof(wchar_t)));
mTempString[(sizeof(mTempString) / sizeof(wchar_t)) - 1] = 0;
return mTempString;
}
return NULL;
}
/******************************************************************************
*
* NAME
* IMECandidate::SelectCandidate
*
* DESCRIPTION
* Select a string in the candidate list.
*
* INPUTS
* Index of candidate string to select.
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidate::SelectCandidate(unsigned long selection)
{
HIMC imc = ImmGetContext(mHWND);
if (imc)
{
ImmNotifyIME(imc, NI_SELECTCANDIDATESTR, mIndex, selection);
ImmNotifyIME(imc, NI_CLOSECANDIDATE, mIndex, 0);
ImmReleaseContext(mHWND, imc);
}
}
/******************************************************************************
*
* NAME
* IMECandidate::SetView
*
* DESCRIPTION
*
* INPUTS
* Top - Index of top candidate.
* Bottom - Index of bottom candidate.
*
* RESULT
*
******************************************************************************/
void IMECandidate::SetView(unsigned long topIndex, unsigned long bottomIndex)
{
HIMC imc = ImmGetContext(mHWND);
if (imc)
{
ImmNotifyIME(imc, NI_SETCANDIDATE_PAGESIZE, mIndex, (bottomIndex - topIndex) + 1);
ImmNotifyIME(imc, NI_SETCANDIDATE_PAGESTART, mIndex, topIndex);
ImmReleaseContext(mHWND, imc);
}
}
} // namespace IME

128
Code/wwui/IMECandidate.h Normal file
View File

@@ -0,0 +1,128 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/******************************************************************************
*
* FILE
* $Archive: /Commando/Code/wwui/IMECandidate.h $
*
* DESCRIPTION
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 1/11/02 6:44p $
*
******************************************************************************/
#ifndef __IMECANDIDATE_H__
#define __IMECANDIDATE_H__
#include "Notify.h"
#include "win.h"
#include <imm.h>
#pragma warning(disable : 4514)
#if defined(_MSC_VER)
#pragma warning(push, 3)
#endif
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
namespace IME {
class IMECandidate
{
public:
IMECandidate();
~IMECandidate();
void Open(int index, HWND hwnd, UINT codepage, bool unicode, bool startFrom1);
void Read(void);
void Close(void);
bool IsValid(void) const;
int GetIndex(void) const;
unsigned long GetStyle(void) const;
// Get the index of the first candidate in the page
unsigned long GetPageStart(void) const;
// Set the page to start with the specified candidate index
void SetPageStart(unsigned long);
// Get the number of candidates per page
unsigned long GetPageSize(void) const;
// Get the total number of candidates in the list.
unsigned long GetCount(void) const;
// Get the index of the current candidate selection
unsigned long GetSelection(void) const;
// Get the specified candidate string
const wchar_t* GetCandidate(unsigned long index);
// Select a candidate from the list.
void SelectCandidate(unsigned long index);
// Set the candidate page view
void SetView(unsigned long topIndex, unsigned long bottomIndex);
// Check if the candidates should be displayed starting from 1 or 0
bool IsStartFrom1(void) const;
private:
int mIndex;
HWND mHWND;
UINT mCodePage;
bool mUseUnicode;
bool mStartFrom1;
unsigned long mCandidateSize;
CANDIDATELIST* mCandidates;
// Multibyte -> Unicode string conversion buffer
wchar_t mTempString[80];
};
typedef enum
{
CANDIDATE_OPEN = 1,
CANDIDATE_CHANGE,
CANDIDATE_CLOSE
} CandidateAction;
typedef TypedActionPtr<CandidateAction, IMECandidate> CandidateEvent;
typedef std::vector<IMECandidate> IMECandidateCollection;
} // namespace IME
#endif // __IMECANDIDATE_H__

View File

@@ -0,0 +1,684 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "IMECandidateCtrl.h"
#include "IMECandidate.h"
#include "DialogBase.h"
#include "StyleMgr.h"
#include "MouseMgr.h"
#define BORDER_WIDTH 2
#define BORDER_HEIGHT 2
/******************************************************************************
*
* NAME
* IMECandidateCtrl::IMECandidateCtrl
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
IMECandidateCtrl::IMECandidateCtrl() :
mFullRect(0,0,0,0),
mCellSize(0,0),
mCurrSel(-1),
mScrollPos(0),
mCellsPerPage(0),
mCandidate(NULL)
{
StyleMgrClass::Assign_Font(&mTextRenderer, StyleMgrClass::FONT_LISTS);
// Candidate control never wants to take focus
Set_Wants_Focus(false);
// Setup child scrollbar
mScrollBarCtrl.Set_Wants_Focus(false);
mScrollBarCtrl.Set_Small_BMP_Mode(true);
mScrollBarCtrl.Set_Advise_Sink(this);
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::~IMECandidateCtrl
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
IMECandidateCtrl::~IMECandidateCtrl()
{
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::Init
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::Init(IME::IMECandidate* candidate)
{
WWDEBUG_SAY(("IMECandidateCtrl: Init\n"));
Reset();
mCandidate = candidate;
Changed(candidate);
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::Changed
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::Changed(IME::IMECandidate* candidate)
{
WWDEBUG_SAY(("IMECandidateCtrl: Changed\n"));
WWASSERT(mCandidate == candidate);
if (candidate)
{
mScrollPos = candidate->GetPageStart();
unsigned long candSel = candidate->GetSelection();
if (candSel != (unsigned long)mCurrSel)
{
mCurrSel = candSel;
UpdateScrollPos();
}
}
Set_Dirty();
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::Reset
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::Reset(void)
{
mCellSize.Set(0,0);
mCurrSel = -1;
mScrollPos = 0;
mCellsPerPage = 0;
mScrollBarCtrl.Show(false);
mCandidate = NULL;
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::CreateControlRenderer
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::CreateControlRenderer(void)
{
Render2DClass& renderer = mControlRenderer;
// Configure this renderer
renderer.Reset();
renderer.Enable_Texturing(false);
renderer.Set_Coordinate_Range(Render2DClass::Get_Screen_Resolution());
renderer.Add_Quad(mFullRect, RGBA_TO_INT32(0, 0, 0, 170));
// Determine which color to draw the outline in
int color = StyleMgrClass::Get_Line_Color();
int bkColor = StyleMgrClass::Get_Bk_Color();
if (IsEnabled == false)
{
color = StyleMgrClass::Get_Disabled_Line_Color();
bkColor = StyleMgrClass::Get_Disabled_Bk_Color();
}
// Draw the control outline
RectClass rect = Rect;
renderer.Add_Outline(rect, 1.0F, color);
// Now draw the background
rect.Right -= 1;
rect.Bottom -= 1;
renderer.Add_Quad(rect, bkColor);
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::CreateTextRenderer
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::CreateTextRenderer(void)
{
mHilightRenderer.Reset();
mHilightRenderer.Set_Coordinate_Range(Render2DClass::Get_Screen_Resolution());
StyleMgrClass::Configure_Hilighter(&mHilightRenderer);
mTextRenderer.Reset();
if (mCandidate)
{
// Add each candidate to the list
const unsigned int selIndexBias = (mCandidate->IsStartFrom1() ? 1 : 0);
float currYPos = ClientRect.Top;
const unsigned long candidateCount = mCandidate->GetCount();
for (unsigned long index = mScrollPos; index < candidateCount; ++index)
{
// Build the rectangle we will draw the text into
RectClass textRect;
textRect.Left = ClientRect.Left;
textRect.Top = currYPos;
textRect.Right = (textRect.Left + mCellSize.X);
textRect.Bottom = (textRect.Top + mCellSize.Y);
// If this cell extends past the end of the control then stop
if (textRect.Bottom > ClientRect.Bottom)
{
break;
}
// Draw the text
const WCHAR* text = mCandidate->GetCandidate(index);
WideStringClass entry(0, true);
entry.Format(L"%d. %s", ((index - mScrollPos) + selIndexBias), text);
StyleMgrClass::Render_Text(entry, &mTextRenderer, textRect, true, true);
// Hilight this entry (if its the currently selected one)
if ((int)index == mCurrSel)
{
StyleMgrClass::Render_Hilight(&mHilightRenderer, textRect);
}
currYPos += mCellSize.Y;
}
}
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::Render
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::Render(void)
{
// Recreate the renderers (if necessary)
if (IsDirty)
{
CreateControlRenderer();
CreateTextRenderer();
}
mControlRenderer.Render();
mTextRenderer.Render();
mHilightRenderer.Render();
DialogControlClass::Render();
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::SetCurrSel
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::SetCurrSel(int index)
{
if (mCandidate)
{
if ((index != mCurrSel) && (index == -1) || ((index >= 0) && (unsigned long)index < mCandidate->GetCount()))
{
mCurrSel = index;
Set_Dirty();
}
}
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::EntryFromPos
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
*
******************************************************************************/
int IMECandidateCtrl::EntryFromPos(const Vector2& mousePos)
{
if (mCandidate)
{
// Loop over all the entries in our current view
float currYPos = ClientRect.Top;
const unsigned long candidateCount = mCandidate->GetCount();
for (unsigned long index = mScrollPos; index < candidateCount; ++index)
{
// Is ths mouse over this entry?
if ((mousePos.Y >= currYPos && mousePos.Y <= (currYPos + mCellSize.Y))
|| mousePos.Y > ClientRect.Bottom)
{
return index;
}
currYPos += mCellSize.Y;
}
}
return -1;
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::UpdateScrollPos
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::UpdateScrollPos(void)
{
if (mCurrSel != -1)
{
unsigned int scrollPos = mScrollPos;
if (mCurrSel < (int)scrollPos)
{
// Scroll up so the current selection is in view
scrollPos = mCurrSel;
Set_Dirty();
}
else if (mCurrSel >= (int)(scrollPos + mCellsPerPage))
{
// Scroll down so the current selection is in view
scrollPos = max<unsigned int>((unsigned int)mCurrSel - (mCellsPerPage - 1), 0);
Set_Dirty();
}
if (scrollPos != mScrollPos)
{
// Update the scrollbar
mScrollBarCtrl.Set_Pos(mScrollPos, false);
if (mCandidate)
{
mCandidate->SetPageStart(mScrollPos);
}
}
}
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::Update_Client_Rect
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::Update_Client_Rect(void)
{
WWDEBUG_SAY(("IMECandidateCtrl: Update_Client_Rect()\n"));
Vector2 pageSize;
CalculateCandidatePageExtent(pageSize, mCellSize);
mCellsPerPage = (unsigned int)(pageSize.Y / mCellSize.Y);
Rect.Right = (Rect.Left + (pageSize.X + (BORDER_WIDTH * 2.0f)));
Rect.Bottom = (Rect.Top + (pageSize.Y + (BORDER_HEIGHT * 2.0f)));
mFullRect = Rect;
ClientRect = Rect;
ClientRect.Inflate(Vector2(-BORDER_WIDTH, -BORDER_HEIGHT));
if (mCandidate)
{
WWASSERT(mCandidate->GetPageSize() <= mCellsPerPage);
// Do we need to show a scroll bar?
const unsigned long candidateCount = mCandidate->GetCount();
if ((unsigned long)mCellsPerPage < candidateCount)
{
// Position the scrollbar to the right of the list
RectClass scrollRect;
scrollRect.Left = mFullRect.Right;
scrollRect.Top = mFullRect.Top;
scrollRect.Right = -1;
scrollRect.Bottom = mFullRect.Bottom;
// Size the scroll bar
mScrollBarCtrl.Set_Window_Rect(scrollRect);
mScrollBarCtrl.Set_Page_Size(mCellsPerPage - 1);
mScrollBarCtrl.Set_Range(0, (candidateCount - mCellsPerPage));
mScrollBarCtrl.Show(true);
const RectClass& rect = mScrollBarCtrl.Get_Window_Rect();
mFullRect.Right = rect.Right;
}
}
Set_Dirty();
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::CalculateCandidatePageExtent(Vector2& outExtent, Vector2& outCellSize)
{
if (mCandidate)
{
// Get the size of the widest candidate string.
float maxCandWidth = 0.0f;
const unsigned long candidateCount = mCandidate->GetCount();
for (unsigned long index = 0; index < candidateCount; ++index)
{
// Get the extent of the current entry
const WCHAR* text = mCandidate->GetCandidate(index);
Vector2 textExtent = mTextRenderer.Get_Text_Extents(text);
if (textExtent.X > maxCandWidth)
{
maxCandWidth = textExtent.X;
}
}
Vector2 charSize = mTextRenderer.Get_Text_Extents(L"W");
// The cell size is the maximum candidate size plus some spacing.
outCellSize.X = (maxCandWidth + (charSize.X * 3.0f));
outCellSize.Y = (charSize.Y * 1.25f);
outExtent.X = outCellSize.X;
outExtent.Y = (mCellSize.Y * (float)mCandidate->GetPageSize());
}
else
{
outExtent.X = 0.0f;
outExtent.Y = 0.0f;
outCellSize.X = 0.0f;
outCellSize.Y = 0.0f;
}
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::On_Set_Cursor
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::On_Set_Cursor(const Vector2& mousePos)
{
// Change the mouse cursor if necessary
if (ClientRect.Contains(mousePos))
{
MouseMgrClass::Set_Cursor(MouseMgrClass::CURSOR_ACTION);
}
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::On_LButton_Down
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::On_LButton_Down(const Vector2& mousePos)
{
SetCurrSel(EntryFromPos(mousePos));
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::On_LButton_Up
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::On_LButton_Up(const Vector2& mousePos)
{
int sel = EntryFromPos(mousePos);
SetCurrSel(sel);
// Process candidate selection here
if (mCandidate && (sel >= 0))
{
const wchar_t* string = mCandidate->GetCandidate(sel);
WWDEBUG_SAY(("*** Selected Candidate: %d %04x\n", sel, *string));
mCandidate->SelectCandidate((unsigned long)sel);
}
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::On_Add_To_Dialog
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::On_Add_To_Dialog(void)
{
Parent->Add_Control(&mScrollBarCtrl);
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::On_Remove_From_Dialog
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::On_Remove_From_Dialog(void)
{
Parent->Remove_Control(&mScrollBarCtrl);
}
/******************************************************************************
*
* NAME
* IMECandidateCtrl::On_VScroll
*
* DESCRIPTION
*
* INPUTS
*
* RESULT
* NONE
*
******************************************************************************/
void IMECandidateCtrl::On_VScroll(ScrollBarCtrlClass*, int , int newPos)
{
mScrollPos = newPos;
if (mCandidate)
{
mCandidate->SetPageStart(mScrollPos);
}
Set_Dirty();
}

View File

@@ -0,0 +1,93 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __IMECANDIDATECTRL_H__
#define __IMECANDIDATECTRL_H__
#include "DialogControl.h"
#include "ScrollBarCtrl.h"
#include "Render2D.h"
#include "Render2DSentence.h"
#include "Vector.h"
namespace IME
{
class IMECandidate;
}
class IMECandidateCtrl :
public DialogControlClass
{
public:
IMECandidateCtrl();
virtual ~IMECandidateCtrl();
void Init(IME::IMECandidate* candidate);
void Changed(IME::IMECandidate* candidate);
void Reset(void);
protected:
void CreateControlRenderer(void);
void CreateTextRenderer(void);
void SetCurrSel(int index);
int EntryFromPos(const Vector2& mousePos);
void UpdateScrollPos(void);
void CalculateCandidatePageExtent(Vector2& outExtent, Vector2& outCellSize);
// DialogControlClass methods
public:
const RectClass& Get_Window_Rect(void) const
{return mFullRect;}
protected:
void Render(void);
void Update_Client_Rect(void);
void On_Set_Cursor(const Vector2& mousePos);
void On_LButton_Down(const Vector2& mousePos);
void On_LButton_Up(const Vector2& mousePos);
void On_Add_To_Dialog(void);
void On_Remove_From_Dialog(void);
// ControlAdviseSinkClass methods
protected:
void On_VScroll(ScrollBarCtrlClass*, int, int);
// Data members
protected:
RectClass mFullRect;
Vector2 mCellSize;
int mCurrSel;
unsigned int mScrollPos;
unsigned int mCellsPerPage;
ScrollBarCtrlClass mScrollBarCtrl;
RectClass mScrollBarRect;
Render2DClass mControlRenderer;
Render2DClass mHilightRenderer;
Render2DSentenceClass mTextRenderer;
IME::IMECandidate* mCandidate;
};
#endif // __IMECANDIDATECTRL_H__

1857
Code/wwui/IMEManager.cpp Normal file

File diff suppressed because it is too large Load Diff

217
Code/wwui/IMEManager.h Normal file
View File

@@ -0,0 +1,217 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/******************************************************************************
*
* FILE
* $Archive: /Commando/Code/wwui/IMEManager.h $
*
* DESCRIPTION
* Input Method Editor Manager for input of far east characters.
*
* PROGRAMMER
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 3 $
* $Modtime: 1/08/02 8:38p $
*
******************************************************************************/
#ifndef __IMEMANAGER_H__
#define __IMEMANAGER_H__
#include "RefCount.h"
#include "IMECandidate.h"
#include "Notify.h"
#include "WideString.h"
#include "win.h"
#include <imm.h>
namespace IME {
#define IME_MAX_STRING_LEN 255
#define IME_MAX_TYPING_LEN 80
class IMEManager;
typedef enum
{
IME_ACTIVATED = 1,
IME_DEACTIVATED,
IME_LANGUAGECHANGED,
IME_GUIDELINE,
IME_ENABLED,
IME_DISABLED,
} IMEAction;
typedef TypedActionPtr<IMEAction, IMEManager> IMEEvent;
typedef enum
{
COMPOSITION_INVALID = 0,
COMPOSITION_TYPING,
COMPOSITION_START,
COMPOSITION_CHANGE,
COMPOSITION_FULL,
COMPOSITION_END,
COMPOSITION_CANCEL,
COMPOSITION_RESULT
} CompositionAction;
typedef TypedActionPtr<CompositionAction, IMEManager> CompositionEvent;
class UnicodeType;
typedef TypedEvent<UnicodeType, wchar_t> UnicodeChar;
class IMEManager :
public RefCountClass,
public Notifier<IMEEvent>,
public Notifier<UnicodeChar>,
public Notifier<CompositionEvent>,
public Notifier<CandidateEvent>
{
public:
static IMEManager* Create(HWND hwnd);
void Activate(void);
void Deactivate(void);
bool IsActive(void) const;
void Disable(void);
void Enable(void);
bool IsDisabled(void) const;
const wchar_t* GetDescription(void) const
{return mIMEDescription;}
WORD GetLanguageID(void) const
{return mLangID;}
UINT GetCodePage(void) const
{return mCodePage;}
const wchar_t* GetResultString(void) const
{return mResultString;}
const wchar_t* GetCompositionString(void) const
{return mCompositionString;}
long GetCompositionCursorPos(void) const
{return mCompositionCursorPos;}
const wchar_t* GetReadingString(void) const
{return mReadingString;}
#ifdef SHOW_IME_TYPING
const wchar_t* GetTypingString(void) const
{return mTypingString;}
#endif
void GetTargetClause(unsigned long& start, unsigned long& end);
bool GetCompositionFont(LPLOGFONT lpFont);
const IMECandidateCollection GetCandidateColl(void) const
{return mCandidateColl;}
unsigned long GetGuideline(wchar_t* outString, int length);
bool ProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& result);
protected:
IMEManager();
virtual ~IMEManager();
bool FinalizeCreate(HWND hwnd);
LRESULT IMENotify(WPARAM wParam, LPARAM lParam);
HKL InputLanguageChangeRequest(HKL hkl);
void InputLanguageChanged(HKL hkl);
void ResetComposition(void);
void StartComposition(void);
void DoComposition(unsigned int dbcsChar, long changeFlag);
void EndComposition(void);
bool ReadCompositionString(HIMC imc, unsigned long flag, wchar_t* buffer, int length);
long ReadReadingAttr(HIMC imc, unsigned char* attr, int length);
long ReadReadingClause(HIMC imc, unsigned long* clause, int length);
long ReadCompositionAttr(HIMC imc, unsigned char* attr, int length);
long ReadCompositionClause(HIMC imc, unsigned long* clause, int length);
long ReadCursorPos(HIMC imc);
void OpenCandidate(unsigned long candList);
void ChangeCandidate(unsigned long candList);
void CloseCandidate(unsigned long candList);
bool IMECharHandler(unsigned short dbcs);
bool CharHandler(unsigned short ch);
long ConvertAttrForUnicode(unsigned char* mbcs, unsigned char* attr);
long ConvertClauseForUnicode(unsigned char* mbcs, long length, unsigned long* clause);
DECLARE_NOTIFIER(IMEEvent)
DECLARE_NOTIFIER(UnicodeChar)
DECLARE_NOTIFIER(CompositionEvent)
DECLARE_NOTIFIER(CandidateEvent)
// Prevent copy and assignment
IMEManager(const IMEManager&);
const IMEManager& operator=(const IMEManager&);
private:
HWND mHWND;
HIMC mDefaultHIMC;
HIMC mHIMC;
HIMC mDisabledHIMC;
unsigned long mDisableCount;
WORD mLangID;
UINT mCodePage;
WideStringClass mIMEDescription;
DWORD mIMEProperties;
bool mHilite;
bool mStartCandListFrom1;
bool mOSCanUnicode;
bool mUseUnicode;
bool mInComposition;
#ifdef SHOW_IME_TYPING
wchar_t mTypingString[IME_MAX_TYPING_LEN];
long mTypingCursorPos;
#endif
wchar_t mCompositionString[IME_MAX_STRING_LEN];
unsigned char mCompositionAttr[IME_MAX_STRING_LEN];
unsigned long mCompositionClause[IME_MAX_STRING_LEN / 2];
long mCompositionCursorPos;
wchar_t mReadingString[IME_MAX_STRING_LEN * 2];
wchar_t mResultString[IME_MAX_STRING_LEN];
IMECandidateCollection mCandidateColl;
};
} // namespace IME
#endif __IMEMANAGER_H__

416
Code/wwui/ProgressCtrl.cpp Normal file
View File

@@ -0,0 +1,416 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/******************************************************************************
*
* FILE
* $Archive: /Commando/Code/wwui/ProgressCtrl.cpp $
*
* DESCRIPTION
* Progress bar control
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 4 $
* $Modtime: 1/12/02 9:44p $
*
******************************************************************************/
#include "ProgressCtrl.h"
#include "StyleMgr.h"
#define BAR_INSET 3
/******************************************************************************
*
* NAME
* ProgressCtrlClass::ProgressCtrlClass
*
* DESCRIPTION
* Constructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
ProgressCtrlClass::ProgressCtrlClass(void) :
mBarRect(0, 0, 0, 0),
mMinLimit(0),
mMaxLimit(100),
mPosition(0),
mStep(10)
{
StyleMgrClass::Configure_Renderer(&mControlRenderer);
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::~ProgressCtrlClass
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
ProgressCtrlClass::~ProgressCtrlClass()
{
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Create_Control_Renderers
*
* DESCRIPTION
* Create the renderers for the control
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Create_Control_Renderers(void)
{
Render2DClass& renderer = mControlRenderer;
// Configure this renderer
renderer.Reset();
renderer.Enable_Texturing(false);
// Determine which color to draw the outline in
int color = StyleMgrClass::Get_Line_Color();
int bkColor = StyleMgrClass::Get_Bk_Color();
if (IsEnabled == false)
{
color = StyleMgrClass::Get_Disabled_Line_Color();
bkColor = StyleMgrClass::Get_Disabled_Bk_Color();
}
// Draw the control outline
RectClass rect = Rect;
renderer.Add_Outline(rect, 1.0F, color);
// Now draw the background
rect.Right -= 1;
rect.Bottom -= 1;
renderer.Add_Quad(rect, bkColor);
// Draw the bar
if (mPosition > mMinLimit)
{
int barColor = StyleMgrClass::Get_Text_Color();
if (IsEnabled == false)
{
barColor = StyleMgrClass::Get_Disabled_Text_Color();
}
renderer.Add_Quad(mBarRect, barColor);
}
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Calculate_Bar_Width
*
* DESCRIPTION
* Calculate the new bar width.
*
* INPUTS
* Position - Position to calculate bar width for.
*
* RESULT
* NONE
*
******************************************************************************/
float ProgressCtrlClass::Calculate_Bar_Width(unsigned int position)
{
// Adjust the bar to reflect the new position
float maxBarWidth = (Rect.Width() - (float)(2 * BAR_INSET));
float scaler = (maxBarWidth / (float)(mMaxLimit - mMinLimit));
float barWidth = (scaler * (float)(position - mMinLimit));
return barWidth;
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Update_Client_Rect
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Update_Client_Rect(void)
{
// Calculate the new bar rectangle
mBarRect.Left = Rect.Left + BAR_INSET;
mBarRect.Top = Rect.Top + BAR_INSET;
mBarRect.Bottom = Rect.Bottom - BAR_INSET;
mBarRect.Right = (mBarRect.Left + Calculate_Bar_Width(mPosition));
Set_Dirty();
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Render
*
* DESCRIPTION
* Render the control
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Render(void)
{
// Recreate the renderers (if necessary)
if (IsDirty)
{
Create_Control_Renderers();
}
// Render the progress bar's current state
mControlRenderer.Render();
DialogControlClass::Render();
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Set_Range
*
* DESCRIPTION
* Sets the minimum and maximum values for the progress bar and redraws the
* bar to reflect the new range.
*
* INPUTS
* Min - Minimum range value
* Max - Maximum range value
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Set_Range(unsigned int min, unsigned int max)
{
WWASSERT(min < max);
// Scale current position to new range
if (mPosition > mMinLimit)
{
float oldDelta = (mMaxLimit - mMinLimit);
float newDelta = (max - min);
float scaler = (oldDelta / newDelta);
unsigned int position = (unsigned int)((float)mPosition * scaler);
Set_Position(position);
}
mMinLimit = min;
mMaxLimit = max;
Set_Dirty();
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Get_Range
*
* DESCRIPTION
* Get the minimun and maximum values for the progress bar.
*
* INPUTS
* Min - On return; Minimum range value
* Max - On return; Maximum range value
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Get_Range(unsigned int& min, unsigned int& max)
{
min = mMinLimit;
max = mMaxLimit;
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Set_Position
*
* DESCRIPTION
* Set the current position for the progress bar.
*
* INPUTS
* Position - New position
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Set_Position(unsigned int position)
{
unsigned int oldPosition = mPosition;
mPosition = min<unsigned int>(mMaxLimit, position);
mPosition = max<unsigned int>(mMinLimit, mPosition);
if (oldPosition != mPosition)
{
mBarRect.Right = (mBarRect.Left + Calculate_Bar_Width(mPosition));
Set_Dirty();
}
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Delta_Position
*
* DESCRIPTION
* Advance the position of the progress bar by a specified increment.
*
* INPUTS
* Delta - Amount to advance the position by.
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Delta_Position(int delta)
{
Set_Position(mPosition + delta);
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Get_Position
*
* DESCRIPTION
* Get the current position of the progress bar.
*
* INPUTS
* NONE
*
* RESULT
* Position - Progress position
*
******************************************************************************/
unsigned int ProgressCtrlClass::Get_Position(void) const
{
return mPosition;
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Set_Step
*
* DESCRIPTION
* Specify the step increment for the progress bar. This is the amount
* the progress bar increases its current position whenever Step_Position()
* is called.
*
* INPUTS
* Step - New step increment.
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Set_Step(unsigned int step)
{
mStep = min<unsigned int>((mMaxLimit - mMinLimit), step);
mStep = max<unsigned int>(1, mStep);
}
/******************************************************************************
*
* NAME
* ProgressCtrlClass::Step_Position
*
* DESCRIPTION
* Advance the position for the progress bar by the step increment.
*
* INPUTS
* NONE
*
* RESULT
* NONE
*
******************************************************************************/
void ProgressCtrlClass::Step_Position(void)
{
float stepping = ((float)(mMaxLimit - mMinLimit) / (float)mStep);
float stepPos = (floor((float)mPosition / stepping) * stepping);
Set_Position(stepPos + mStep);
}

104
Code/wwui/ProgressCtrl.h Normal file
View File

@@ -0,0 +1,104 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/******************************************************************************
*
* FILE
* $Archive: /Commando/Code/wwui/ProgressCtrl.h $
*
* DESCRIPTION
* Progress bar control
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Denzil_l $
*
* VERSION INFO
* $Revision: 2 $
* $Modtime: 10/18/01 9:22a $
*
******************************************************************************/
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __PROGRESS_CTRL_H
#define __PROGRESS_CTRL_H
#include "DialogControl.h"
#include "Render2D.h"
//#include "vector3.h"
//#include "bittype.h"
class ProgressCtrlClass :
public DialogControlClass
{
public:
ProgressCtrlClass(void);
virtual ~ProgressCtrlClass();
// RTTI
ProgressCtrlClass* As_ProgressCtrlClass(void)
{return this;}
void Render(void);
// Sets the minimum and maximum values for the progress bar and redraws
// the bar to reflect the new range.
void Set_Range(unsigned int min, unsigned int max);
// Get the minimun and maximum values for the progress bar.
void Get_Range(unsigned int& min, unsigned int& max);
// Set the current position for the progress bar.
void Set_Position(unsigned int position);
// Advance the position of the progress bar by a specified increment.
void Delta_Position(int delta);
// Get the current position of the progress bar.
unsigned int Get_Position(void) const;
// Specify the step increment for the progress bar. This is the amount
// the progress bar increases its position whenever Step_Position()
// is called.
void Set_Step(unsigned int step);
// Advance the position for the progress bar by the step increment.
void Step_Position(void);
protected:
void Create_Control_Renderers(void);
float Calculate_Bar_Width(unsigned int position);
void Update_Client_Rect(void);
protected:
Render2DClass mControlRenderer;
RectClass mBarRect;
unsigned int mMinLimit;
unsigned int mMaxLimit;
unsigned int mPosition;
unsigned int mStep;
};
#endif //__PROGRESS_CTRL_H

766
Code/wwui/buttonctrl.cpp Normal file
View File

@@ -0,0 +1,766 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/buttonctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/02/02 11:16a $*
* *
* $Revision:: 14 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
#pragma warning(disable : 4530)
#include "buttonctrl.h"
#include "assetmgr.h"
#include "font3d.h"
#include "dialogbase.h"
#include "mousemgr.h"
#include "stylemgr.h"
#include "dialogmgr.h"
////////////////////////////////////////////////////////////////
// Local constants
////////////////////////////////////////////////////////////////
static const RectClass BUTTON_UVS (96.0F, 51.0F, 217.0F, 84.0F);
static const RectClass BUTTON_DN_UVS (96.0F, 92.0F, 217.0F, 125.0F);
static const RectClass HILIGHT_UVS (117.0F, 4.0F, 220.0F, 41.0F);
////////////////////////////////////////////////////////////////
//
// ButtonCtrlClass
//
////////////////////////////////////////////////////////////////
ButtonCtrlClass::ButtonCtrlClass (void) :
WasButtonPressedOnMe (false),
IsMouseOverMe (false),
PulseTime (0)
{
//
// Set the font for the text renderer
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_CONTROLS);
StyleMgrClass::Assign_Font (&GlowRenderer, StyleMgrClass::FONT_CONTROLS);
//
// Configure the renderers
//
StyleMgrClass::Configure_Renderer (&ButtonRenderers[0]);
StyleMgrClass::Configure_Renderer (&ButtonRenderers[1]);
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (Is_Dirty ()) {
Create_Text_Renderers ();
//
// Determine which type of button to create
//
if ((Get_Style () & BS_BITMAP) == 0) {
Create_Component_Button ();
} else {
Create_Bitmap_Button ();
}
//Create_Vector_Button ();
//Create_Bitmap_Button ();
}
if (WasButtonPressedOnMe && IsMouseOverMe) {
//
// Render the button "pressed"
//
ButtonRenderers[DOWN].Render ();
ButtonRenderers[UP].Render ();
} else {
//
// Render the button normally
//
ButtonRenderers[UP].Render ();
}
//
// Render the text (only if its not a bitmap button)
//
if ((Get_Style () & BS_BITMAP) == 0) {
if (HasFocus) {
GlowRenderer.Render ();
}
TextRenderer.Render ();
}
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_Create (void)
{
GlowRenderer.Build_Sentence (Title);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
Set_Capture ();
WasButtonPressedOnMe = true;
//
// Play the sound effect
//
StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MOUSE_CLICK);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
Release_Capture ();
IsMouseOverMe = Rect.Contains (mouse_pos);
//
// Notify the parent (if necessary)
//
if (WasButtonPressedOnMe && IsMouseOverMe) {
Parent->On_Command (ID, BN_CLICKED, 0);
}
WasButtonPressedOnMe = false;
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Move
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
{
IsMouseOverMe = Rect.Contains (mouse_pos);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Vector_Button
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Create_Vector_Button (void)
{
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
ButtonRenderers[0].Enable_Texturing (false);
ButtonRenderers[1].Enable_Texturing (false);
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
} else if (HasFocus) {
//bkcolor =
}
//
// Draw the button outline
//
ButtonRenderers[0].Add_Outline (Rect, 1.0F, color);
ButtonRenderers[1].Add_Outline (Rect, 1.0F, RGB_TO_INT32 (255, 0, 0));
//
// Draw the button center
//
RectClass rect = Rect;
rect.Right -= 1;
rect.Bottom -= 1;
ButtonRenderers[0].Add_Quad (rect, bkcolor);
ButtonRenderers[1].Add_Quad (rect, RGB_TO_INT32 (128, 0, 0));
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Bitmap_Button
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Create_Bitmap_Button (void)
{
//
// Darken the bitmap if its disabled
//
int color = 0xFFFFFFFF;
if (IsEnabled == false) {
color = RGB_TO_INT32 (96, 96, 96);
}
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
ButtonRenderers[0].Add_Quad (Rect, color);
ButtonRenderers[1].Add_Quad (Rect, color);
//
// Turn off texturing on the UI background
//
/*TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("if_circle02.tga", TextureClass::MIP_LEVELS_1);
ButtonRenderers[0].Set_Texture (texture);
ButtonRenderers[1].Set_Texture (texture);
texture->Release_Ref();
RectClass uv_rect1 = BUTTON_UVS;
uv_rect1.Inverse_Scale (Vector2 (256.0F, 256.0F));
ButtonRenderers[0].Add_Quad (Rect, uv_rect1);
RectClass uv_rect2 = BUTTON_DN_UVS;
uv_rect2.Inverse_Scale (Vector2 (256.0F, 256.0F));
ButtonRenderers[1].Add_Quad (Rect, uv_rect2);
ShaderClass *shader = ButtonRenderers[0].Get_Shader ();
shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE);
shader = ButtonRenderers[1].Get_Shader ();
shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE); */
return ;
}
////////////////////////////////////////////////////////////////
//
// Blit_Section
//
////////////////////////////////////////////////////////////////
void
Blit_Section
(
Render2DClass & renderer,
const Vector2 & screen_pos,
const Vector2 & texture_pos,
const Vector2 & pixels,
const Vector2 & texture_dimensions
)
{
RectClass screen_rect;
screen_rect.Left = screen_pos.X;
screen_rect.Top = screen_pos.Y;
screen_rect.Right = screen_rect.Left + pixels.X;
screen_rect.Bottom = screen_rect.Top + pixels.Y;
RectClass uv_rect (texture_pos.X, texture_pos.Y, texture_pos.X + pixels.X, texture_pos.Y + pixels.Y);
uv_rect.Inverse_Scale (Vector2 (texture_dimensions.X, texture_dimensions.Y));
renderer.Add_Quad (screen_rect, uv_rect);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Component_Button
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Create_Component_Button (void)
{
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
//
// Turn off texturing on the UI background
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("if_circle02.tga", TextureClass::MIP_LEVELS_1);
ButtonRenderers[0].Set_Texture (texture);
ButtonRenderers[1].Set_Texture (texture);
texture->Release_Ref();
float height = 10.0F;
float edge_width = 10.0F;
float top = BUTTON_UVS.Top;
float left = BUTTON_UVS.Left;
float right = BUTTON_UVS.Right;
float bottom = BUTTON_UVS.Bottom;
// float dn_start = bottom - height;
//float horz_tile_width = 20.0F;
//float vert_tile_height = 10.0F;
Vector2 texture_dimensions (256.0F, 256.0F);
//
// Upper left
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, Rect.Top), Vector2 (left, top),
Vector2 (edge_width, height), texture_dimensions);
//
// Upper right
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, Rect.Top), Vector2 (right - edge_width, top),
Vector2 (edge_width, height), texture_dimensions);
//
// Lower left
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, Rect.Bottom - height), Vector2 (left, bottom - height),
Vector2 (edge_width, height), texture_dimensions);
//
// Lower right
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, Rect.Bottom - height), Vector2 (right - edge_width, bottom - height),
Vector2 (edge_width, height), texture_dimensions);
Vector2 horz_top_pos (left + ((right-left) / 2) - 5, top);
Vector2 horz_bottom_pos (left + ((right-left) / 2) - 5, bottom - height);
Vector2 horz_size (10, height);
//
// Horizontal tile
//
float remaining_width = Rect.Width () - (edge_width * 2);
float x_pos = Rect.Left + edge_width;
while (remaining_width > 0) {
horz_size.X = min (remaining_width, horz_size.X);
::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, Rect.Top), horz_top_pos,
horz_size, texture_dimensions);
::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, Rect.Bottom - height), horz_bottom_pos,
horz_size, texture_dimensions);
x_pos += horz_size.X;
remaining_width -= horz_size.X;
}
Vector2 vert_left_pos (left, top + ((bottom - top)/ 2) - 5);
Vector2 vert_right_pos (right - edge_width, top + ((bottom - top)/ 2) - 5);
Vector2 vert_size (edge_width, 10);
//
// Vertical tile
//
float remaining_height = Rect.Height () - (height * 2);
float y_pos = Rect.Top + height;
while (remaining_height > 0) {
vert_size.Y = min (remaining_height, vert_size.Y);
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, y_pos), vert_left_pos,
vert_size, texture_dimensions);
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, y_pos), vert_right_pos,
vert_size, texture_dimensions);
y_pos += vert_size.Y;
remaining_height -= vert_size.Y;
}
RectClass hilight_rect = Rect;
hilight_rect.Inflate (Vector2 (-((edge_width/2)+1), -((height/2)+1)));
hilight_rect.Right += 1.0F;
hilight_rect.Bottom += 1.0F;
RectClass uv_rect = HILIGHT_UVS;
uv_rect.Inverse_Scale (Vector2 (256.0F, 256.0F));
ButtonRenderers[1].Add_Quad (hilight_rect, uv_rect);
//
// "Patch" fill the interior
//
/*y_pos = Rect.Top + height;
remaining_height = Rect.Height () - (height * 2);
while (remaining_height > 0) {
x_pos = Rect.Left + edge_width;
remaining_width = Rect.Width () - (edge_width * 2);
while (remaining_width > 0) {
Vector2 size (8, 8);
size.X = min (remaining_width, size.X);
size.Y = min (remaining_height, size.Y);
::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, y_pos), Vector2 ((right / 2) - 4, (bottom / 2) - 4),
size, texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (x_pos, y_pos), Vector2 ((right / 2) - 4, dn_start + (bottom / 2) - 4),
size, texture_dimensions);
remaining_width -= 8;
x_pos += 8;
}
remaining_height -= 8;
y_pos += 8;
}*/
ShaderClass *shader = ButtonRenderers[0].Get_Shader ();
shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE);
shader = ButtonRenderers[1].Get_Shader ();
shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Component_Button2
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Create_Component_Button2 (void)
{
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
ButtonRenderers[0].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
ButtonRenderers[1].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
//
// Turn off texturing on the UI background
//
ButtonRenderers[0].Enable_Texturing (false);
ButtonRenderers[1].Enable_Texturing (false);
const int BLACK = VRGB_TO_INT32 (Vector3 (0, 0, 0));
const int WHITE = VRGB_TO_INT32 (Vector3 (1, 1, 1));
const int DK_GRAY = VRGB_TO_INT32 (Vector3 (0.5F, 0.5F, 0.5F));
const int GRAY = VRGB_TO_INT32 (Vector3 (0.75F, 0.75F, 0.75F));
const int LT_GRAY = VRGB_TO_INT32 (Vector3 (0.9F, 0.9F, 0.9F));
//
// Draw the outside button outline
//
RectClass rect = Rect;
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, WHITE);
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, WHITE);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, BLACK);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, BLACK);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, BLACK);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, BLACK);
ButtonRenderers[1].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, WHITE);
ButtonRenderers[1].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, WHITE);
//
// Draw the inside button outline
//
rect.Inflate (Vector2 (-1, -1));
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, LT_GRAY);
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, LT_GRAY);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, DK_GRAY);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, DK_GRAY);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, DK_GRAY);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, DK_GRAY);
//
// Fill the button center
//
rect.Right -= 1;
rect.Bottom -= 1;
ButtonRenderers[0].Add_Quad (rect, GRAY);
ButtonRenderers[1].Add_Quad (rect, GRAY);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderers
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Create_Text_Renderers (void)
{
TextRenderer.Reset ();
GlowRenderer.Reset_Polys ();
//
// Draw the text
//
StyleMgrClass::Render_Text (Title, &TextRenderer, Rect, true, true, StyleMgrClass::CENTER_JUSTIFY, IsEnabled);
//
// Draw the glow effect
//
StyleMgrClass::Render_Glow (Title, &GlowRenderer, Rect, 8, 8,
StyleMgrClass::Get_Tab_Glow_Color (), StyleMgrClass::CENTER_JUSTIFY);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor if necessary
//
if (ClientRect.Contains (mouse_pos)) {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_Frame_Update (void)
{
DialogControlClass::On_Frame_Update ();
//
// Get the current mouse position
//
Vector3 complete_mouse_pos = DialogMgrClass::Get_Mouse_Pos ();
Vector2 mouse_pos;
mouse_pos.X = complete_mouse_pos.X;
mouse_pos.Y = complete_mouse_pos.Y;
//
// Update the pulse (as necessary)
//
if (ClientRect.Contains (mouse_pos)) {
Update_Pulse (true);
} else {
Update_Pulse (false);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
WasButtonPressedOnMe = false;
IsMouseOverMe = false;
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
ButtonCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
switch (key_id)
{
case VK_RETURN:
case VK_SPACE:
Parent->On_Command (ID, BN_CLICKED, 0);
//
// Play the sound effect
//
StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MOUSE_CLICK);
return true;
break;
}
return false;
}
////////////////////////////////////////////////////////////////
//
// Set_Bitmap
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Set_Bitmap (const char *texture_up_name, const char *texture_dn_name)
{
//
// Configure the up bitmap
//
TextureClass *texture_up = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_up_name, TextureClass::MIP_LEVELS_1);
ButtonRenderers[0].Set_Texture (texture_up);
//
// Configure the down bitmap
//
if (texture_dn_name != NULL && texture_dn_name[0] != 0) {
TextureClass *texture_dn = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_dn_name, TextureClass::MIP_LEVELS_1);
ButtonRenderers[1].Set_Texture (texture_dn);
REF_PTR_RELEASE (texture_dn);
} else {
ButtonRenderers[1].Set_Texture (texture_up);
}
REF_PTR_RELEASE (texture_up);
//
// Force the bitmap style on...
//
Style |= BS_BITMAP;
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Pulse
//
////////////////////////////////////////////////////////////////
void
ButtonCtrlClass::Update_Pulse (bool is_mouse_over)
{
const int PULSE_LEN = 1000;
int color;
//
// Short circuit if there's nothing to do
//
if (PulseTime == PULSE_LEN && is_mouse_over == false) {
return ;
}
if (IsEnabled) {
if (is_mouse_over) {
//
// Examine the current time to determine what
// percent of the "pulse" we are at
//
PulseTime -= DialogMgrClass::Get_Frame_Time ();
if (PulseTime < 0) {
PulseTime += PULSE_LEN;
}
float percent = (float)PulseTime / (float)PULSE_LEN;
//
// Map the percent onto a circle to give us a pulse
//
float value = ::cos (DEG_TO_RADF (360.0F) * percent);
value = 0.8F + (value * 0.2F);
//
// Convert this value into a grayscale color
//
color = VRGB_TO_INT32 (Vector3 (value, value, value));
} else {
color = RGB_TO_INT32 (0xff, 0xff, 0xff);
PulseTime = PULSE_LEN;
}
} else {
color = RGB_TO_INT32 (0x60, 0x60, 0x60);
}
//
// Update the color vector arrays
//
DynamicVectorClass<unsigned long> &color_array = ButtonRenderers[0].Get_Color_Array ();
for (int index = 0; index < color_array.Count (); index ++) {
color_array[index] = color;
}
DynamicVectorClass<unsigned long> &color_array2 = ButtonRenderers[1].Get_Color_Array ();
for (index = 0; index < color_array2.Count (); index ++) {
color_array2[index] = color;
}
return ;
}

127
Code/wwui/buttonctrl.h Normal file
View File

@@ -0,0 +1,127 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/buttonctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/26/01 10:20a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __BUTTON_CTRL_H
#define __BUTTON_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
////////////////////////////////////////////////////////////////
//
// ButtonCtrlClass
//
////////////////////////////////////////////////////////////////
class ButtonCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ButtonCtrlClass (void);
virtual ~ButtonCtrlClass (void) {}
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
// RTTI.
virtual ButtonCtrlClass *As_ButtonCtrlClass (void) { return this; }
//
// From DialogControlClass
//
void Render (void);
//
// Bitmap access
//
void Set_Bitmap (const char *texture_up, const char *texture_dn);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Create (void);
void On_Kill_Focus (DialogControlClass *focus);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Frame_Update (void);
void Create_Bitmap_Button (void);
void Create_Component_Button (void);
void Create_Component_Button2 (void);
void Create_Vector_Button (void);
void Create_Text_Renderers (void);
void Update_Pulse (bool is_mouse_over);
////////////////////////////////////////////////////////////////
// Protected constants
////////////////////////////////////////////////////////////////
enum
{
UP = 0,
DOWN,
STATE_MAX
};
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass GlowRenderer;
Render2DSentenceClass TextRenderer;
Render2DClass ButtonRenderers[STATE_MAX];
bool WasButtonPressedOnMe;
bool IsMouseOverMe;
bool IsBitmapMode;
int PulseTime;
};
#endif //__BUTTON_CTRL_H

410
Code/wwui/checkboxctrl.cpp Normal file
View File

@@ -0,0 +1,410 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/checkboxctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 12/05/01 4:22p $*
* *
* $Revision:: 18 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "checkboxctrl.h"
#include "assetmgr.h"
#include "refcount.h"
#include "font3d.h"
#include "mousemgr.h"
#include "ww3d.h"
#include "dialogmgr.h"
#include "dialogbase.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// CheckBoxCtrlClass
//
////////////////////////////////////////////////////////////////
CheckBoxCtrlClass::CheckBoxCtrlClass (void) :
TextRect (0, 0, 0, 0),
ButtonRect (0, 0, 0, 0),
MaxRect (0, 0, 0, 0),
IsChecked (false)
{
//
// Set the font for the text renderers
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_CONTROLS);
StyleMgrClass::Configure_Renderer (&ControlRenderer);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~CheckBoxCtrlClass
//
////////////////////////////////////////////////////////////////
CheckBoxCtrlClass::~CheckBoxCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderers
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::Create_Text_Renderers (void)
{
const float TEXT_SPACING = 8.0F;
//
// Configure the renderers
//
HilightRenderer.Reset ();
HilightRenderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
StyleMgrClass::Configure_Hilighter (&HilightRenderer);
//
// Determine how wide to make the text area
//
Vector2 extents = TextRenderer.Get_Text_Extents (Title);
float width = extents.X + (StyleMgrClass::Get_X_Scale () * TEXT_SPACING);
//
// Resize the text area to fit the text
//
TextRect.Right = TextRect.Left + width;
TextRect.Right = min (TextRect.Right, MaxRect.Right);
Rect.Right = TextRect.Right;
//
// Start fresh
//
TextRenderer.Reset ();
//
// Draw the text
//
StyleMgrClass::Render_Text (Title, &TextRenderer, TextRect, true, true,
StyleMgrClass::LEFT_JUSTIFY, IsEnabled);
//
// Do the hilight
//
if (HasFocus) {
StyleMgrClass::Render_Hilight (&HilightRenderer, TextRect);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Control_Renderers
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::Create_Control_Renderers (void)
{
Render2DClass &renderer = ControlRenderer;
//
// Configure this renderer
//
renderer.Reset ();
renderer.Enable_Texturing (false);
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
}
//
// Draw the button outline
//
RectClass rect = ButtonRect;
renderer.Add_Outline (ButtonRect, 1.0F, color);
//
// Now draw the background
//
rect.Right -= 1;
rect.Bottom -= 1;
renderer.Add_Quad (rect, bkcolor);
//
// Draw the check (if necessary)
//
if (IsChecked) {
int text_color = StyleMgrClass::Get_Text_Color ();
int shadow_color = StyleMgrClass::Get_Text_Shadow_Color ();
if (IsEnabled == false) {
text_color = StyleMgrClass::Get_Disabled_Text_Color ();
shadow_color = StyleMgrClass::Get_Disabled_Text_Shadow_Color ();
}
rect = ButtonRect;
rect.Inflate (Vector2 (-5, -5));
renderer.Add_Line (Vector2 (rect.Left-1, rect.Top+1), Vector2 (rect.Right-2, rect.Bottom+1), 2, shadow_color);
renderer.Add_Line (Vector2 (rect.Left-1, rect.Bottom+1), Vector2 (rect.Right-2, rect.Top+1), 2, shadow_color);
renderer.Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right-1, rect.Bottom), 2, text_color);
renderer.Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Right-1, rect.Top), 2, text_color);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor
//
if (Rect.Contains (mouse_pos) && mouse_pos.X <= TextRect.Right) {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
} else {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ARROW);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::Update_Client_Rect (void)
{
//
// Determine what one character spacing would be
//
Vector2 char_size = TextRenderer.Get_Text_Extents (L"W");
//
// Set the client area
//
MaxRect = Rect;
ClientRect = Rect;
//
// Determine what size the button should be
//
float button_width = int(char_size.X * 1.5F);
float button_height = button_width;
//
// Calculate the button rectangle
//
ButtonRect.Left = ClientRect.Left;
ButtonRect.Top = ClientRect.Top + int((ClientRect.Height () / 2.0F) - (button_height / 2.0F));
ButtonRect.Right = ButtonRect.Left + button_width;
ButtonRect.Bottom = ClientRect.Top + int((ClientRect.Height () / 2.0F) + (button_height / 2.0F));
//
// Calculate the text rectangle
//
TextRect.Left = int(ButtonRect.Right + (char_size.X * 0.5F));
TextRect.Top = ClientRect.Top;
TextRect.Right = ClientRect.Right;
TextRect.Bottom = ClientRect.Bottom;
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderers ();
Create_Text_Renderers ();
}
//
// Render the background and text for the current state
//
ControlRenderer.Render ();
TextRenderer.Render ();
HilightRenderer.Render ();
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Check
//
////////////////////////////////////////////////////////////////
void CheckBoxCtrlClass::Set_Check (bool onoff)
{
Internal_Set_Check(onoff, false);
}
void CheckBoxCtrlClass::Internal_Set_Check(bool onoff, bool notify)
{
IsChecked = onoff;
Set_Dirty ();
if (notify) {
Parent->On_Command (Get_ID (), 0, onoff);
}
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
Internal_Set_Check (!IsChecked, true);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Focus
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::On_Set_Focus (void)
{
Set_Dirty ();
DialogControlClass::On_Set_Focus ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
Set_Dirty ();
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
CheckBoxCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
bool handled = false;
bool is_dirty = true;
switch (key_id)
{
case VK_SPACE:
Internal_Set_Check (!IsChecked, true);
handled = true;
break;
default:
is_dirty = false;
break;
}
if (is_dirty) {
Set_Dirty ();
}
return handled;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
CheckBoxCtrlClass::On_Create (void)
{
return ;
}

117
Code/wwui/checkboxctrl.h Normal file
View File

@@ -0,0 +1,117 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/checkboxctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 12/05/01 4:20p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __CHECKBOX_CTRL_H
#define __CHECKBOX_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
#include "bittype.h"
////////////////////////////////////////////////////////////////
//
// CheckBoxCtrlClass
//
////////////////////////////////////////////////////////////////
class CheckBoxCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
CheckBoxCtrlClass (void);
virtual ~CheckBoxCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// RTTI
//
CheckBoxCtrlClass * As_CheckBoxCtrlClass (void) { return this; }
//
// From DialogControlClass
//
void Render (void);
//
// Selection management
//
void Set_Check (bool onoff);
bool Get_Check (void) const { return IsChecked; }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Internal_Set_Check(bool onoff, bool notify);
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *focus);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Create (void);
void Update_Client_Rect (void);
void Create_Control_Renderers (void);
void Create_Text_Renderers (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DClass ControlRenderer;
Render2DClass HilightRenderer;
bool IsChecked;
RectClass ButtonRect;
RectClass TextRect;
RectClass MaxRect;
};
#endif //__CHECKBOX_CTRL_H

116
Code/wwui/childdialog.cpp Normal file
View File

@@ -0,0 +1,116 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/childdialog.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 4/16/01 8:20a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "childdialog.h"
#include "assetmgr.h"
#include "texture.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// ChildDialogClass
//
////////////////////////////////////////////////////////////////
ChildDialogClass::ChildDialogClass (int res_id) :
ParentDialog (NULL),
DialogBaseClass (res_id)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// ~ChildDialogClass
//
////////////////////////////////////////////////////////////////
ChildDialogClass::~ChildDialogClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Init_Dialog
//
////////////////////////////////////////////////////////////////
void
ChildDialogClass::On_Init_Dialog (void)
{
DialogBaseClass::On_Init_Dialog ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
ChildDialogClass::Render (void)
{
//
// Only render the controls... don't render any
// backdrop or border.
//
DialogBaseClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Is_Active
//
////////////////////////////////////////////////////////////////
bool
ChildDialogClass::Is_Active (void)
{
bool retval = false;
//
// We are automatically active if our parent is active
//
if (IsVisible && ParentDialog != NULL && ParentDialog->Is_Active ()) {
//retval = true;
}
return retval;
}

121
Code/wwui/childdialog.h Normal file
View File

@@ -0,0 +1,121 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/childdialog.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 7/17/01 5:37p $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __CHILD_DIALOG_H
#define __CHILD_DIALOG_H
#include "dialogbase.h"
#include "wwstring.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//
// ChildDialogClass
//
////////////////////////////////////////////////////////////////
class ChildDialogClass : public DialogBaseClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ChildDialogClass (int res_id);
virtual ~ChildDialogClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// RTTI
//
virtual ChildDialogClass * As_ChildDialogClass (void) { return this; }
//
// From DialogBaseClass
//
virtual void Render (void);
virtual bool Is_Active (void);
virtual bool Wants_Activation (void) { return false; }
//
// Parent dialog access
//
void Set_Parent_Dialog (DialogBaseClass *dialog) { ParentDialog = dialog; }
DialogBaseClass * Get_Parent_Dialog (void) const { return ParentDialog; }
//
// Data management
//
// Note: Returning false from either method will keep
// the dialog from advancing.
//
virtual bool On_Apply (void) { return true; }
virtual bool On_Discard (void) { return true; }
virtual void On_Reload (void) { }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
//
// From DialogBaseClass
//
virtual void On_Init_Dialog (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
DialogBaseClass * ParentDialog;
};
#endif //__CHILD_DIALOG_H

791
Code/wwui/comboboxctrl.cpp Normal file
View File

@@ -0,0 +1,791 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/comboboxctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/10/02 12:30p $*
* *
* $Revision:: 25 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "comboboxctrl.h"
#include "assetmgr.h"
#include "refcount.h"
#include "font3d.h"
#include "mousemgr.h"
#include "ww3d.h"
#include "dialogmgr.h"
#include "dialogbase.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// ComboBoxCtrlClass
//
////////////////////////////////////////////////////////////////
ComboBoxCtrlClass::ComboBoxCtrlClass (void) :
WasButtonPressedOnMe (false),
IsDropDownDisplayed (false),
TextRect (0, 0, 0, 0),
ButtonRect (0, 0, 0, 0),
FullRect (0, 0, 0, 0),
DropDownSize (0, 0),
IsInitialized (false),
LastDropDownDisplayChange (0),
CurrSel(-1)
{
//
// Set the font for the text renderers
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_LISTS);
StyleMgrClass::Configure_Renderer (&ControlRenderer);
//
// Configure the hilight renderer
//
StyleMgrClass::Configure_Renderer (&HilightRenderer);
//
// Let the drop down know who its parent is
//
DropDownCtrl.Set_Combo_Box (this);
DropDownCtrl.Set_Is_Embedded (true);
EditControl.Set_Is_Embedded (true);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~ComboBoxCtrlClass
//
////////////////////////////////////////////////////////////////
ComboBoxCtrlClass::~ComboBoxCtrlClass (void)
{
return ;
}
void ComboBoxCtrlClass::Set_Style(DWORD style)
{
DialogControlClass::Set_Style(style);
if ((style & CBS_OEMCONVERT) != 0) {
EditControl.Set_Style(ES_OEMCONVERT);
} else {
EditControl.Set_Style(0);
}
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderers
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Create_Text_Renderers (void)
{
if ((Style & 0x0F) == CBS_DROPDOWN) {
return;
}
HilightRenderer.Reset ();
HilightRenderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution ());
StyleMgrClass::Configure_Hilighter (&HilightRenderer);
//
// Lookup the string to display
//
WideStringClass display_string(255, true);
DropDownCtrl.Get_String (DropDownCtrl.Get_Curr_Sel(), display_string);
//
// Setup this renderer
//
Render2DSentenceClass &renderer = TextRenderer;
renderer.Reset ();
//
// Draw the text
//
StyleMgrClass::Render_Text (display_string, &renderer, TextRect, true, true,
StyleMgrClass::LEFT_JUSTIFY, IsEnabled);
//
// Do the hilight
//
if (HasFocus && IsEnabled) {
StyleMgrClass::Render_Hilight (&HilightRenderer, TextRect);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Control_Renderers
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Create_Control_Renderers (void)
{
Render2DClass &renderer = ControlRenderer;
//
// Configure this renderer
//
renderer.Reset ();
renderer.Enable_Texturing (false);
renderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
}
//
// Draw the control outline
//
RectClass rect = ClientRect;
renderer.Add_Outline (rect, 1.0F, color);
//
// Now draw the background
//
rect.Right -= 1;
rect.Bottom -= 1;
renderer.Add_Quad (rect, bkcolor);
//
// Draw the button
//
rect = ButtonRect;
renderer.Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, color);
float width = int(ButtonRect.Width () / 4);
float height = int(ButtonRect.Height () / 4);
float center_x = int(ButtonRect.Left + (ButtonRect.Width () / 2));
float center_y = int(ButtonRect.Top + (ButtonRect.Height () / 2));
renderer.Add_Line (Vector2 (center_x - width, center_y - height), Vector2 (center_x + width, center_y - height), 1, color);
renderer.Add_Line (Vector2 (center_x + width, center_y - height), Vector2 (center_x, center_y + height), 1, color);
renderer.Add_Line (Vector2 (center_x, center_y + height), Vector2 (center_x - width, center_y - height), 1, color);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor if necessary
//
if (ClientRect.Contains (mouse_pos)) {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Window_Pos
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Set_Window_Pos (const Vector2 &pos)
{
float width = FullRect.Width ();
float height = FullRect.Height ();
//
// Recalculate the window's bounding rectangle
//
FullRect.Left = (int)pos.X;
FullRect.Top = (int)pos.Y;
FullRect.Right = (int)(FullRect.Left + width);
FullRect.Bottom = (int)(FullRect.Top + height);
//
// Let the control recalculate anything it needs
//
DialogControlClass::Set_Window_Pos (pos);
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Update_Client_Rect (void)
{
if (IsInitialized == false) {
FullRect = Rect;
IsInitialized = true;
}
//
// Determine what one character spacing would be
//
Vector2 char_size = TextRenderer.Get_Text_Extents (L"W");
float border_width = char_size.X + 2;
float border_height = 2;
float button_height = int(char_size.Y * 2.0F);
float button_width = button_height;
//
// Shrink the client area
//
ClientRect = Rect;
ClientRect.Bottom = ClientRect.Top + button_height;
//
// Remember how much space we have for the drop down control
//
DropDownSize.X = int(ClientRect.Width ());
DropDownSize.Y = int(FullRect.Bottom - ClientRect.Bottom);
//
// Calculate the bounding rectangle for the drop-down control
//
RectClass drop_down_rect;
drop_down_rect.Left = ClientRect.Left;
drop_down_rect.Top = ClientRect.Bottom;
drop_down_rect.Right = drop_down_rect.Left + DropDownSize.X;
drop_down_rect.Bottom = drop_down_rect.Top + DropDownSize.Y;
//
// Should the drop-down, go down or up?
//
RectClass screen_rect = Render2DClass::Get_Screen_Resolution ();
if (drop_down_rect.Bottom > screen_rect.Bottom) {
drop_down_rect.Bottom = ClientRect.Top;
drop_down_rect.Top = drop_down_rect.Bottom - DropDownSize.Y;
}
//
// Configure the drop-down control
//
DropDownCtrl.Set_Full_Rect (drop_down_rect);
DropDownCtrl.Set_Window_Rect (drop_down_rect);
//
// Make the window rect and the client rect the same
//
Rect = ClientRect;
//
// Calculate where the button is located
//
ButtonRect = ClientRect;
ButtonRect.Left = ClientRect.Right - button_width;
ButtonRect.Bottom = ClientRect.Top + button_height;
//
// Calculate the area the text can render into
//
TextRect = ClientRect;
TextRect.Top += border_height;
TextRect.Left += border_width;
TextRect.Right = ButtonRect.Left - border_width;
TextRect.Bottom = ButtonRect.Bottom - border_height;
RectClass editRect = ClientRect;
editRect.Right = ButtonRect.Left;
editRect.Bottom = ButtonRect.Bottom;
EditControl.Set_Window_Rect(editRect);
// If this is a dropdown then make the controls rect only cover the button.
// The edit control will handle the rest of the control orginal area.
if ((Style & 0x0F) == CBS_DROPDOWN) {
ClientRect = ButtonRect;
Rect = ButtonRect;
}
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderers ();
Create_Text_Renderers ();
}
//
// Render the background and text for the current state
//
ControlRenderer.Render ();
TextRenderer.Render ();
HilightRenderer.Render ();
//
// Check to see if the mouse button is still down
//
WasButtonPressedOnMe &= DialogMgrClass::Is_Button_Down (VK_LBUTTON);
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
if (HasFocus) {
WasButtonPressedOnMe = true;
}
// Display_Drop_Down (true);
Display_Drop_Down(!IsDropDownDisplayed);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
//
// Reset our flags
//
WasButtonPressedOnMe = false;
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Move
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Focus
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Set_Focus (void)
{
Set_Dirty ();
//
// Set the focus to the edit control if we are in that mode
//
/*if ((Style & 0x0F) == CBS_DROPDOWN) {
DialogMgrClass::Set_Focus(&EditControl);
}*/
DialogControlClass::On_Set_Focus ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
Set_Dirty ();
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
ComboBoxCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
bool handled = false;
bool is_dirty = true;
switch (key_id)
{
case VK_HOME:
Set_Sel (0, true);
break;
case VK_END:
Set_Sel (DropDownCtrl.Get_Count () - 1, true);
break;
case VK_UP:
case VK_LEFT:
Set_Sel (max<int>(0, (DropDownCtrl.Get_Curr_Sel () - 1)), true);
break;
case VK_DOWN:
case VK_RIGHT:
Set_Sel (DropDownCtrl.Get_Curr_Sel () + 1, true);
break;
default:
is_dirty = false;
handled = false;
break;
}
if (is_dirty) {
Set_Dirty ();
}
return handled;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Create (void)
{
if ((Style & 0x0F) == CBS_DROPDOWN) {
Parent->Add_Control(&EditControl);
Set_Wants_Focus(false);
EditControl.Set_Advise_Sink(this);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Destroy
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Destroy (void)
{
Parent->Remove_Control(&DropDownCtrl);
Parent->Remove_Control(&EditControl);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Drop_Down_End
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Drop_Down_End (int curr_sel)
{
Set_Sel(curr_sel, true);
// Hide the drop down
Display_Drop_Down (false);
//
// If we aren't embedding an edit control, then we
// need to focus after the drop down exits
//
if ((Style & 0x0F) != CBS_DROPDOWN) {
Set_Focus ();
} else {
EditControl.Set_Focus ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Display_Drop_Down
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Display_Drop_Down (bool onoff)
{
int curr_time = DialogMgrClass::Get_Time ();
if (onoff) {
//
// Show the drop down control
//
if (IsDropDownDisplayed == false && (curr_time - LastDropDownDisplayChange) > 0.1F) {
Parent->Add_Control (&DropDownCtrl);
DropDownCtrl.Set_Focus ();
IsDropDownDisplayed = true;
LastDropDownDisplayChange = curr_time;
if ((Style & 0x0F) == CBS_DROPDOWN) {
WideStringClass text(255, true);
text = EditControl.Get_Text();
int index = DropDownCtrl.Find_Closest_String(text);
Set_Sel(index, true);
}
}
} else {
//
// Hide the drop down
//
if (IsDropDownDisplayed) {
Parent->Remove_Control (&DropDownCtrl);
IsDropDownDisplayed = false;
LastDropDownDisplayChange = curr_time;
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Wheel
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_Mouse_Wheel (int direction)
{
if (direction < 0) {
Set_Sel (max<int>(0, (DropDownCtrl.Get_Curr_Sel () - 1)), true);
} else {
Set_Sel (DropDownCtrl.Get_Curr_Sel () + 1, true);
}
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Select_String
//
////////////////////////////////////////////////////////////////
int
ComboBoxCtrlClass::Select_String (const WCHAR* string)
{
int index = Find_String (string);
if (index >= 0) {
Set_Curr_Sel (index);
}
return index;
}
void ComboBoxCtrlClass::Delete_String(int index)
{
if (index >= 0 && index < DropDownCtrl.Get_Count()) {
DropDownCtrl.Delete_String(index);
CurrSel = -2;
int newSel = DropDownCtrl.Get_Curr_Sel();
Set_Sel(newSel, false);
}
}
////////////////////////////////////////////////////////////////
//
// Set_Curr_Sel
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Set_Curr_Sel (int index)
{
Set_Sel(index, false);
}
void
ComboBoxCtrlClass::Set_Sel (int index, bool notify)
{
if (CurrSel != index) {
DropDownCtrl.Set_Curr_Sel(index);
int newSel = DropDownCtrl.Get_Curr_Sel();
if (CurrSel != newSel) {
Set_Dirty();
// If this is a dropdown then automatically fill in the edit part with
// the new selection string.
if ((Style & 0x0F) == CBS_DROPDOWN) {
if (newSel >= 0) {
WideStringClass editString(255, true);
DropDownCtrl.Get_String(newSel, editString);
EditControl.Set_Text(editString);
} else {
EditControl.Set_Text(L"");
}
}
int oldSel = CurrSel;
CurrSel = newSel;
if (notify) {
ADVISE_NOTIFY(On_ComboBoxCtrl_Sel_Change(this, Get_ID(), oldSel, newSel));
}
}
}
}
////////////////////////////////////////////////////////////////
//
// Get_Text
//
////////////////////////////////////////////////////////////////
const WCHAR*
ComboBoxCtrlClass::Get_Text(void) const
{
if ((Style & 0x0F) == CBS_DROPDOWN) {
return EditControl.Get_Text();
}
return DropDownCtrl.Get_String(Get_Curr_Sel());
}
////////////////////////////////////////////////////////////////
//
// Set_Text
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::Set_Text (const WCHAR *title)
{
if ((Style & 0x0F) == CBS_DROPDOWN) {
EditControl.Set_Text (title);
}
DialogControlClass::Set_Text (title);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_EditCtrl_Key_Down
//
////////////////////////////////////////////////////////////////
void
ComboBoxCtrlClass::On_EditCtrl_Change(EditCtrlClass* edit, int)
{
if (edit == &EditControl) {
ADVISE_NOTIFY(On_ComboBoxCtrl_Edit_Change(this, Get_ID()));
}
}
////////////////////////////////////////////////////////////////
//
// On_EditCtrl_Key_Down
//
////////////////////////////////////////////////////////////////
bool
ComboBoxCtrlClass::On_EditCtrl_Key_Down (EditCtrlClass *edit, uint32 key_id, uint32 key_data)
{
if (edit != &EditControl) {
return false;
}
bool handled = true;
switch (key_id)
{
case VK_UP:
Set_Sel (max<int>(0, (DropDownCtrl.Get_Curr_Sel () - 1)), true);
break;
case VK_DOWN:
Set_Sel (DropDownCtrl.Get_Curr_Sel () + 1, true);
break;
default:
handled = false;
break;
}
return handled;
}

157
Code/wwui/comboboxctrl.h Normal file
View File

@@ -0,0 +1,157 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/comboboxctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/09/02 4:07p $*
* *
* $Revision:: 22 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __COMBOBOX_CTRL_H
#define __COMBOBOX_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
#include "bittype.h"
#include "dropdownctrl.h"
#include "EditCtrl.h"
////////////////////////////////////////////////////////////////
//
// ComboBoxCtrlClass
//
////////////////////////////////////////////////////////////////
class ComboBoxCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public friends
////////////////////////////////////////////////////////////////
friend class DropDownCtrlClass;
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ComboBoxCtrlClass (void);
virtual ~ComboBoxCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
const WCHAR * Get_Text (void) const;
void Set_Text (const WCHAR *title);
void Set_Window_Pos (const Vector2 &pos);
void Render (void);
void Set_Style(DWORD style);
//
// Content control
//
int Add_String (const WCHAR* string) { return DropDownCtrl.Add_String (string); }
void Delete_String (int index);
int Find_String (const WCHAR* string) { return DropDownCtrl.Find_String (string); }
int Select_String (const WCHAR* string);
void Set_Item_Data (int index, uint32 data) { DropDownCtrl.Set_Item_Data (index, data); Set_Dirty();}
uint32 Get_Item_Data (int index) { return DropDownCtrl.Get_Item_Data (index); }
void Reset_Content (void) { DropDownCtrl.Reset_Content (); }
bool Get_String (int index, WideStringClass &string) { return DropDownCtrl.Get_String (index, string); }
int Get_Item_Count(void) {return DropDownCtrl.Get_Count();}
//
// Selection management
//
void Set_Curr_Sel (int index);
int Get_Curr_Sel (void) const { return CurrSel; }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Set_Sel (int index, bool notify);
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *focus);
void On_Mouse_Wheel (int direction);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Create (void);
void On_Destroy (void);
void Update_Client_Rect (void);
void Create_Control_Renderers (void);
void Create_Text_Renderers (void);
void Display_Drop_Down (bool onoff);
//
// Notifications
//
void On_Drop_Down_End (int curr_sel);
void On_EditCtrl_Change(EditCtrlClass* edit_ctrl, int ctrl_id);
bool On_EditCtrl_Key_Down(EditCtrlClass* edit_ctrl, uint32 key_id, uint32 key_data);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DClass ControlRenderer;
Render2DClass HilightRenderer;
bool IsDropDownDisplayed;
int CurrState;
RectClass ButtonRect;
RectClass TextRect;
RectClass FullRect;
Vector2 DropDownSize;
bool WasButtonPressedOnMe;
bool IsInitialized;
DropDownCtrlClass DropDownCtrl;
int LastDropDownDisplayChange;
int CurrSel;
EditCtrlClass EditControl;
};
#endif //__COMBOBOX_CTRL_H

View File

@@ -0,0 +1,158 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/controladvisesink.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/15/02 5:34p $*
* *
* $Revision:: 20 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __CONTROL_ADVISE_SINK_H
#define __CONTROL_ADVISE_SINK_H
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class DialogControlClass;
class ScrollBarCtrlClass;
class ListCtrlClass;
class MapCtrlClass;
class ViewerCtrlClass;
class RenderObjClass;
class Vector3;
class InputCtrlClass;
class SliderCtrlClass;
class EditCtrlClass;
class ComboBoxCtrlClass;
class MerchandiseCtrlClass;
class TreeCtrlClass;
class TreeItemClass;
////////////////////////////////////////////////////////////////
//
// ControlAdviseSinkClass
//
// This is an abstrct base class that defines an interface
// which dialog controls can communicate state/activation
// changes via.
//
////////////////////////////////////////////////////////////////
class ControlAdviseSinkClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ControlAdviseSinkClass (void) {}
virtual ~ControlAdviseSinkClass (void) {}
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Generic callbacks
//
virtual bool On_Command (DialogControlClass *control, int ctrl_id, int param1, int param2) { return false; }
//
// Scrollbar callbacks
//
virtual void On_VScroll (ScrollBarCtrlClass *scrollbar, int ctrl_id, int new_position) {}
virtual void On_VScroll_Page (ScrollBarCtrlClass *scrollbar, int ctrl_id, int direction) {}
//
// List control callbacks
//
virtual void On_ListCtrl_Delete_Entry (ListCtrlClass *list_ctrl, int ctrl_id, int item_index) {}
virtual void On_ListCtrl_Column_Click (ListCtrlClass *list_ctrl, int ctrl_id, int col_index) {}
virtual void On_ListCtrl_DblClk (ListCtrlClass *list_ctrl, int ctrl_id, int item_index) {}
virtual void On_ListCtrl_Sel_Change (ListCtrlClass *list_ctrl, int ctrl_id, int old_index, int new_index) {}
virtual void On_ListCtrl_Mouse_Over (ListCtrlClass *list_ctrl, int ctrl_id, int index) {}
//
// Tree control callbacks
virtual void On_TreeCtrl_Expand_Item (TreeCtrlClass *list_ctrl, int ctrl_id, TreeItemClass *item) {}
virtual void On_TreeCtrl_Delete_Item (TreeCtrlClass *list_ctrl, int ctrl_id, TreeItemClass *item) {}
virtual void On_TreeCtrl_Sel_Change (TreeCtrlClass *list_ctrl, int ctrl_id, TreeItemClass *old_item, TreeItemClass *new_item) {}
virtual void On_TreeCtrl_Needs_Children (TreeCtrlClass *list_ctrl, int ctrl_id, TreeItemClass *parent_item) {}
//
// Map control callbacks
//
virtual void On_MapCtrl_Marker_Hilighted (MapCtrlClass *map_ctrl, int ctrl_id, int marker_index) {}
virtual void On_MapCtrl_Marker_Clicked (MapCtrlClass *map_ctrl, int ctrl_id, int marker_index) {}
virtual void On_MapCtrl_Pos_Clicked (MapCtrlClass *map_ctrl, int ctrl_id, const Vector3 &pos) {}
//
// Viewer control callbacks
//
virtual void On_ViewerCtrl_Model_Loaded (ViewerCtrlClass *viewer_ctrl, int ctrl_id, RenderObjClass *model) {}
//
// Input control callbacks
//
virtual bool On_InputCtrl_Get_Key_Info (InputCtrlClass *viewer_ctrl, int ctrl_id, int vkey_id, WideStringClass &key_name, int *game_key_id) { return false; }
//
// Slider control callbacks
//
virtual void On_SliderCtrl_Pos_Changed (SliderCtrlClass *slider_ctrl, int ctrl_id, int new_pos) {}
//
// Edit control callbacks
//
virtual void On_EditCtrl_Enter_Pressed (EditCtrlClass *edit_ctrl, int ctrl_id) {}
virtual bool On_EditCtrl_Key_Down(EditCtrlClass *edit_ctrl, uint32 key_id, uint32 key_data) {return false;}
virtual void On_EditCtrl_Change(EditCtrlClass *edit_ctrl, int ctrl_id) {}
//
// Combo control callbacks
//
virtual void On_ComboBoxCtrl_Sel_Change (ComboBoxCtrlClass *combo_ctrl, int ctrl_id, int old_sel, int new_sel) {}
virtual void On_ComboBoxCtrl_Edit_Change (ComboBoxCtrlClass *combo_ctrl, int ctrl_id) {}
//
// Merchandise control callbacks
//
virtual void On_Merchandise_Selected (MerchandiseCtrlClass *ctrl, int ctrl_id) {}
virtual void On_Merchandise_DblClk (MerchandiseCtrlClass *ctrl, int ctrl_id) {}
};
#endif //__CONTROL_ADVISE_SINK_H

1640
Code/wwui/dialogbase.cpp Normal file

File diff suppressed because it is too large Load Diff

293
Code/wwui/dialogbase.h Normal file
View File

@@ -0,0 +1,293 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogbase.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 12/03/01 5:09p $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_BASE_H
#define __DIALOG_BASE_H
#include "vector.h"
#include "vector3.h"
#include "rect.h"
#include "refcount.h"
#include "bittype.h"
#include "widestring.h"
#include "controladvisesink.h"
#include "win.h"
#include "notify.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class DialogControlClass;
class MenuDialogClass;
class PopupDialogClass;
class ChildDialogClass;
class DialogBaseClass;
class DialogTransitionClass;
////////////////////////////////////////////////////////////////
// Usefull Macros
////////////////////////////////////////////////////////////////
#define START_DIALOG(class_name) \
{ class_name *dialog = new class_name; \
dialog->Start_Dialog (); \
REF_PTR_RELEASE (dialog); }
////////////////////////////////////////////////////////////////
// Typedefs
////////////////////////////////////////////////////////////////
typedef bool (CALLBACK *DEFAULT_DLG_CMD_HANDLER) (DialogBaseClass *dialog, int ctrl_id, int mesage_id, DWORD param);
class DialogEvent :
public TypedEventPtr<DialogEvent, DialogBaseClass>
{
public:
typedef enum
{
STARTED = 1,
DESTROY,
ACTIVATED,
DEACTIVATED,
} EventID;
//! Retrieve event
inline EventID GetEventID(void) const
{return mEvent;}
DialogEvent(EventID event, DialogBaseClass* dialog) :
TypedEventPtr<DialogEvent, DialogBaseClass>(dialog),
mEvent(event)
{}
private:
EventID mEvent;
};
////////////////////////////////////////////////////////////////
//
// DialogBaseClass
//
// These dialogs are analagous to Windows dialogs. They are
// initialized from an RC file, however the dialog template is
// only parsed - the window isn't actually created.
//
////////////////////////////////////////////////////////////////
class DialogBaseClass : public RefCountClass, public ControlAdviseSinkClass,
public Notifier<DialogEvent>
{
public:
////////////////////////////////////////////////////////////////
// Public friends
////////////////////////////////////////////////////////////////
friend class DialogMgrClass;
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
DialogBaseClass (int res_id);
virtual ~DialogBaseClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// RTTI
//
virtual MenuDialogClass * As_MenuDialogClass (void) { return NULL; }
virtual PopupDialogClass * As_PopupDialogClass (void) { return NULL; }
virtual ChildDialogClass * As_ChildDialogClass (void) { return NULL; }
int Get_Dlg_ID(void) const {return DialogResID;}
//
// Display methods
//
virtual void Render (void);
void Show (bool onoff) { IsVisible = onoff; }
bool Is_Visible (void) const { return IsVisible; }
void Set_Dirty(bool onoff=true);
//
// Position control
//
const RectClass & Get_Rect (void) const { return Rect; }
void Set_Rect (const RectClass &rect);
//
// Flow control
//
virtual void Start_Dialog (void);
virtual void End_Dialog (void);
virtual bool Is_Running (void) { return IsRunning; }
//
// Control access
//
DialogControlClass * Get_Dlg_Item (int id) const;
DialogControlClass * Find_Control (const Vector2 &mouse_pos);
void Add_Control (DialogControlClass *control);
void Remove_Control (DialogControlClass *control);
DialogControlClass * Find_Next_Control (DialogControlClass *control, int direction = 1);
DialogControlClass * Find_Next_Group_Control (DialogControlClass *control, int direction = 1);
int Get_Control_Count (void) const { return ControlList.Count (); }
DialogControlClass * Get_Control (int index) const { return ControlList[index]; }
//
// Control enable state access
//
void Enable_Dlg_Item (int id, bool onoff);
bool Is_Dlg_Item_Enabled (int id);
//
// Control text access
//
const WCHAR * Get_Dlg_Item_Text (int id) const;
void Set_Dlg_Item_Text (int id, const WCHAR *text);
int Get_Dlg_Item_Int (int id) const;
void Set_Dlg_Item_Int (int id, int value);
float Get_Dlg_Item_Float (int id) const;
void Set_Dlg_Item_Float (int id, float value);
//
// Control "check" access
//
void Check_Dlg_Button (int id, bool onoff);
bool Is_Dlg_Button_Checked (int id) const;
//
// Child dialog access
//
void Add_Child_Dialog (ChildDialogClass *child);
void Remove_Child_Dialog (ChildDialogClass *child);
//
// Title access
//
void Get_Title (WideStringClass *title) { *title = Title; }
void Set_Title (const WCHAR *title) { Title = title; }
//
// Activation access
//
virtual bool Is_Active (void);
virtual bool Wants_Activation (void) { return true; }
//
// Transition control
//
virtual DialogTransitionClass * Get_Transition_In (DialogBaseClass *prev_dlg) { return NULL; }
virtual DialogTransitionClass * Get_Transition_Out (DialogBaseClass *next_dlg) { return NULL; }
virtual void Set_Controls_Hidden (bool onoff) { AreControlsHidden = onoff; }
virtual bool Are_Controls_Hidden (void) const { return AreControlsHidden; }
//
// Notifications
//
virtual void On_Command (int ctrl_id, int mesage_id, DWORD param);
//
// Default processing support
//
static void Set_Default_Command_Handler (DEFAULT_DLG_CMD_HANDLER ptr) { DefaultCmdHandler = ptr; }
static DEFAULT_DLG_CMD_HANDLER Get_Default_Command_Handler (void) { return DefaultCmdHandler; }
DECLARE_NOTIFIER(DialogEvent)
protected:
////////////////////////////////////////////////////////////////
// Protected typedefs
////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<DialogControlClass *> CONTROL_LIST;
typedef DynamicVectorClass<ChildDialogClass *> DIALOG_LIST;
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
virtual void On_Init_Dialog (void);
virtual void On_Destroy (void) {}
virtual void On_Activate (bool onoff);
virtual bool On_Key_Down (uint32 key_id, uint32 key_data);
virtual void On_Unicode_Char(uint16 unicode);
virtual void On_Mouse_Wheel (int direction);
virtual bool On_Key_Up (uint32 key_id);
virtual void On_Frame_Update (void);
virtual void On_Periodic (void) {}
void Free_Controls (void);
void Update_Mouse_State (void);
int Find_Focus_Control (void);
int Find_Control_Index (DialogControlClass *control);
void Send_Mouse_Input (DialogControlClass *control, const Vector2 &mouse_pos);
void Build_Control_List (CONTROL_LIST &list);
void Set_Default_Focus (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
WideStringClass Title;
RectClass Rect;
int DialogResID;
CONTROL_LIST ControlList;
DIALOG_LIST ChildDialogList;
DialogControlClass * LastFocusControl;
bool IsVisible;
bool AreControlsHidden;
bool IsRunning;
int LastMouseClickTime;
static DEFAULT_DLG_CMD_HANDLER DefaultCmdHandler;
};
#endif //__DIALOG_BASE_H

516
Code/wwui/dialogbutton.cpp Normal file
View File

@@ -0,0 +1,516 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogbutton.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/11/01 3:58p $*
* *
* $Revision:: 10 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dialogbutton.h"
#include "assetmgr.h"
#include "font3d.h"
#include "dialogbase.h"
#include "mousemgr.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// DialogButtonClass
//
////////////////////////////////////////////////////////////////
DialogButtonClass::DialogButtonClass (void) :
WasButtonPressedOnMe (false),
IsMouseOverMe (false)
{
//
// Set the font for the text renderer
//
StyleMgrClass::Assign_Font (&TextRenderers[0], StyleMgrClass::FONT_CONTROLS);
StyleMgrClass::Assign_Font (&TextRenderers[1], StyleMgrClass::FONT_CONTROLS);
//
// Configure the renderers
//
//StyleMgrClass::Configure_Renderer (&TextRenderers[0]);
//StyleMgrClass::Configure_Renderer (&TextRenderers[1]);
StyleMgrClass::Configure_Renderer (&ButtonRenderers[0]);
StyleMgrClass::Configure_Renderer (&ButtonRenderers[1]);
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (Is_Dirty ()) {
Create_Text_Renderers ();
Create_Component_Button ();
}
if (WasButtonPressedOnMe && IsMouseOverMe) {
//
// Render the button "pressed"
//
ButtonRenderers[DOWN].Render ();
TextRenderers[DOWN].Render ();
} else {
//
// Render the button normally
//
ButtonRenderers[UP].Render ();
TextRenderers[UP].Render ();
}
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_Create (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_LButton_Down (const Vector2 &mouse_pos)
{
Set_Capture ();
WasButtonPressedOnMe = true;
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_LButton_Up (const Vector2 &mouse_pos)
{
Release_Capture ();
IsMouseOverMe = Rect.Contains (mouse_pos);
//
// Notify the parent (if necessary)
//
if (WasButtonPressedOnMe && IsMouseOverMe) {
Parent->On_Command (ID, BN_CLICKED, 0);
}
WasButtonPressedOnMe = false;
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Move
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_Mouse_Move (const Vector2 &mouse_pos)
{
IsMouseOverMe = Rect.Contains (mouse_pos);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Bitmap_Button
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::Create_Bitmap_Button (void)
{
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
//
// Turn off texturing on the UI background
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("button_test04.tga", TextureClass::MIP_LEVELS_1);
ButtonRenderers[0].Set_Texture (texture);
ButtonRenderers[1].Set_Texture (texture);
texture->Release_Ref();
RectClass uv_rect1 (0, 0, 161.0F / 256.0F, 63.0F / 256.0F);
ButtonRenderers[0].Add_Quad (Rect, uv_rect1);
return ;
}
void
Blit_Section
(
Render2DClass & renderer,
const Vector2 & screen_pos,
const Vector2 & texture_pos,
const Vector2 & pixels,
const Vector2 & texture_dimensions
)
{
RectClass screen_rect;
screen_rect.Left = screen_pos.X;
screen_rect.Top = screen_pos.Y;
screen_rect.Right = screen_rect.Left + pixels.X;
screen_rect.Bottom = screen_rect.Top + pixels.Y;
RectClass uv_rect (texture_pos.X, texture_pos.Y, texture_pos.X + pixels.X, texture_pos.Y + pixels.Y);
uv_rect.Inverse_Scale (Vector2 (texture_dimensions.X - 1, texture_dimensions.Y - 1));
renderer.Add_Quad (screen_rect, uv_rect);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Component_Button
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::Create_Component_Button (void)
{
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
ButtonRenderers[0].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
ButtonRenderers[1].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
//
// Turn off texturing on the UI background
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("button_test04.tga", TextureClass::MIP_LEVELS_1);
ButtonRenderers[0].Set_Texture (texture);
ButtonRenderers[1].Set_Texture (texture);
texture->Release_Ref();
float height = 15.0F;
float edge_width = 17.0F;
float right = 160.0F;
float bottom = 62.0F;
float dn_start = 63.0F;
//float horz_tile_width = 20.0F;
//float vert_tile_height = 10.0F;
Vector2 texture_dimensions (256.0F, 256.0F);
//
// Upper left
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, Rect.Top), Vector2 (0, 0),
Vector2 (edge_width, height), texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (Rect.Left, Rect.Top), Vector2 (0, dn_start),
Vector2 (edge_width, height), texture_dimensions);
//
// Upper right
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, Rect.Top), Vector2 (right - edge_width, 0),
Vector2 (edge_width, height), texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (Rect.Right - edge_width, Rect.Top), Vector2 (right - edge_width, dn_start),
Vector2 (edge_width, height), texture_dimensions);
//
// Lower left
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, Rect.Bottom - height), Vector2 (0, bottom - height),
Vector2 (edge_width, height), texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (Rect.Left, Rect.Bottom - height), Vector2 (0, dn_start + bottom - height),
Vector2 (edge_width, height), texture_dimensions);
//
// Lower right
//
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, Rect.Bottom - height), Vector2 (right - edge_width, bottom - height),
Vector2 (edge_width, height), texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (Rect.Right - edge_width, Rect.Bottom - height), Vector2 (right - edge_width, dn_start + bottom - height),
Vector2 (edge_width, height), texture_dimensions);
Vector2 horz_top_pos ((right / 2) - 5, 0);
Vector2 horz_bottom_pos ((right / 2) - 5, bottom - height);
Vector2 horz_size (10, height);
//
// Horizontal tile
//
float remaining_width = Rect.Width () - (edge_width * 2);
float x_pos = Rect.Left + edge_width;
while (remaining_width > 0) {
horz_size.X = min (remaining_width, horz_size.X);
::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, Rect.Top), horz_top_pos,
horz_size, texture_dimensions);
::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, Rect.Bottom - height), horz_bottom_pos,
horz_size, texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (x_pos, Rect.Top), horz_top_pos + Vector2 (0, dn_start),
horz_size, texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (x_pos, Rect.Bottom - height), horz_bottom_pos + Vector2 (0, dn_start),
horz_size, texture_dimensions);
x_pos += horz_size.X;
remaining_width -= horz_size.X;
}
Vector2 vert_left_pos (0, (bottom / 2) - 5);
Vector2 vert_right_pos (right - edge_width, (bottom / 2) - 5);
Vector2 vert_size (edge_width, 10);
//
// Vertical tile
//
float remaining_height = Rect.Height () - (height * 2);
float y_pos = Rect.Top + height;
while (remaining_height > 0) {
vert_size.Y = min (remaining_height, vert_size.Y);
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, y_pos), vert_left_pos,
vert_size, texture_dimensions);
::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, y_pos), vert_right_pos,
vert_size, texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (Rect.Left, y_pos), vert_left_pos + Vector2 (0, dn_start),
vert_size, texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (Rect.Right - edge_width, y_pos), vert_right_pos + Vector2 (0, dn_start),
vert_size, texture_dimensions);
y_pos += vert_size.Y;
remaining_height -= vert_size.Y;
}
//
// "Patch" fill the interior
//
y_pos = Rect.Top + height;
remaining_height = Rect.Height () - (height * 2);
while (remaining_height > 0) {
x_pos = Rect.Left + edge_width;
remaining_width = Rect.Width () - (edge_width * 2);
while (remaining_width > 0) {
Vector2 size (8, 8);
size.X = min (remaining_width, size.X);
size.Y = min (remaining_height, size.Y);
::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, y_pos), Vector2 ((right / 2) - 4, (bottom / 2) - 4),
size, texture_dimensions);
::Blit_Section (ButtonRenderers[1], Vector2 (x_pos, y_pos), Vector2 ((right / 2) - 4, dn_start + (bottom / 2) - 4),
size, texture_dimensions);
remaining_width -= 8;
x_pos += 8;
}
remaining_height -= 8;
y_pos += 8;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Component_Button2
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::Create_Component_Button2 (void)
{
ButtonRenderers[0].Reset ();
ButtonRenderers[1].Reset ();
ButtonRenderers[0].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
ButtonRenderers[1].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
//
// Turn off texturing on the UI background
//
ButtonRenderers[0].Enable_Texturing (false);
ButtonRenderers[1].Enable_Texturing (false);
const int BLACK = VRGB_TO_INT32 (Vector3 (0, 0, 0));
const int WHITE = VRGB_TO_INT32 (Vector3 (1, 1, 1));
const int DK_GRAY = VRGB_TO_INT32 (Vector3 (0.5F, 0.5F, 0.5F));
const int GRAY = VRGB_TO_INT32 (Vector3 (0.75F, 0.75F, 0.75F));
const int LT_GRAY = VRGB_TO_INT32 (Vector3 (0.9F, 0.9F, 0.9F));
//
// Draw the outside button outline
//
RectClass rect = Rect;
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, WHITE);
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, WHITE);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, BLACK);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, BLACK);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, BLACK);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, BLACK);
ButtonRenderers[1].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, WHITE);
ButtonRenderers[1].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, WHITE);
//
// Draw the inside button outline
//
rect.Inflate (Vector2 (-1, -1));
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, LT_GRAY);
ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, LT_GRAY);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, DK_GRAY);
ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, DK_GRAY);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, DK_GRAY);
ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, DK_GRAY);
//
// Fill the button center
//
rect.Right -= 1;
rect.Bottom -= 1;
ButtonRenderers[0].Add_Quad (rect, GRAY);
ButtonRenderers[1].Add_Quad (rect, GRAY);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderers
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::Create_Text_Renderers (void)
{
TextRenderers[0].Reset ();
TextRenderers[1].Reset ();
//
// Draw the text
//
StyleMgrClass::Render_Text (Title, &TextRenderers[0], Rect, true, true, StyleMgrClass::CENTER_JUSTIFY);
StyleMgrClass::Render_Text (Title, &TextRenderers[1], Rect, true, true, StyleMgrClass::CENTER_JUSTIFY);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor if necessary
//
if (ClientRect.Contains (mouse_pos)) {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_Kill_Focus (DialogControlClass *focus)
{
WasButtonPressedOnMe = false;
IsMouseOverMe = false;
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
void
DialogButtonClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
switch (key_id)
{
case VK_RETURN:
case VK_SPACE:
Parent->On_Command (ID, BN_CLICKED, 0);
break;
}
return ;
}

112
Code/wwui/dialogbutton.h Normal file
View File

@@ -0,0 +1,112 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogbutton.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/08/01 9:41a $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_BUTTON_H
#define __DIALOG_BUTTON_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
////////////////////////////////////////////////////////////////
//
// DialogButtonClass
//
////////////////////////////////////////////////////////////////
class DialogButtonClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
DialogButtonClass (void);
virtual ~DialogButtonClass (void) {}
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void Render (void);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Create (void);
void On_Kill_Focus (DialogControlClass *focus);
void On_Key_Down (uint32 key_id, uint32 key_data);
void Create_Bitmap_Button (void);
void Create_Component_Button (void);
void Create_Component_Button2 (void);
void Create_Text_Renderers (void);
////////////////////////////////////////////////////////////////
// Protected constants
////////////////////////////////////////////////////////////////
enum
{
UP = 0,
DOWN,
STATE_MAX
};
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderers[STATE_MAX];
Render2DClass ButtonRenderers[STATE_MAX];
bool WasButtonPressedOnMe;
bool IsMouseOverMe;
};
#endif //__DIALOG_BUTTON_H

210
Code/wwui/dialogcontrol.cpp Normal file
View File

@@ -0,0 +1,210 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogcontrol.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/26/01 12:07p $*
* *
* $Revision:: 13 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dialogcontrol.h"
#include "dialogbase.h"
#include "mousemgr.h"
#include "dialogmgr.h"
#include "render2d.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// DialogControlClass
//
////////////////////////////////////////////////////////////////
DialogControlClass::DialogControlClass (void) :
Rect (0, 0, 0, 0),
ClientRect (0, 0, 0, 0),
Style (0),
ID (0),
Parent (NULL),
HasFocus (false),
IsDirty (true),
WantsFocus (true),
AdviseSink (NULL),
IsEnabled (true),
IsVisible (true),
IsEmbedded (false),
TextColor (0, 0, 0),
IsTextColorOverridden (false)
{
INT32_TO_VRGB (StyleMgrClass::Get_Text_Color (), TextColor);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~DialogControlClass
//
////////////////////////////////////////////////////////////////
DialogControlClass::~DialogControlClass (void)
{
//
// Remove the input focus if this control has it
//
if (DialogMgrClass::Get_Focus () == this) {
DialogMgrClass::Set_Focus (NULL);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Focus
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::Set_Focus (void)
{
DialogMgrClass::Set_Focus (this);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::On_Set_Cursor (const Vector2 & /*mouse_pos*/)
{
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ARROW);
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Capture
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::Set_Capture (void)
{
DialogMgrClass::Set_Capture (this);
return ;
}
////////////////////////////////////////////////////////////////
//
// Release_Capture
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::Release_Capture (void)
{
DialogMgrClass::Release_Capture ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Window_Pos
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::Set_Window_Pos (const Vector2 &pos)
{
float width = Rect.Width ();
float height = Rect.Height ();
//
// Recalculate the window's bounding rectangle
//
Rect.Left = (int)pos.X;
Rect.Top = (int)pos.Y;
Rect.Right = (int)(Rect.Left + width);
Rect.Bottom = (int)(Rect.Top + height);
//
// Let the control recalculate anything it needs
//
Update_Client_Rect ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Center_Mouse
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::Center_Mouse (void)
{
//
// Put the mouse cursor in the middle of this control
//
/*Vector3 mouse_pos = DialogMgrClass::Get_Mouse_Pos ();
mouse_pos.X = Rect.Left + int(Rect.Width () / 2);
mouse_pos.Y = Rect.Top + int(Rect.Height () / 2);
DialogMgrClass::Set_Mouse_Pos (mouse_pos);*/
return ;
}
////////////////////////////////////////////////////////////////
//
// Enable
//
////////////////////////////////////////////////////////////////
void
DialogControlClass::Enable (bool onoff)
{
if (onoff != IsEnabled) {
IsEnabled = onoff;
Set_Dirty ();
//
// Remove the focus (if necessary)
//
if (IsEnabled == false && DialogMgrClass::Get_Focus () == this) {
DialogMgrClass::Set_Focus (NULL);
}
}
return ;
}

259
Code/wwui/dialogcontrol.h Normal file
View File

@@ -0,0 +1,259 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogcontrol.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/09/02 4:06p $*
* *
* $Revision:: 23 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_CONTROL_H
#define __DIALOG_CONTROL_H
#include "rect.h"
#include "vector2.h"
#include "vector3.h"
#include "widestring.h"
#include "bittype.h"
#include "controladvisesink.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class DialogBaseClass;
class ButtonCtrlClass;
class CheckBoxCtrlClass;
class EditCtrlClass;
class ListCtrlClass;
class TabCtrlClass;
class DialogTextClass;
class InputCtrlClass;
class ButtonCtrlClass;
class MenuEntryCtrlClass;
class ComboBoxCtrlClass;
class ScrollBarCtrlClass;
class SliderCtrlClass;
class ViewerCtrlClass;
class ShortcutBarCtrlClass;
////////////////////////////////////////////////////////////////
// Useful macros
////////////////////////////////////////////////////////////////
#define ADVISE_NOTIFY(fn) \
if (Parent != NULL) { Parent->fn; } \
if (AdviseSink != NULL) { AdviseSink->fn; }
////////////////////////////////////////////////////////////////
//
// DialogControlClass
//
////////////////////////////////////////////////////////////////
class DialogControlClass : public ControlAdviseSinkClass
{
public:
////////////////////////////////////////////////////////////////
// Public friends
////////////////////////////////////////////////////////////////
friend class DialogBaseClass;
friend class DialogMgrClass;
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
DialogControlClass (void);
virtual ~DialogControlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// RTTI
//
virtual CheckBoxCtrlClass * As_CheckBoxCtrlClass (void) { return NULL; }
virtual EditCtrlClass * As_EditCtrlClass (void) { return NULL; }
virtual ListCtrlClass * As_ListCtrlClass (void) { return NULL; }
virtual TabCtrlClass * As_TabCtrlClass (void) { return NULL; }
virtual DialogTextClass * As_DialogTextClass (void) { return NULL; }
virtual InputCtrlClass * As_InputCtrlClass (void) { return NULL; }
virtual ButtonCtrlClass * As_ButtonCtrlClass (void) { return NULL; }
virtual MenuEntryCtrlClass * As_MenuEntryCtrlClass (void) { return NULL; }
virtual ComboBoxCtrlClass * As_ComboBoxCtrlClass (void) { return NULL; }
virtual ScrollBarCtrlClass * As_ScrollBarCtrlClass (void) { return NULL; }
virtual SliderCtrlClass * As_SliderCtrlClass (void) { return NULL; }
virtual ViewerCtrlClass * As_ViewerCtrlClass (void) { return NULL; }
virtual ShortcutBarCtrlClass * As_ShortcutBarCtrlClass (void){ return NULL; }
virtual TreeCtrlClass * As_TreeCtrlClass (void) { return NULL; }
//
// Simple property access
//
virtual const WCHAR * Get_Text (void) const { return Title; }
virtual const RectClass & Get_Window_Rect (void) const { return Rect; }
Vector2 Get_Window_Pos (void) const { return Rect.Upper_Left (); }
const RectClass & Get_Client_Rect (void) const { return ClientRect; }
DWORD Get_Style (void) const { return Style; }
int Get_ID (void) const { return ID; }
virtual void Set_Text (const WCHAR *title) { Title = title; Set_Dirty (); }
void Set_Window_Rect (const RectClass &rect) { Rect = rect; Update_Client_Rect (); }
virtual void Set_Window_Pos (const Vector2 &pos);
void Set_Client_Rect (const RectClass &rect) { ClientRect = rect; }
virtual void Set_Style (DWORD style) { Style = style; }
void Set_ID (int id) { ID = id; }
//
// Parent access
//
DialogBaseClass * Peek_Parent (void) const { return Parent; }
void Set_Parent (DialogBaseClass *parent) { Parent = parent; }
//
// Advise sink access
//
ControlAdviseSinkClass * Get_Advise_Sink (void) const { return AdviseSink; }
void Set_Advise_Sink (ControlAdviseSinkClass *sink) { AdviseSink = sink; }
//
// Focus support
//
bool Has_Focus (void) const { return HasFocus; }
void Set_Focus (void);
bool Wants_Focus (void) const { return WantsFocus; }
void Set_Wants_Focus (bool onoff) { WantsFocus = onoff; }
//
// Enabled support
//
bool Is_Enabled (void) const { return IsEnabled; }
void Enable (bool onoff);
//
// Visibility
//
void Show (bool onoff) { IsVisible = onoff; }
bool Is_Visible (void) const { return IsVisible; }
//
// Embedded support
//
void Set_Is_Embedded (bool onoff) { IsEmbedded = onoff; }
bool Is_Embedded (void) const { return IsEmbedded; }
//
// Input capture support
//
void Set_Capture (void);
void Release_Capture (void);
//
// Tooltip support
//
virtual bool Wants_Tooltip (void) const { return (ToolTipText.Get_Length () > 0); }
virtual void Get_Tooltip_Text (WideStringClass &text) { text = ToolTipText; }
virtual void Set_Tooltip_Text (const WCHAR *text) { ToolTipText = text; }
//
// Appearance control
//
const Vector3 & Get_Text_Color (void) const { return TextColor; }
void Set_Text_Color (const Vector3 &color) { TextColor = color; IsTextColorOverridden = true; Set_Dirty (); }
//
// Display methods
//
virtual void Render (void) { IsDirty = false; }
virtual void Center_Mouse (void);
//
// Dirty support
//
virtual void Set_Dirty (bool onoff = true) { IsDirty = onoff; }
virtual bool Is_Dirty (void) const { return IsDirty; }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
virtual void On_LButton_Down (const Vector2 &mouse_pos) {}
virtual void On_LButton_DblClk (const Vector2 &mouse_pos) {}
virtual void On_LButton_Up (const Vector2 &mouse_pos) {}
virtual void On_RButton_Down (const Vector2 &mouse_pos) {}
virtual void On_RButton_Up (const Vector2 &mouse_pos) {}
virtual void On_MButton_Down (const Vector2 &mouse_pos) {}
virtual void On_MButton_Up (const Vector2 &mouse_pos) {}
virtual void On_Mouse_Move (const Vector2 &mouse_pos) {}
virtual bool On_Key_Down (uint32 key_id, uint32 key_data) {return false;}
virtual bool On_Key_Up (uint32 key_id) {return false;}
virtual void On_Unicode_Char(WCHAR unicode) {}
virtual void On_Mouse_Wheel (int direction) {}
virtual void On_Set_Cursor (const Vector2 &mouse_pos);
virtual void On_Create (void) {}
virtual void On_Destroy (void) {}
virtual void On_Add_To_Dialog (void) {}
virtual void On_Remove_From_Dialog (void) {}
virtual void On_Frame_Update (void) {}
virtual void On_Set_Focus (void) { HasFocus = true; }
virtual void On_Kill_Focus (DialogControlClass *) { HasFocus = false; }
virtual void Update_Client_Rect (void) { ClientRect = Rect; Set_Dirty (); }
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
WideStringClass Title;
WideStringClass ToolTipText;
RectClass Rect;
RectClass ClientRect;
DWORD Style;
int ID;
DialogBaseClass * Parent;
bool HasFocus;
bool IsDirty;
bool WantsFocus;
bool IsEnabled;
bool IsVisible;
bool IsEmbedded;
Vector3 TextColor;
bool IsTextColorOverridden;
ControlAdviseSinkClass * AdviseSink;
};
#endif //__DIALOG_CONTROL_H

81
Code/wwui/dialogfactory.h Normal file
View File

@@ -0,0 +1,81 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogfactory.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 4/26/01 10:37a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_FACTORY_H
#define __DIALOG_FACTORY_H
#include "dialogbase.h"
////////////////////////////////////////////////////////////////
//
// DialogFactoryBaseClass
//
////////////////////////////////////////////////////////////////
class DialogFactoryBaseClass
{
public:
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
virtual void Do_Dialog (void) = 0;
};
////////////////////////////////////////////////////////////////
//
// DialogFactoryClass
//
////////////////////////////////////////////////////////////////
template<class T>
class DialogFactoryClass : public DialogFactoryBaseClass
{
public:
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
void Do_Dialog (void) { T *dialog = new T; dialog->Start_Dialog (); REF_PTR_RELEASE (dialog); }
};
#endif //__DIALOG_FACTORY_H

967
Code/wwui/dialogmgr.cpp Normal file
View File

@@ -0,0 +1,967 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogmgr.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 2/05/02 1:04p $*
* *
* $Revision:: 40 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dialogmgr.h"
#include "dialogbase.h"
#include "childdialog.h"
#include "dx8wrapper.h"
#include "assetmgr.h"
#include "rinfo.h"
#include "camera.h"
#include "mousemgr.h"
#include "tooltipmgr.h"
#include "stylemgr.h"
#include "dialogcontrol.h"
#include "menudialog.h"
#include "wwuiinput.h"
#include "wwmemlog.h"
#include "dialogtransition.h"
#include "systimer.h"
#include "tooltip.h"
////////////////////////////////////////////////////////////////
// Static member initialization
////////////////////////////////////////////////////////////////
DynamicVectorClass<DialogBaseClass *> DialogMgrClass::DialogList;
DialogBaseClass ** DialogMgrClass::TestArray;
int DialogMgrClass::TestArrayCount;
int DialogMgrClass::TestArrayMaxCount;
bool DialogMgrClass::IsFirstRender = false;
bool DialogMgrClass::IsInMenuMode = false;
DialogBaseClass * DialogMgrClass::ActiveDialog = NULL;
BYTE DialogMgrClass::KeyboardState[256];
DialogControlClass * DialogMgrClass::InputCapture = NULL;
DialogControlClass * DialogMgrClass::FocusControl = NULL;
WWUIInputClass * DialogMgrClass::Input = NULL;
DialogTransitionClass * DialogMgrClass::Transition = NULL;
DialogBaseClass * DialogMgrClass::PendingActiveDialog = NULL;
DialogBaseClass * DialogMgrClass::TransitionDialog = NULL;
uint32 DialogMgrClass::CurrTime = 0;
uint32 DialogMgrClass::LastFrameTime = 0;
Vector3 DialogMgrClass::LastMousePos (0, 0, 0);
bool DialogMgrClass::LastMouseButtonState[MB_COUNT] = { 0 };
bool DialogMgrClass::IsFlushing = false;
ToolTipClass* DialogMgrClass::mIMEMessage = NULL;
uint32 DialogMgrClass::mIMEMessageTime = 0;
static bool GameWasInFocus;
////////////////////////////////////////////////////////////////
//
// Initialize
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Initialize (const char *stylemgr_ini)
{
StyleMgrClass::Initialize_From_INI (stylemgr_ini);
MouseMgrClass::Initialize ();
ToolTipMgrClass::Initialize ();
MenuDialogClass::Initialize ();
::memset (KeyboardState, 0, sizeof (KeyboardState));
TestArrayMaxCount = 0;
return ;
}
////////////////////////////////////////////////////////////////
//
// Shutdown
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Shutdown (void)
{
//
// Remove all the dialogs from our list
//
Flush_Dialogs ();
MenuDialogClass::Shutdown ();
StyleMgrClass::Shutdown ();
MouseMgrClass::Shutdown ();
ToolTipMgrClass::Shutdown ();
Set_Active_Dialog (NULL);
delete[] TestArray;
TestArray=NULL;
if (mIMEMessage) {
delete mIMEMessage;
mIMEMessage = NULL;
mIMEMessageTime = 0;
}
//
// Release our hold on the input mechanism
//
REF_PTR_RELEASE (Input);
return ;
}
////////////////////////////////////////////////////////////////
//
// Reset_Inputs
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Reset_Inputs (void)
{
//
// Update the cached mouse button states
//
LastMouseButtonState[MB_LBUTTON] = Input->Is_Button_Down (VK_LBUTTON);
LastMouseButtonState[MB_MBUTTON] = Input->Is_Button_Down (VK_MBUTTON);
LastMouseButtonState[MB_RBUTTON] = Input->Is_Button_Down (VK_RBUTTON);
return ;
}
////////////////////////////////////////////////////////////////
//
// Register_Dialog
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Register_Dialog (DialogBaseClass *dialog)
{
//
// Check to see if this dialog is already in our list
//
if (DialogList.ID (dialog) == -1) {
Reset_Inputs ();
//
// Keep a lock on the dialog
//
dialog->Add_Ref ();
//
// Add the dialog to our list. Note: We keep popup dialogs
// as the topmost windows in our z order. Z order is determined
// by the order in the list.
//
bool is_top_level = true;
if (dialog->As_PopupDialogClass () == NULL) {
int new_index = DialogList.Count () - 1;
for (; new_index >= 0; new_index --) {
if (DialogList[new_index]->As_PopupDialogClass () == NULL) {
break;
}
is_top_level = false;
}
DialogList.Insert (new_index + 1, dialog);
} else {
DialogList.Add (dialog);
}
//
// Make this the active dialog
//
if (is_top_level && dialog->Wants_Activation ()) {
Set_Active_Dialog (dialog);
}
//
// Update the framework
//
On_Dialog_Added ();
//
// Handle the first dialog...
//
if (DialogList.Count () == 1) {
MouseMgrClass::Show_Cursor (true);
IsFirstRender = true;
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// UnRegister_Dialog
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::UnRegister_Dialog (DialogBaseClass *dialog)
{
//
// Is this dialog in our list?
//
int index = DialogList.ID (dialog);
if (index != -1) {
Reset_Inputs ();
//
// Remove the dialog from our list
//
DialogList.Delete (index);
REF_PTR_RELEASE (dialog);
//
// Update the framework
//
On_Dialog_Removed ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Dialog_Added
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::On_Dialog_Added (void)
{
//
// Center the mouse in the window
//
#if (0)
HWND wnd = (HWND)WW3D::Get_Window ();
RECT rect = { 0 };
::GetClientRect (wnd, &rect);
#endif //(0)
/*Vector3 mouse_pos = Get_Mouse_Pos ();
mouse_pos.X = rect.left + (rect.right - rect.left) / 2;
mouse_pos.Y = rect.top + (rect.bottom - rect.top) / 2;
Set_Mouse_Pos (mouse_pos);*/
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Dialog_Removed
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::On_Dialog_Removed (void)
{
//
// Are there any dialogs left?
//
if (DialogList.Count () == 0) {
//
// Revert from "dialog" mode.
//
MouseMgrClass::Show_Cursor (false);
Set_Active_Dialog (NULL);
} else if (IsFlushing == false) {
//
// Force "focus" to go to the most recent dialog
//
int index = DialogList.Count ();
while (index --) {
if (DialogList[index]->Wants_Activation ()) {
Set_Active_Dialog (DialogList[index]);
break;
}
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Transition
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Update_Transition (void)
{
if (Transition != NULL) {
//
// Allow the transition to think
//
Transition->On_Frame_Update ();
Transition->Render ();
//
// Did the transition finish?
//
if (Transition->Is_Complete ()) {
//
// Let the dialog controls be displayed (as necessary)
//
if (TransitionDialog != NULL) {
TransitionDialog->Set_Controls_Hidden (false);
}
if (PendingActiveDialog != NULL) {
PendingActiveDialog->Set_Controls_Hidden (false);
}
//
// Now make the pending dialog active
//
Internal_Set_Active_Dialog (PendingActiveDialog);
PendingActiveDialog = NULL;
TransitionDialog = NULL;
//
// Release our hold on the transition
//
REF_PTR_RELEASE (Transition);
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::On_Frame_Update (void)
{
WWMEMLOG(MEM_GAMEDATA);
//
// Update the timing
//
uint32 old_time = CurrTime;
CurrTime = TIMEGETTIME ();
LastFrameTime = CurrTime - old_time;
// DynamicVectorClass<DialogBaseClass *> test_list = DialogList;
if (DialogList.Count()>TestArrayMaxCount) {
delete[] TestArray;
TestArrayMaxCount=DialogList.Count();
TestArray=new DialogBaseClass*[TestArrayMaxCount];
}
TestArrayCount=DialogList.Count();
for (int i=0;i<TestArrayCount;++i) {
TestArray[i]=DialogList[i];
}
//
// Let each dialog think
//
for (int index = 0; index < DialogList.Count (); index ++) {
//
// Simple check to ensure that the DialogList hasn't changed
// due to this On_Frame_Update () call
//
if (index >= TestArrayCount || DialogList[index] != TestArray[index]) {
break;
}
DialogBaseClass* dialog = DialogList[index];
WWASSERT(dialog != NULL);
dialog->Add_Ref();
if (dialog->Is_Active () && dialog->As_ChildDialogClass () == NULL) {
dialog->On_Frame_Update ();
}
//
// Force an "On_Periodic" for dialogs that aren't in focus...
//
dialog->On_Periodic ();
dialog->Release_Ref();
}
//
// Return from "dialog" mode if the ESC key has been let up...
//
if (IsInMenuMode && DialogList.Count () == 0 && ((KeyboardState[VK_ESCAPE] & 0x80) == 0)) {
IsInMenuMode = false;
Input->Exit_Menu_Mode ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Render (void)
{
WWMEMLOG(MEM_GAMEDATA);
if (!GameInFocus) {
GameWasInFocus=false;
return;
}
if (!GameWasInFocus) {
DialogMgrClass::Reset();
GameWasInFocus=true;
}
//
// Enable static sorting levels
//
bool enable_static_sort = WW3D::Are_Static_Sort_Lists_Enabled ();
WW3D::Enable_Static_Sort_Lists (true);
//
// Enable the "console" mode if this is the first dialog
// we're rendering
//
if (IsFirstRender) {
IsFirstRender = false;
IsInMenuMode = true;
Input->Enter_Menu_Mode ();
}
//
// Update any transitions
//
Update_Transition ();
//
// Render each dialog
//
for (int index = 0; index < DialogList.Count (); index ++) {
bool render = false;
//
// Should this dialog be rendered?
//
DialogBaseClass *dialog = DialogList[index];
if ( dialog->Is_Visible () /*&&
dialog != PendingActiveDialog &&
dialog != TransitionOutDialog*/ )
{
//
// Don't render here if its a child-dialog
//
render = (dialog->As_ChildDialogClass () == NULL);
}
//
// Render the dialog
//
if (render) {
dialog->Render ();
}
}
//
// Render the tooltip
//
Vector3 cursor_pos = Get_Mouse_Pos ();
ToolTipMgrClass::Update (Vector2 (cursor_pos.X, cursor_pos.Y));
ToolTipMgrClass::Render ();
if ((mIMEMessageTime > CurrTime) && mIMEMessage) {
mIMEMessage->Render();
}
//
// Render the mouse cursor
//
MouseMgrClass::Render ();
//
// Update the cached mouse button states
//
Reset_Inputs ();
//
// Put the static sort flag back the way we found it
//
WW3D::Enable_Static_Sort_Lists (enable_static_sort);
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Active_Dialog
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Set_Active_Dialog (DialogBaseClass *dialog)
{
if (ActiveDialog == dialog) {
return ;
}
//REF_PTR_RELEASE (Transition);
if (Transition != NULL) {
PendingActiveDialog = dialog;
return ;
}
//
// Check to see if we should play an outro-transition for
// the currently active dialog
//
if (ActiveDialog != NULL) {
Transition = ActiveDialog->Get_Transition_Out (dialog);
if (Transition != NULL) {
PendingActiveDialog = dialog;
TransitionDialog = ActiveDialog;
//
// Hide the controls on the pending dialog (if necessary)
//
if (PendingActiveDialog != NULL) {
//PendingActiveDialog->Set_Controls_Hidden (true);
}
}
}
//
// Check to see if we should play an intro-transition for
// the new active dialog
//
if (dialog != NULL && Transition == NULL) {
Transition = dialog->Get_Transition_In (ActiveDialog);
if (Transition != NULL) {
PendingActiveDialog = dialog;
TransitionDialog = dialog;
//
// Hide the controls on the transitioning dialog
//
//TransitionDialog->Set_Controls_Hidden (true);
}
}
//
// If we don't have any transition to play, then simply
// set the active dialog
//
if (Transition == NULL) {
Internal_Set_Active_Dialog (dialog);
}
return ;
}
void
DialogMgrClass::Reset (void)
{
// REF_PTR_RELEASE (Transition);
// if (PendingActiveDialog) {
// REF_PTR_SET(ActiveDialog,PendingActiveDialog);
// REF_PTR_RELEASE(PendingActiveDialog);
// }
// Internal_Set_Active_Dialog (ActiveDialog);
if (ActiveDialog) {
ActiveDialog->Set_Dirty();
}
if (PendingActiveDialog) {
PendingActiveDialog->Set_Dirty();
}
}
////////////////////////////////////////////////////////////////
//
// Internal_Set_Active_Dialog
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Internal_Set_Active_Dialog (DialogBaseClass *dialog)
{
//
// Get rid of the input capture and focus
//
Release_Capture ();
//
// Switch the active dialog
//
DialogBaseClass *old_dialog = ActiveDialog;
ActiveDialog = dialog;
//
// Notify the old dialog
//
if (old_dialog != NULL) {
old_dialog->On_Activate (false);
REF_PTR_RELEASE (old_dialog);
}
Set_Focus (NULL);
//
// Notify the new dialog (if necessary)
//
if (ActiveDialog != NULL) {
ActiveDialog->Add_Ref ();
ActiveDialog->On_Activate (true);
}
//
// Remove any tooltips
//
ToolTipMgrClass::Reset ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
DialogMgrClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
if (Transition != NULL) {
return false;
}
//
// Update the keyboard state
//
::GetKeyboardState (KeyboardState);
//
// Notify the active dialog (if any)
//
if (ActiveDialog != NULL) {
return ActiveDialog->On_Key_Down (key_id, key_data);
}
return false;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Up
//
////////////////////////////////////////////////////////////////
bool
DialogMgrClass::On_Key_Up (uint32 key_id)
{
if (Transition != NULL) {
return false;
}
//
// Update the keyboard state
//
::GetKeyboardState (KeyboardState);
//
// Notify the active dialog (if any)
//
if (ActiveDialog != NULL) {
return ActiveDialog->On_Key_Up (key_id);
}
return false;
}
////////////////////////////////////////////////////////////////
//
// On_Unicode_Char
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::On_Unicode_Char (uint16 unicode)
{
if (Transition != NULL) {
return ;
}
//
// Update the keyboard state
//
::GetKeyboardState (KeyboardState);
//
// Notify the active dialog (if any)
//
if (ActiveDialog != NULL) {
ActiveDialog->On_Unicode_Char (unicode);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Find_Control
//
////////////////////////////////////////////////////////////////
DialogControlClass *
DialogMgrClass::Find_Control (const Vector2 &mouse_pos)
{
DialogControlClass *retval = NULL;
//
// Get this information from the active dialog
//
if (ActiveDialog != NULL) {
retval = ActiveDialog->Find_Control (mouse_pos);
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Set_Capture
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Set_Capture (DialogControlClass *control)
{
InputCapture = control;
return ;
}
////////////////////////////////////////////////////////////////
//
// Release_Capture
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Release_Capture (void)
{
InputCapture = NULL;
return ;
}
////////////////////////////////////////////////////////////////
//
// Flush_Dialogs
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Flush_Dialogs (void)
{
WWDEBUG_SAY(("DialogMgrClass: Flushing dialogs\n"));
IsFlushing = true;
Set_Active_Dialog (NULL);
//
// Remove all the dialogs from our list
//
while (DialogList.Count () > 0) {
DialogList[DialogList.Count () - 1]->End_Dialog ();
}
Set_Focus (NULL);
//
// Reset our transition variables
//
TransitionDialog = NULL;
PendingActiveDialog = NULL;
REF_PTR_RELEASE (Transition);
//
// Release our hold on the transitioning dialogs
//
//REF_PTR_RELEASE (TransitionInDialog);
//REF_PTR_RELEASE (TransitionOutDialog);
//
// Reset the list
//
DialogList.Delete_All ();
IsFlushing = false;
WWDEBUG_SAY(("DialogMgrClass: Flush complete\n"));
return ;
}
bool DialogMgrClass::Is_Flushing_Dialogs(void)
{
return IsFlushing;
}
////////////////////////////////////////////////////////////////
//
// Was_Button_Down
//
////////////////////////////////////////////////////////////////
bool
DialogMgrClass::Was_Button_Down (int vk_mouse_button_id)
{
bool retval = false;
switch (vk_mouse_button_id)
{
case VK_LBUTTON:
retval = LastMouseButtonState[MB_LBUTTON];
break;
case VK_MBUTTON:
retval = LastMouseButtonState[MB_MBUTTON];
break;
case VK_RBUTTON:
retval = LastMouseButtonState[MB_RBUTTON];
break;
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Set_Focus
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Set_Focus (DialogControlClass *control)
{
if (FocusControl == control) {
return ;
}
//
// Change the focus
//
DialogControlClass *old_focus_ctrl = FocusControl;
FocusControl = control;
//
// Let go of the currently focus'd control
//
if (old_focus_ctrl != NULL) {
old_focus_ctrl->On_Kill_Focus (control);
}
//
// Reset the focus
//
if (FocusControl != NULL) {
FocusControl->On_Set_Focus ();
}
//
// Remove the input capture
//
Release_Capture ();
return ;
}
DialogBaseClass* DialogMgrClass::Find_Dialog(int dialogID)
{
for (int index = 0; index < DialogList.Count(); ++index) {
if (DialogList[index]->Get_Dlg_ID() == dialogID) {
return DialogList[index];
}
}
return NULL;
}
////////////////////////////////////////////////////////////////
//
// Rollback
//
////////////////////////////////////////////////////////////////
void
DialogMgrClass::Rollback (DialogBaseClass *dialog)
{
for (int index = DialogList.Count () - 1; index >= 0; index --) {
//
// Stop once we've come across the dialog we're rolling back to
//
if (DialogList[index] == dialog) {
break;
}
//
// Close this dialog (if necessary)
//
if (DialogList[index]->As_ChildDialogClass () == NULL) {
DialogList[index]->End_Dialog ();
}
}
return ;
}
void DialogMgrClass::Show_IME_Message(const wchar_t* message, uint32 duration)
{
if (mIMEMessage == NULL) {
mIMEMessage = new ToolTipClass;
}
if (mIMEMessage) {
mIMEMessage->Set_Position(Vector2(10,10));
mIMEMessage->Set_Text(message);
mIMEMessageTime = (CurrTime + duration);
}
}

245
Code/wwui/dialogmgr.h Normal file
View File

@@ -0,0 +1,245 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogmgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/08/02 6:05p $*
* *
* $Revision:: 22 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_MGR_H
#define __DIALOG_MGR_H
#include "vector.h"
#include "vector2.h"
#include "vector3.h"
#include "bittype.h"
#include "wwuiinput.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class DialogBaseClass;
class DialogControlClass;
class DialogTransitionClass;
class ToolTipClass;
////////////////////////////////////////////////////////////////
// Public constants
////////////////////////////////////////////////////////////////
enum
{
VKEY_PRESSED = 0x80,
VKEY_TOGGLED = 0x01
};
////////////////////////////////////////////////////////////////
//
// DialogMgrClass
//
////////////////////////////////////////////////////////////////
class DialogMgrClass
{
public:
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Library management
//
static void Initialize (const char *stylemgr_ini);
static void Shutdown (void);
//
// Per-frame processing
//
static void Render (void);
static void On_Frame_Update (void);
//
// Input support
//
static void Install_Input (WWUIInputClass *instance) { REF_PTR_SET (Input, instance); }
static IME::IMEManager* Get_IME(void)
{return Input->GetIME();}
static void Show_IME_Message(const wchar_t* message, uint32 duration);
//
// Keyboard Input
//
static BYTE * Get_Keyboard_State (void) { return KeyboardState; }
static BYTE Get_VKey_State (BYTE index) { return KeyboardState[index]; }
static void Reset (void);
//
// Mouse Input
//
// Note X,Y are screen coordinates, while the Z component is the mouse wheel
// position.
//
static const Vector3 & Get_Mouse_Pos (void) { return Input->Get_Mouse_Pos (); }
static void Set_Mouse_Pos (const Vector3 &pos) { Input->Set_Mouse_Pos (pos); }
static const Vector3 & Get_Last_Mouse_Pos (void) { return LastMousePos; }
static void Set_Last_Mouse_Pos (const Vector3 &pos){ LastMousePos = pos; }
//
// Mouse button input
//
static bool Is_Button_Down (int vk_mouse_button_id) { return Input->Is_Button_Down (vk_mouse_button_id); };
static bool Was_Button_Down (int vk_mouse_button_id);
//
// Dialog registration
//
static void Register_Dialog (DialogBaseClass *dialog);
static void UnRegister_Dialog (DialogBaseClass *dialog);
static void Flush_Dialogs (void);
static bool Is_Flushing_Dialogs(void);
//
// Timing support
//
static int Get_Time (void) { return CurrTime; }
static int Get_Frame_Time (void) { return LastFrameTime; }
//
// Active dialog support
//
static DialogBaseClass* Find_Dialog(int dialogID);
static void Set_Active_Dialog (DialogBaseClass *dialog);
static DialogBaseClass * Get_Active_Dialog (void) { return ActiveDialog; }
static void Rollback (DialogBaseClass *dialog);
//
// Control support
//
static DialogControlClass * Find_Control (const Vector2 &mouse_pos);
//
// Input capture
//
static void Set_Capture (DialogControlClass *control);
static void Release_Capture (void);
static DialogControlClass * Get_Capture (void) { return InputCapture; }
//
// Focus support
//
static void Set_Focus (DialogControlClass *control);
static DialogControlClass * Get_Focus (void) { return FocusControl; }
//
// Transition support
//
static DialogBaseClass * Peek_Transitioning_Dialog (void) { return TransitionDialog; }
//
// Statistics
//
static int Get_Dialog_Count (void) { return DialogList.Count (); }
private:
////////////////////////////////////////////////////////////////
// Private constants
////////////////////////////////////////////////////////////////
enum
{
MB_LBUTTON = 0,
MB_MBUTTON,
MB_RBUTTON,
MB_COUNT,
};
////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////
static void On_Dialog_Added (void);
static void On_Dialog_Removed (void);
static void Update_Transition (void);
static void Reset_Inputs (void);
static void Internal_Set_Active_Dialog (DialogBaseClass *dialog);
//
// Keyboard input
//
static bool On_Key_Down (uint32 key_id, uint32 key_data);
static bool On_Key_Up (uint32 key_id);
static void On_Unicode_Char(uint16 unicode);
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
static DynamicVectorClass<DialogBaseClass *> DialogList;
static DialogBaseClass ** TestArray;
static int TestArrayCount;
static int TestArrayMaxCount;
static bool IsFirstRender;
static bool IsInMenuMode;
static DialogBaseClass * ActiveDialog;
static BYTE KeyboardState[256];
static bool LastMouseButtonState[MB_COUNT];
static DialogControlClass * InputCapture;
static DialogControlClass * FocusControl;
static WWUIInputClass * Input;
static DialogTransitionClass * Transition;
static DialogBaseClass * TransitionDialog;
static DialogBaseClass * PendingActiveDialog;
static uint32 CurrTime;
static uint32 LastFrameTime;
static Vector3 LastMousePos;
static bool IsFlushing;
static ToolTipClass* mIMEMessage;
static uint32 mIMEMessageTime;
////////////////////////////////////////////////////////////////
// Friend classes
////////////////////////////////////////////////////////////////
friend WWUIInputClass;
};
#endif //__DIALOG_MGR_H

300
Code/wwui/dialogparser.cpp Normal file
View File

@@ -0,0 +1,300 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogparser.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/25/01 3:54p $*
* *
* $Revision:: 12 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dialogparser.h"
#include "win.h"
#include "translatedb.h"
#include <commctrl.h>
//////////////////////////////////////////////////////////////////////////////
// Macros
//////////////////////////////////////////////////////////////////////////////
#define ALIGN_WORD_PTR(p) ((WORD *)(((DWORD)p + 1) & ~1))
#define ALIGN_DWORD_PTR(p) ((DWORD *)(((DWORD)p + 3) & ~3))
//////////////////////////////////////////////////////////////////////////////
// Local prototypes
//////////////////////////////////////////////////////////////////////////////
WORD *Skip_Dlg_Field (WORD *src, WCHAR *buffer = NULL, int buffer_len = 0, WORD *ctrl_type = NULL);
//////////////////////////////////////////////////////////////////////////////
//
// Skip_Dlg_Field
//
//////////////////////////////////////////////////////////////////////////////
WORD *
Skip_Dlg_Field (WORD *src, WCHAR *buffer, int buffer_len, WORD *ctrl_type)
{
//
// These fields always start on the next word boundary, so align
// the source pointer on this boundary.
//
WORD *retval = ALIGN_WORD_PTR(src);
//
// Note: The field codes are as follows:
//
// 0xFFFF - The following WORD is an ordinal value of a system class.
// 0x0000 - Empty field
// Otherwise - The remaining data is a NULL terminated WCHAR string.
//
if (*retval == 0xFFFF) {
//
// Move past the field designator
//
retval ++;
//
// Does the user want information about the ctrl type?
//
if (ctrl_type != NULL) {
*ctrl_type = *retval;
}
//
// Move past the ctrl type identifier
//
retval ++;
} else if (*retval == 0x0000) {
//
// Null terminate the string if the user is expecting data
//
if (buffer != NULL) {
*buffer = 0;
}
//
// Move past the field designator
//
retval ++;
} else {
//
// The following data is a null-terminated string. Scan
// as much data into our desination buffer as possible.
// Note: The data is stored in wide character format.
//
while (*retval != 0x0000) {
if (buffer != NULL && buffer_len > 1) {
//
// Store this character in the supplied buffer
// and decrement the remaining buffer length.
//
*buffer++ = *retval;
buffer_len --;
}
retval ++;
}
//
// Ensure the supplied buffer is NULL terminated
//
if (buffer != NULL) {
*buffer = 0;
}
//
// Advance to the next field
//
retval ++;
}
//
// Return the new buffer position to the caller
//
return retval;
}
//////////////////////////////////////////////////////////////////////////////
//
// Parse_Template
//
//////////////////////////////////////////////////////////////////////////////
void
DialogParserClass::Parse_Template
(
int res_id,
int * dlg_width,
int * dlg_height,
WideStringClass * dlg_title,
DynamicVectorClass<ControlDefinitionStruct> * control_list
)
{
//
// Load the resource file
//
HRSRC resource = ::FindResource (ProgramInstance, MAKEINTRESOURCE (res_id), RT_DIALOG);
HGLOBAL hglobal = ::LoadResource (ProgramInstance, resource);
LPVOID res_buffer = ::LockResource (hglobal);
if(res_buffer != NULL) {
//
// The first few bytes of the resource buffer are the DLGTEMPLATE structure
//
DLGTEMPLATE *dlg_template = (DLGTEMPLATE *)res_buffer;
(*dlg_width) = (int)dlg_template->cx;
(*dlg_height) = (int)dlg_template->cy;
//
// Move past the DLGTEMPLATE header to the other fields
//
WORD *buffer = (WORD *)(((char *)res_buffer) + sizeof (DLGTEMPLATE));
//
// Skip the menu, and window class
//
buffer = Skip_Dlg_Field (buffer);
buffer = Skip_Dlg_Field (buffer);
//
// Read the title
//
buffer = Skip_Dlg_Field (buffer, dlg_title->Get_Buffer (96), 96);
WCHAR *string_id = ::wcsstr (dlg_title->Peek_Buffer (), L"IDS_");
if (string_id != NULL) {
WideStringClass wide_string_id = string_id;
StringClass ascii_string_id;
wide_string_id.Convert_To (ascii_string_id);
(*dlg_title) = TRANSLATE_BY_DESC(ascii_string_id);
}
//
// Do we need to skip past the font settings?
//
if (dlg_template->style & DS_SETFONT) {
buffer ++;
while (*buffer != 0x0000) {
buffer ++;
}
buffer ++;
}
//
// Loop over each control and gather information about them
//
for (int index = 0; index < dlg_template->cdit; index ++) {
DLGITEMTEMPLATE *dlg_item_template = (DLGITEMTEMPLATE *)ALIGN_DWORD_PTR((DWORD *)buffer);
buffer = (WORD *)(((char *)dlg_item_template) + sizeof (DLGITEMTEMPLATE));
//
// Read the ctrl type
//
WCHAR text_buffer[256] = { 0 };
WORD ctrl_type = 0x0000;
buffer = Skip_Dlg_Field (buffer, text_buffer, 256, &ctrl_type);
//
// Wasn't one of the standard types, so see if we can determine
// what it is by its class name.
//
if (ctrl_type == 0) {
::_wcsupr (text_buffer);
if (::wcsstr (text_buffer, L"TRACKBAR") != 0) {
ctrl_type = SLIDER;
} else if (::wcsstr (text_buffer, L"TABCONTROL") != 0) {
ctrl_type = TAB;
} else if (::wcsstr (text_buffer, L"LISTVIEW") != 0) {
ctrl_type = LIST_CTRL;
} else if (::wcsstr (text_buffer, L"MAP") != 0) {
ctrl_type = MAP;
} else if (::wcsstr (text_buffer, L"VIEWER") != 0) {
ctrl_type = VIEWER;
} else if (::wcsstr (text_buffer, L"HOTKEY") != 0) {
ctrl_type = HOTKEY;
} else if (::wcsstr (text_buffer, L"SHORTCUTBAR") != 0) {
ctrl_type = SHORTCUT_BAR;
} else if (::wcsstr (text_buffer, L"MERCHANDISE") != 0) {
ctrl_type = MERCHANDISE_CTRL;
} else if (::wcsstr (text_buffer, L"TREEVIEW") != 0) {
ctrl_type = TREE_CTRL;
} else if (::wcsicmp(text_buffer, PROGRESS_CLASSW) == 0) {
ctrl_type = PROGRESS_BAR;
} else if (::wcsstr (text_buffer, L"HEALTHBAR") != 0) {
ctrl_type = HEALTH_BAR;
}
}
//
// Read the window text
//
buffer = Skip_Dlg_Field (buffer, text_buffer, 256);
WCHAR *string_id = ::wcsstr (text_buffer, L"IDS_");
if (string_id != NULL) {
WideStringClass wide_string_id = string_id;
StringClass ascii_string_id;
wide_string_id.Convert_To (ascii_string_id);
WideStringClass translation = TRANSLATE_BY_DESC(ascii_string_id);
::wcscpy (string_id, translation);
}
//
// Add this control definition to the list
//
ControlDefinitionStruct definition;
definition.id = (int)dlg_item_template->id;
definition.style = dlg_item_template->style;
definition.x = dlg_item_template->x;
definition.y = dlg_item_template->y;
definition.cx = dlg_item_template->cx;
definition.cy = dlg_item_template->cy;
definition.type = (CONTROL_TYPE)ctrl_type;
definition.title = text_buffer;
control_list->Add (definition);
//
// Skip past the extra data
//
WORD extra_data_size = *buffer;
buffer ++;
if (extra_data_size > 0) {
buffer = (WORD *)(((char *)ALIGN_WORD_PTR(buffer)) + extra_data_size);
}
}
}
return ;
}

130
Code/wwui/dialogparser.h Normal file
View File

@@ -0,0 +1,130 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogparser.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/25/01 3:53p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_PARSER_H
#define __DIALOG_PARSER_H
#include "vector.h"
#include "bittype.h"
#include "widestring.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class WideStringClass;
////////////////////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////////////////////
typedef enum
{
BUTTON = 0x0080,
EDIT,
STATIC,
LIST_BOX,
SCROLL_BAR,
COMBOBOX,
SLIDER,
LIST_CTRL,
TAB,
MAP,
VIEWER,
HOTKEY,
SHORTCUT_BAR,
MERCHANDISE_CTRL,
TREE_CTRL,
PROGRESS_BAR,
HEALTH_BAR
} CONTROL_TYPE;
////////////////////////////////////////////////////////////////
// Structures
////////////////////////////////////////////////////////////////
typedef struct _ControlDefinitionStruct
{
int id;
CONTROL_TYPE type;
uint32 style;
int x;
int y;
int cx;
int cy;
WideStringClass title;
//
// Required by DynamicVectorClass
//
bool operator== (const _ControlDefinitionStruct &src) { return false; }
bool operator!= (const _ControlDefinitionStruct &src) { return true; }
_ControlDefinitionStruct (void) :
id (0),
type (BUTTON),
style (0),
x (0),
y (0),
cx (0),
cy (0)
{}
} ControlDefinitionStruct;
////////////////////////////////////////////////////////////////
//
// DialogParserClass
//
////////////////////////////////////////////////////////////////
class DialogParserClass
{
public:
////////////////////////////////////////////////////////////////
// Static methods
////////////////////////////////////////////////////////////////
static void Parse_Template (int res_id, int *dlg_width, int *dlg_height, WideStringClass *dlg_title, DynamicVectorClass<ControlDefinitionStruct> *control_list);
};
#endif //__DIALOG_PARSER_H

256
Code/wwui/dialogtext.cpp Normal file
View File

@@ -0,0 +1,256 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogtext.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/08/01 12:14a $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dialogtext.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// DialogButtonClass
//
////////////////////////////////////////////////////////////////
DialogTextClass::DialogTextClass (void) :
IsTitle (false)
{
Set_Wants_Focus (false);
//
// Set the font for the text renderer
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_CONTROLS);
StyleMgrClass::Configure_Renderer (&ControlRenderer);
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
DialogTextClass::Render (void)
{
if (Style & WS_VISIBLE) {
//
// Update the text renderer (if necessary)
//
if (IsDirty) {
Create_Text_Renderer ();
}
if (IsTitle) {
GlowRenderer.Render ();
}
//
// Render the control
//
TextRenderer.Render ();
ControlRenderer.Render ();
DialogControlClass::Render ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderer
//
////////////////////////////////////////////////////////////////
void
DialogTextClass::Create_Text_Renderer (void)
{
TextRenderer.Reset ();
ControlRenderer.Reset ();
if ((Style & SS_TYPEMASK) == SS_ETCHEDHORZ) {
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
}
//
// Draw the line
//
ControlRenderer.Add_Line (Rect.Upper_Left (), Rect.Upper_Right (), 1.0F, color);
} else if ((Style & SS_TYPEMASK) == SS_BLACKFRAME) {
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
}
//
// Draw the outline
//
ControlRenderer.Add_Outline (Rect, 1.0F, color);
} else {
//
// Determine how to justify the text
//
StyleMgrClass::JUSTIFICATION justification = StyleMgrClass::LEFT_JUSTIFY;
if ((Style & 0xF) == SS_RIGHT) {
justification = StyleMgrClass::RIGHT_JUSTIFY;
} else if ((Style & 0xF) == SS_CENTER) {
justification = StyleMgrClass::CENTER_JUSTIFY;
}
//
// Determine if the text should be centered vertically
//
bool is_vcentered = ((Style & SS_CENTERIMAGE) == SS_CENTERIMAGE);
//
// Draw the text
//
if (IsTitle) {
//
// Render the title text using a glow
//
GlowRenderer.Reset_Polys ();
StyleMgrClass::Render_Glow (Title, &GlowRenderer, Rect, 5, 5, RGB_TO_INT32 (14, 0, 0), StyleMgrClass::CENTER_JUSTIFY);
StyleMgrClass::Render_Text (Title, &TextRenderer, RGB_TO_INT32 (255, 255, 36), 0, Rect, false, false, StyleMgrClass::CENTER_JUSTIFY, true);
} else if ((Style & 0x0F) == SS_LEFTNOWORDWRAP) {
//
// Render the text using the default color scheme or the overriden
// color scheme
//
if (IsTextColorOverridden == false) {
StyleMgrClass::Render_Text (Title, &TextRenderer, Rect, true, true,
justification, IsEnabled, is_vcentered);
} else {
StyleMgrClass::Render_Text (Title, &TextRenderer, VRGB_TO_INT32 (TextColor),
RGB_TO_INT32 (0, 0, 0), Rect, true, true, justification, is_vcentered);
}
} else {
//
// Render the text using the default color scheme or the overriden
// color scheme
//
if (IsTextColorOverridden == false) {
StyleMgrClass::Render_Wrapped_Text_Ex (Title, &TextRenderer, Rect, true, is_vcentered, IsEnabled, justification);
} else {
StyleMgrClass::Render_Wrapped_Text_Ex (Title, &TextRenderer, VRGB_TO_INT32 (TextColor),
RGB_TO_INT32 (0, 0, 0), Rect, true, is_vcentered, justification);
}
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
DialogTextClass::On_Create (void)
{
if (Title.Get_Length () >= 2) {
//
// Does this string have special formatting?
//
if (Title[0] == L'%' && Title[1] == L't') {
//
// Strip off the preceding format specifier
//
WideStringClass text = Title.Peek_Buffer () + 2;
Title = text;
//
// Keep in mind that this is a "Title"
//
IsTitle = true;
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_TITLE);
StyleMgrClass::Assign_Font (&GlowRenderer, StyleMgrClass::FONT_TITLE);
GlowRenderer.Build_Sentence (Title);
} else if (Title[0] == L'%' && Title[1] == L'h') {
//
// Support a "header" style font
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_LG_CONTROLS);
//
// Strip off the preceding format specifier
//
WideStringClass text = Title.Peek_Buffer () + 2;
Title = text;
} else if (Title[0] == L'%' && Title[1] == L's') {
//
// Support a "small" style font
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_TOOLTIPS);
//
// Strip off the preceding format specifier
//
WideStringClass text = Title.Peek_Buffer () + 2;
Title = text;
}
}
return ;
}

95
Code/wwui/dialogtext.h Normal file
View File

@@ -0,0 +1,95 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogtext.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/26/01 12:25p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_TEXT_H
#define __DIALOG_TEXT_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2d.h"
#include "render2dsentence.h"
////////////////////////////////////////////////////////////////
//
// DialogTextClass
//
////////////////////////////////////////////////////////////////
class DialogTextClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
DialogTextClass (void);
virtual ~DialogTextClass (void) {}
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
// RTTI
DialogTextClass *As_DialogTextClass (void) { return (this); }
//
// From DialogControlClass
//
void Render (void);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_Create (void);
void Create_Text_Renderer (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DSentenceClass GlowRenderer;
Render2DClass ControlRenderer;
bool IsTitle;
};
#endif //__DIALOG_TEXT_H

View File

@@ -0,0 +1,62 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogtransition.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/27/01 8:51a $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dialogtransition.h"
#include "dialogmgr.h"
////////////////////////////////////////////////////////////////
//
// DialogTransitionClass
//
////////////////////////////////////////////////////////////////
DialogTransitionClass::DialogTransitionClass (TYPE type) :
Type (type)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// ~DialogTransitionClass
//
////////////////////////////////////////////////////////////////
DialogTransitionClass::~DialogTransitionClass (void)
{
return ;
}

View File

@@ -0,0 +1,113 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dialogtransition.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/27/01 9:56a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DIALOG_TRANSITION_H
#define __DIALOG_TRANSITION_H
#include "refcount.h"
///////////////////////////////////////////////////////////////////////////////
//
// DialogTransitionClass
//
///////////////////////////////////////////////////////////////////////////////
class DialogTransitionClass : public RefCountClass
{
public:
////////////////////////////////////////////////////////////////////////
// Public constants
////////////////////////////////////////////////////////////////////////
enum TYPE
{
SCREEN_OUT = 0,
SCREEN_IN
};
////////////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////////////
DialogTransitionClass (TYPE type = SCREEN_OUT);
virtual ~DialogTransitionClass (void);
////////////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////////////
//
// Configuration
//
virtual void Set_Type (TYPE type) { Type = type; }
TYPE Get_Type (void) const { return Type; }
//
// Frame updates
//
virtual void Render (void) {}
virtual void On_Frame_Update (void) {}
//
// Flow control
//
virtual bool Is_Complete (void) { return true; }
protected:
////////////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////////////
//virtual void Update_Renderer (void);
////////////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////////////
//Render2DClass Renderer;
//Render2DClass SwipeRenderer;
TYPE Type;
//int MaxTime;
//int Timer;
};
#endif //__DIALOG_TRANSITION_H

783
Code/wwui/dropdownctrl.cpp Normal file
View File

@@ -0,0 +1,783 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dropdownctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/07/02 10:42a $*
* *
* $Revision:: 17 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
#pragma warning(disable : 4530)
#include "dropdownctrl.h"
#include "comboboxctrl.h"
#include "dialogbase.h"
#include "assetmgr.h"
#include "refcount.h"
#include "font3d.h"
#include "mousemgr.h"
#include "ww3d.h"
#include "dialogmgr.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// DropDownCtrlClass
//
////////////////////////////////////////////////////////////////
DropDownCtrlClass::DropDownCtrlClass (void) :
CellSize (0, 0),
CurrSel (-1),
ComboBox (NULL),
ScrollPos (0),
CountPerPage (0),
FullRect (0, 0, 0, 0),
DisplayScrollBar (false)
{
//
// Set the font for the text renderers
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_LISTS);
//
// We don't want the scroll bar getting focus
//
ScrollBarCtrl.Set_Wants_Focus (false);
ScrollBarCtrl.Set_Small_BMP_Mode (true);
ScrollBarCtrl.Set_Advise_Sink (this);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~DropDownCtrlClass
//
////////////////////////////////////////////////////////////////
DropDownCtrlClass::~DropDownCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderer
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Create_Text_Renderer (void)
{
HilightRenderer.Reset ();
HilightRenderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
StyleMgrClass::Configure_Hilighter (&HilightRenderer);
//
// Setup the coordinate system of the renderer
//
TextRenderer.Reset ();
//
// Add each string to the list
//
float curr_y_pos = ClientRect.Top;
for (int index = ScrollPos; index < EntryList.Count (); index ++) {
//
// Get the width and height of the current entry
//
const WCHAR *text = EntryList[index].text;
Vector2 text_extent = TextRenderer.Get_Text_Extents (text);
//
// Build a rectangle we'll draw the text into
//
RectClass text_rect;
text_rect.Left = ClientRect.Left;
text_rect.Top = curr_y_pos;
text_rect.Right = text_rect.Left + CellSize.X;
text_rect.Bottom = text_rect.Top + CellSize.Y;
if (text_rect.Bottom <= ClientRect.Bottom) {
//
// Draw the text
//
StyleMgrClass::Render_Text (text, &TextRenderer, text_rect, true, true);
//
// Hilight this entry (if its the currently selected one)
//
if (index == CurrSel) {
StyleMgrClass::Render_Hilight (&HilightRenderer, text_rect);
}
}
//
// Move on to the next y-position
//
curr_y_pos += CellSize.Y;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Control_Renderer
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Create_Control_Renderer (void)
{
//
// Configure this renderer
//
ControlRenderer.Reset ();
ControlRenderer.Enable_Texturing (false);
ControlRenderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
ControlRenderer.Add_Quad (FullRect, RGBA_TO_INT32 (0, 0, 0, 236));
//
// Lookup the colors to use
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
//
// Draw the control outline
//
RectClass rect = Rect;
ControlRenderer.Add_Outline (rect, 1.0F, color);
//
// Now draw the background
//
rect.Right -= 1;
rect.Bottom -= 1;
ControlRenderer.Add_Quad (rect, bkcolor);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor if necessary
//
if (ClientRect.Contains (mouse_pos)) {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Update_Client_Rect (void)
{
Rect = FullRect;
//
// Determine what one character spacing would be
//
Vector2 char_size = TextRenderer.Get_Text_Extents (L"W");
float border_width = char_size.X + 2;
float border_height = 2;
//
// Shrink the client area
//
ClientRect = Rect;
ClientRect.Inflate (Vector2 (-border_width, -border_height));
//
// Calculate how each "text" cell should be
//
CellSize.X = int(ClientRect.Width ());
CellSize.Y = int(char_size.Y * 1.5F);
//
// Update the number of entries we can display at one time
//
CountPerPage = int(ClientRect.Height () / CellSize.Y);
//
// Do we need to show a scroll bar?
//
if (CountPerPage < EntryList.Count ()) {
float width = (char_size.X * 3);
//
// Calculate the width of the scroll bar
//
RectClass scroll_rect;
scroll_rect.Left = Rect.Right - width;
scroll_rect.Top = Rect.Top;
scroll_rect.Right = Rect.Right;
scroll_rect.Bottom = Rect.Bottom;
//
// Size the scroll bar
//
ScrollBarCtrl.Set_Window_Rect (scroll_rect);
ScrollBarCtrl.Set_Page_Size (CountPerPage - 1);
ScrollBarCtrl.Set_Range (0, EntryList.Count () - CountPerPage);
DisplayScrollBar = true;
//
// Shrink the client area
//
float new_width = ScrollBarCtrl.Get_Window_Rect ().Left;
ClientRect.Right = new_width;
Rect.Right = new_width;
CellSize.X = int(ClientRect.Width ());
}
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderer ();
Create_Text_Renderer ();
}
//
// Render the background and text for the current state
//
ControlRenderer.Render ();
TextRenderer.Render ();
HilightRenderer.Render ();
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
Set_Curr_Sel (Entry_From_Pos (mouse_pos));
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
Set_Curr_Sel (Entry_From_Pos (mouse_pos));
if (ComboBox) {
ComboBox->On_Drop_Down_End (CurrSel);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Move
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
{
if (DialogMgrClass::Is_Button_Down (VK_LBUTTON)) {
Set_Curr_Sel (Entry_From_Pos (mouse_pos));
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
DropDownCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
bool handled = true;
switch (key_id)
{
case VK_HOME:
Set_Curr_Sel (0);
break;
case VK_END:
Set_Curr_Sel (EntryList.Count () - 1);
break;
case VK_UP:
case VK_LEFT:
Set_Curr_Sel (CurrSel - 1);
break;
case VK_DOWN:
case VK_RIGHT:
Set_Curr_Sel (CurrSel + 1);
break;
default:
handled = false;
break;
}
return handled;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_Create (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
//
// Noitify the combobox that we are done
//
if (ComboBox) {
ComboBox->On_Drop_Down_End (CurrSel);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Add_String
//
////////////////////////////////////////////////////////////////
int
DropDownCtrlClass::Add_String (const WCHAR* string)
{
if (string == NULL) {
return -1;
}
//
// Add the entry to the list
//
EntryList.Add (ENTRY (string, 0));
//
// Force scrollbars, etc to be recalculated and painted
//
Update_Client_Rect ();
Set_Dirty ();
return (EntryList.Count () - 1);
}
////////////////////////////////////////////////////////////////
//
// Delete_String
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Delete_String (int index)
{
if (index >= 0 && index < EntryList.Count ()) {
//
// Delete the entry
//
EntryList.Delete (index);
Set_Curr_Sel (min (CurrSel, EntryList.Count () - 1));
Set_Dirty ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Find_String
//
////////////////////////////////////////////////////////////////
int
DropDownCtrlClass::Find_String (const WCHAR* string)
{
int retval = -1;
if (string) {
for (int index = 0; index < EntryList.Count (); index ++) {
//
// If this is the entry the user is requesting, then
// return its index to the caller
//
if (EntryList[index].text.Compare_No_Case (string) == 0) {
retval = index;
break;
}
}
}
return retval;
}
int DropDownCtrlClass::Find_Closest_String(const WCHAR* string)
{
int retval = -1;
if (string && (wcslen(string) > 0)) {
for (int index = 0; index < EntryList.Count (); index ++) {
int relation = EntryList[index].text.Compare_No_Case(string);
if (relation == 0) {
return index;
} else if (relation < 0) {
return index;
}
}
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Set_Item_Data
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Set_Item_Data (int index, uint32 data)
{
//
// Index into the list and set the user data
//
if (index >= 0 && index < EntryList.Count ()) {
EntryList[index].user_data = data;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_Item_Data
//
////////////////////////////////////////////////////////////////
uint32
DropDownCtrlClass::Get_Item_Data (int index)
{
uint32 retval = 0;
//
// Index into the list and return the user data to the caller
//
if (index >= 0 && index < EntryList.Count ()) {
retval = EntryList[index].user_data;
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Reset_Content
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Reset_Content (void)
{
//
// Remove everything from the list
//
EntryList.Delete_All ();
Set_Curr_Sel (0);
//
// Repaint the control
//
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Entry_From_Pos
//
////////////////////////////////////////////////////////////////
int
DropDownCtrlClass::Entry_From_Pos (const Vector2 &mouse_pos)
{
int retval = 0;
//
// Loop over all the entries in our current view
//
float curr_y_pos = ClientRect.Top;
for (int index = ScrollPos; index < EntryList.Count (); index ++) {
retval = index;
//
// Is ths mouse over this entry?
//
if ( (mouse_pos.Y >= curr_y_pos &&
mouse_pos.Y <= (curr_y_pos + CellSize.Y)) ||
mouse_pos.Y > ClientRect.Bottom)
{
break;
}
//
// Move on to the next y-position
//
curr_y_pos += CellSize.Y;
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Set_Curr_Sel
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Set_Curr_Sel (int index)
{
if (index >= -1 && index < EntryList.Count () && CurrSel != index) {
//
// Change the selection
//
CurrSel = index;
//
// Update our current scroll position
//
Update_Scroll_Pos ();
//
// Repaint the view
//
Set_Dirty ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_String
//
////////////////////////////////////////////////////////////////
bool
DropDownCtrlClass::Get_String (int index, WideStringClass &string) const
{
bool retval = false;
if (index >= 0 && index < EntryList.Count ()) {
//
// Index into the entry list and return the string
//
string = EntryList[index].text;
retval = true;
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Get_String
//
////////////////////////////////////////////////////////////////
const WCHAR *
DropDownCtrlClass::Get_String (int index) const
{
const WCHAR *retval = NULL;
if (index >= 0 && index < EntryList.Count ()) {
//
// Index into the entry list and return the string
//
retval = EntryList[index].text;
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Update_Scroll_Pos
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::Update_Scroll_Pos (void)
{
if (CurrSel == -1) {
return;
}
if (CurrSel < ScrollPos) {
//
// Scroll up so the current selection is in view
//
ScrollPos = CurrSel;
Set_Dirty ();
} else if (CurrSel >= ScrollPos + CountPerPage) {
//
// Scroll down so the current selection is in view
//
ScrollPos = max (CurrSel - (CountPerPage - 1), 0);
Set_Dirty ();
}
//
// Update the scrollbar
//
ScrollBarCtrl.Set_Pos (ScrollPos, false);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Add_To_Dialog
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_Add_To_Dialog (void)
{
if (DisplayScrollBar) {
Parent->Add_Control (&ScrollBarCtrl);
}
TextColor.Set (0.35F, 1.0F, 0.35F);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Remove_From_Dialog
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_Remove_From_Dialog (void)
{
if (DisplayScrollBar) {
Parent->Remove_Control (&ScrollBarCtrl);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_VScroll
//
////////////////////////////////////////////////////////////////
void
DropDownCtrlClass::On_VScroll (ScrollBarCtrlClass *, int , int new_position)
{
ScrollPos = new_position;
Set_Dirty ();
return ;
}

186
Code/wwui/dropdownctrl.h Normal file
View File

@@ -0,0 +1,186 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/dropdownctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/16/01 10:27p $*
* *
* $Revision:: 10 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DROPDOWN_CTRL_H
#define __DROPDOWN_CTRL_H
#include "dialogcontrol.h"
#include "vector.h"
#include "render2dsentence.h"
#include "bittype.h"
#include "scrollbarctrl.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class ComboBoxCtrlClass;
////////////////////////////////////////////////////////////////
//
// DropDownCtrlClass
//
////////////////////////////////////////////////////////////////
class DropDownCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
DropDownCtrlClass (void);
virtual ~DropDownCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void Render (void);
//
// Content control
//
int Add_String (const WCHAR* string);
void Delete_String (int index);
int Find_String (const WCHAR* string);
int Find_Closest_String(const WCHAR* string);
void Set_Item_Data (int index, uint32 data);
uint32 Get_Item_Data (int index);
void Reset_Content (void);
//
// Information accessors
//
bool Get_String (int index, WideStringClass &string) const;
const WCHAR * Get_String (int index) const;
int Get_Count (void) { return EntryList.Count (); }
//
// Selection management
//
void Set_Curr_Sel (int index);
int Get_Curr_Sel (void) const { return CurrSel; }
//
// Combobox access
//
ComboBoxCtrlClass * Get_Combo_Box (void) const { return ComboBox; }
void Set_Combo_Box (ComboBoxCtrlClass *ctrl) { ComboBox = ctrl; }
void Set_Full_Rect (const RectClass &rect) { FullRect = rect; }
//
// Advise-sink callbacks
//
void On_VScroll (ScrollBarCtrlClass *scrollbar, int ctrl_id, int new_position);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Kill_Focus (DialogControlClass *focus);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Create (void);
void On_Add_To_Dialog (void);
void On_Remove_From_Dialog (void);
void Update_Client_Rect (void);
void Create_Control_Renderer (void);
void Create_Text_Renderer (void);
int Entry_From_Pos (const Vector2 &mouse_pos);
void Update_Scroll_Pos (void);
////////////////////////////////////////////////////////////////
// Protected data types
////////////////////////////////////////////////////////////////
typedef struct _ENTRY
{
WideStringClass text;
uint32 user_data;
bool operator== (const _ENTRY &src) { return false; }
bool operator!= (const _ENTRY &src) { return true; }
_ENTRY (void) :
user_data (0) {}
_ENTRY (const WCHAR *_text, uint32 _data) :
text (_text), user_data (_data) {}
} ENTRY;
typedef DynamicVectorClass<ENTRY> ENTRY_LIST;
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DClass ControlRenderer;
Render2DClass HilightRenderer;
ENTRY_LIST EntryList;
ComboBoxCtrlClass * ComboBox;
Vector2 CellSize;
ScrollBarCtrlClass ScrollBarCtrl;
RectClass FullRect;
RectClass ScrollBarRect;
int CurrSel;
int ScrollPos;
int CountPerPage;
bool DisplayScrollBar;
bool ButtonClickedOnMe;
int DisplayTime;
};
#endif //__DROPDOWN_CTRL_H

1532
Code/wwui/editctrl.cpp Normal file

File diff suppressed because it is too large Load Diff

180
Code/wwui/editctrl.h Normal file
View File

@@ -0,0 +1,180 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/editctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/09/02 11:09a $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __EDIT_CTRL_H
#define __EDIT_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
#include "bittype.h"
#include "IMEManager.h"
#include "IMECandidateCtrl.h"
#include "ToolTip.h"
////////////////////////////////////////////////////////////////
//
// EditCtrlClass
//
////////////////////////////////////////////////////////////////
class EditCtrlClass :
public DialogControlClass,
public Observer<IME::CompositionEvent>,
public Observer<IME::CandidateEvent>
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
EditCtrlClass (void);
virtual ~EditCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// RTTI
//
EditCtrlClass * As_EditCtrlClass (void) { return this; }
//
// From DialogControlClass
//
void Render (void);
virtual void Set_Text (const WCHAR *title);
int Get_Text_Length (void) const;
void Set_Text_Limit (int numChars);
int Get_Text_Limit (void) const;
//
// Content control
//
bool Delete_Selection (void);
int Get_Int (void);
void Set_Int (int value);
//
// Caret and selection support
//
int Get_Caret_Pos (void) const;
void Set_Caret_Pos (int new_pos);
void Set_Sel (int start_index, int end_index);
void Get_Sel (int &start_index, int &end_index) const;
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *focus);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Create (void);
void Update_Client_Rect (void);
void Create_Control_Renderers (void);
void Create_Text_Renderers (void);
void Create_Caret_Renderer (void);
void Update_Caret (void);
int Character_From_Pos (const Vector2 &mouse_pos);
float Pos_From_Character (int char_index);
void On_Unicode_Char (WCHAR unicode);
void Insert_String (const WCHAR *string);
void Update_Hilight (int new_pos, int anchor_pos);
int Find_Word_Start (int pos, int increment);
void Update_Scroll_Pos (void);
bool IsIMEAllowed(void) const;
void Set_IME_Typing_Text_Pos(void);
void Show_IME_Typing_Text(const wchar_t* text);
void Hide_IME_Typing_Text(void);
void PositionCandidateList(void);
void Get_Display_Text (WideStringClass &text);
void HandleNotification(IME::CompositionEvent&);
void HandleNotification(IME::CandidateEvent&);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DClass ControlRenderer;
Render2DClass CaretRenderer;
Render2DClass HilightRenderer;
bool IsCaretDisplayed;
uint32 CaretBlinkDelay;
uint32 LastCaretBlink;
int CaretPos;
int ScrollPos;
int NumChars;
int TextLimit;
int HilightAnchorPos;
int HilightStartPos;
int HilightEndPos;
bool WasButtonPressedOnMe;
IME::IMEManager* mIME;
bool mInComposition;
#ifdef SHOW_IME_TYPING
bool mShowIMETypingText;
ToolTipClass mIMETypingTip;
#endif
IMECandidateCtrl mCandidateList;
};
#endif //__EDIT_CTRL_H

232
Code/wwui/healthbarctrl.cpp Normal file
View File

@@ -0,0 +1,232 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwui *
* *
* $Archive:: /Commando/Code/wwui/healthbarctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/25/01 4:33p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "healthbarctrl.h"
#include "texture.h"
#include "assetmgr.h"
#include "stylemgr.h"
//////////////////////////////////////////////////////////////////////
// Local constants
//////////////////////////////////////////////////////////////////////
static const char * TEXTURE_NAME = "HUD_C&C_HEALTHBAR.TGA";
static const Vector2 TEXTURE_SIZE = Vector2 (16, 16);
//////////////////////////////////////////////////////////////////////
//
// HealthBarCtrlClass
//
//////////////////////////////////////////////////////////////////////
HealthBarCtrlClass::HealthBarCtrlClass (void) :
Percent (1.0F)
{
//
// Configure the renderer
//
StyleMgrClass::Configure_Renderer (&ControlRenderer);
ControlRenderer.Enable_Texturing (true);
ControlRenderer.Enable_Alpha (true);
//
// Load the texture we'll use
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture (TEXTURE_NAME, TextureClass::MIP_LEVELS_1);
ControlRenderer.Set_Texture (texture);
REF_PTR_RELEASE (texture);
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~HealthBarCtrlClass
//
//////////////////////////////////////////////////////////////////////
HealthBarCtrlClass::~HealthBarCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Blit_Section
//
////////////////////////////////////////////////////////////////
static void
Blit_Section
(
Render2DClass & renderer,
const Vector2 & screen_pos,
const Vector2 & texture_pos,
const Vector2 & pixels,
const Vector2 & texture_dimensions,
int color
)
{
RectClass screen_rect;
screen_rect.Left = screen_pos.X;
screen_rect.Top = screen_pos.Y;
screen_rect.Right = screen_rect.Left + pixels.X;
screen_rect.Bottom = screen_rect.Top + pixels.Y;
//
// Determine the UV coordinates
//
RectClass uv_rect (texture_pos.X, texture_pos.Y, texture_pos.X + pixels.X, texture_pos.Y + pixels.Y);
uv_rect.Inverse_Scale (Vector2 (texture_dimensions.X, texture_dimensions.Y));
//
// Draw the chunk
//
renderer.Add_Quad (screen_rect, uv_rect, color);
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Create_Control_Renderer
//
//////////////////////////////////////////////////////////////////////
void
HealthBarCtrlClass::Create_Control_Renderer (void)
{
Render2DClass &renderer = ControlRenderer;
renderer.Reset ();
//
// Determine what color to draw the bar in
//
int color = RGB_TO_INT32 (0, 255, 0);
if (Percent <= 0.25F) {
color = RGB_TO_INT32 (255, 0, 0);
} else if (Percent <= 0.5F) {
color = RGB_TO_INT32 (255, 255, 0);
}
//
// Calculate how long to draw the texture
//
float full_width = Rect.Width ();
int width = (full_width * Percent);
Vector2 size1 (8.0F, 12.0F);
Vector2 size2 (7.0F, 12.0F);
Vector2 texture_pos1 (0.0F, 2.0F);
Vector2 texture_pos2 (9.0F, 2.0F);
Vector2 *size = &size1;
Vector2 *texture_pos = &texture_pos1;
//
// Tile the sections horizontally until we've reached our edge
//
int index = 0;
float remaining_width = width;
float x_pos = Rect.Left;
while (remaining_width > 0) {
size->X = min (remaining_width, size->X);
//
// Draw this section
//
::Blit_Section (ControlRenderer, Vector2 (x_pos, Rect.Top), *texture_pos,
*size, TEXTURE_SIZE, color);
//
// Advance to the next section
//
x_pos += size->X;
remaining_width -= size->X;
//
// Advance to the next texture chunk
//
index ++;
if (index > 0) {
size = &size2;
texture_pos = &texture_pos2;
}
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Life
//
//////////////////////////////////////////////////////////////////////
void
HealthBarCtrlClass::Set_Life (float value)
{
Percent = value;
//
// Force an update
//
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
HealthBarCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderer ();
}
//
// Render the bar...
//
ControlRenderer.Render ();
DialogControlClass::Render ();
return ;
}

95
Code/wwui/healthbarctrl.h Normal file
View File

@@ -0,0 +1,95 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwui *
* *
* $Archive:: /Commando/Code/wwui/healthbarctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/25/01 3:55p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __HEALTHBARCTRL_H
#define __HEALTHBARCTRL_H
#include "render2d.h"
#include "dialogcontrol.h"
//////////////////////////////////////////////////////////////////////
//
// HealthBarCtrlClass
//
//////////////////////////////////////////////////////////////////////
class HealthBarCtrlClass : public DialogControlClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
HealthBarCtrlClass (void);
virtual ~HealthBarCtrlClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// Inherited
//
void Render (void);
//
// Configuration
//
void Set_Life (float value);
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
void Create_Control_Renderer (void);
void Create_Texture_Renderer (void);
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
Render2DClass ControlRenderer;
Render2DClass TextureRenderer;
float Percent;
};
#endif //__HEALTHBARCTRL_H

176
Code/wwui/imagectrl.cpp Normal file
View File

@@ -0,0 +1,176 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwui *
* *
* $Archive:: /Commando/Code/wwui/imagectrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/22/01 4:12p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "imagectrl.h"
#include "texture.h"
#include "assetmgr.h"
#include "stylemgr.h"
//////////////////////////////////////////////////////////////////////
//
// ImageCtrlClass
//
//////////////////////////////////////////////////////////////////////
ImageCtrlClass::ImageCtrlClass (void)
{
//
// Configure the renderers
//
StyleMgrClass::Configure_Renderer (&ControlRenderer);
StyleMgrClass::Configure_Renderer (&TextureRenderer);
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~ImageCtrlClass
//
//////////////////////////////////////////////////////////////////////
ImageCtrlClass::~ImageCtrlClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Create_Control_Renderer
//
//////////////////////////////////////////////////////////////////////
void
ImageCtrlClass::Create_Control_Renderer (void)
{
Render2DClass &renderer = ControlRenderer;
//
// Configure this renderer
//
renderer.Reset ();
renderer.Enable_Texturing (false);
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
}
//
// Draw the control's outline
//
if ( Style & WS_BORDER == WS_BORDER ) {
renderer.Add_Outline (Rect, 1.0F, color);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Create_Texture_Renderer
//
//////////////////////////////////////////////////////////////////////
void
ImageCtrlClass::Create_Texture_Renderer (void)
{
Render2DClass &renderer = TextureRenderer;
//
// Simply draw the texture inside the control
//
renderer.Reset ();
if (renderer.Peek_Texture () != NULL) {
renderer.Add_Quad (Rect);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Texture
//
//////////////////////////////////////////////////////////////////////
void
ImageCtrlClass::Set_Texture (const char *texture_name)
{
//
// Assign the texture to the renderer
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_name, TextureClass::MIP_LEVELS_1);
TextureRenderer.Set_Texture (texture);
REF_PTR_RELEASE (texture);
//
// Force an update
//
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
ImageCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderer ();
Create_Texture_Renderer ();
}
//
// Render the image...
//
TextureRenderer.Render ();
ControlRenderer.Render ();
DialogControlClass::Render ();
return ;
}

94
Code/wwui/imagectrl.h Normal file
View File

@@ -0,0 +1,94 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwui *
* *
* $Archive:: /Commando/Code/wwui/imagectrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/30/01 9:51a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __IMAGECTRL_H
#define __IMAGECTRL_H
#include "render2d.h"
#include "dialogcontrol.h"
//////////////////////////////////////////////////////////////////////
//
// ImageCtrlClass
//
//////////////////////////////////////////////////////////////////////
class ImageCtrlClass : public DialogControlClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
ImageCtrlClass (void);
virtual ~ImageCtrlClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// Inherited
//
void Render (void);
//
// Configuration
//
void Set_Texture (const char *texture_name);
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
void Create_Control_Renderer (void);
void Create_Texture_Renderer (void);
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
Render2DClass ControlRenderer;
Render2DClass TextureRenderer;
};
#endif //__IMAGECTRL_H

411
Code/wwui/inputctrl.cpp Normal file
View File

@@ -0,0 +1,411 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/inputctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/17/02 11:18a $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "inputctrl.h"
#include "assetmgr.h"
#include "refcount.h"
#include "font3d.h"
#include "mousemgr.h"
#include "ww3d.h"
#include "dialogmgr.h"
#include "dialogbase.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
//
// InputCtrlClass
//
////////////////////////////////////////////////////////////////
InputCtrlClass::InputCtrlClass (void) :
KeyAssignment (0),
MouseIgnoreTime (0),
UserData (0),
PendingKeyID (-1)
{
//
// Set the font for the text renderers
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_CONTROLS);
StyleMgrClass::Configure_Renderer (&ControlRenderer);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~InputCtrlClass
//
////////////////////////////////////////////////////////////////
InputCtrlClass::~InputCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderers
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::Create_Text_Renderers (void)
{
HilightRenderer.Reset ();
HilightRenderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
StyleMgrClass::Configure_Hilighter (&HilightRenderer);
//
// Start fresh
//
TextRenderer.Reset ();
//
// Draw the text
//
StyleMgrClass::Render_Text (Title, &TextRenderer, ClientRect, true, true,
StyleMgrClass::CENTER_JUSTIFY, IsEnabled);
//
// Do the hilight
//
if (HasFocus) {
StyleMgrClass::Render_Hilight (&HilightRenderer, ClientRect);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Control_Renderers
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::Create_Control_Renderers (void)
{
Render2DClass &renderer = ControlRenderer;
//
// Configure this renderer
//
renderer.Reset ();
renderer.Enable_Texturing (false);
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
}
//
// Draw the outline
//
renderer.Add_Outline (Rect, 1.0F, color);
//
// Now draw the background
//
RectClass rect = Rect;
rect.Right -= 1;
rect.Bottom -= 1;
renderer.Add_Quad (rect, bkcolor);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor
//
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::Update_Client_Rect (void)
{
//
// Set the client area
//
ClientRect = Rect;
ClientRect.Inflate (Vector2 (-1, -1));
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::Render (void)
{
if (PendingKeyID != -1) {
//
// Use the pending key
//
if (PendingKeyID >= 0 && PendingKeyID <= 256) {
On_New_Key (PendingKeyID);
}
PendingKeyID = -1;
}
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderers ();
Create_Text_Renderers ();
}
//
// Render the background and text for the current state
//
ControlRenderer.Render ();
TextRenderer.Render ();
HilightRenderer.Render ();
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
if (HasFocus && DialogMgrClass::Get_Time () > MouseIgnoreTime) {
On_New_Key (VK_LBUTTON);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_RButton_Down
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_RButton_Down (const Vector2 &mouse_pos)
{
if (HasFocus) {
On_New_Key (VK_RBUTTON);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_MButton_Down
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_MButton_Down (const Vector2 &mouse_pos)
{
if (HasFocus) {
On_New_Key (VK_MBUTTON);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Focus
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_Set_Focus (void)
{
//
// Ignore mouse input for one second
//
MouseIgnoreTime = DialogMgrClass::Get_Time () + 500;
Set_Dirty ();
DialogControlClass::On_Set_Focus ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
Set_Dirty ();
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_New_Key
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_New_Key (int vkey_id)
{
if (Parent != NULL) {
WideStringClass key_name;
int game_key_id = 0;
//
// Get information about this key from the parent
//
if (Parent->On_InputCtrl_Get_Key_Info (this, Get_ID (), vkey_id, key_name, &game_key_id)) {
//
// Display this information in the control
//
Set_Key_Assignment (game_key_id, key_name);
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Key_Assignment
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::Set_Key_Assignment (int game_key_id, const WideStringClass &key_name)
{
KeyAssignment = game_key_id;
Title = key_name;
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
InputCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
PendingKeyID = key_id;
return false;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_Create (void)
{
Title = L"";
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Wheel
//
////////////////////////////////////////////////////////////////
void
InputCtrlClass::On_Mouse_Wheel (int direction)
{
if (HasFocus) {
if (direction < 0) {
On_New_Key (VK_MOUSEWHEEL_UP);
} else {
On_New_Key (VK_MOUSEWHEEL_DOWN);
}
}
return ;
}

128
Code/wwui/inputctrl.h Normal file
View File

@@ -0,0 +1,128 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/inputctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/15/02 6:33p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __INPUTBOX_CTRL_H
#define __INPUTBOX_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
#include "bittype.h"
////////////////////////////////////////////////////////////////
// Special virtual keys
////////////////////////////////////////////////////////////////
#define VK_MOUSEWHEEL_UP 0x100
#define VK_MOUSEWHEEL_DOWN 0x101
////////////////////////////////////////////////////////////////
//
// InputCtrlClass
//
////////////////////////////////////////////////////////////////
class InputCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
InputCtrlClass (void);
virtual ~InputCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void Render (void);
//
// Key assignment access
//
int Get_Key_Assignment (void) const { return KeyAssignment; }
void Set_Key_Assignment (int game_key_id, const WideStringClass &key_name);
//
// User data support
//
uint32 Get_User_Data (void) { return UserData; }
void Set_User_Data (uint32 data) { UserData = data; }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_RButton_Down (const Vector2 &mouse_pos);
void On_MButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *focus);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Create (void);
void On_Mouse_Wheel (int direction);
void Update_Client_Rect (void);
void On_New_Key (int vkey_id);
void Create_Control_Renderers (void);
void Create_Text_Renderers (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DClass ControlRenderer;
Render2DClass HilightRenderer;
int KeyAssignment;
int MouseIgnoreTime;
uint32 UserData;
int PendingKeyID;
};
#endif //__INPUTBOX_CTRL_H

2512
Code/wwui/listctrl.cpp Normal file

File diff suppressed because it is too large Load Diff

485
Code/wwui/listctrl.h Normal file
View File

@@ -0,0 +1,485 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/listctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/26/01 4:10p $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __LIST_CTRL_H
#define __LIST_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "vector.h"
#include "render2d.h"
#include "bittype.h"
#include "scrollbarctrl.h"
#include "render2dsentence.h"
#include "listiconmgr.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class ListColumnClass;
class ListCtrlClass;
class ListRowClass;
class TextureClass;
////////////////////////////////////////////////////////////////
// Typedefs
////////////////////////////////////////////////////////////////
typedef int (CALLBACK *LISTCTRL_SORT_CALLBACK) (ListCtrlClass *list_ctrl, int item_index1, int item_index2, uint32 user_param);
////////////////////////////////////////////////////////////////
//
// ListCtrlClass
//
////////////////////////////////////////////////////////////////
class ListCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constants
////////////////////////////////////////////////////////////////
typedef enum
{
SORT_NONE = 0,
SORT_ASCENDING,
SORT_DESCENDING
} SORT_TYPE;
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ListCtrlClass (void);
virtual ~ListCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
// RTTI
virtual ListCtrlClass * As_ListCtrlClass (void) { return this; }
//
// From DialogControlClass
//
void Render (void);
void Set_Tabstop(float stop);
//
// Column support
//
void Auto_Size_Columns (float col_spacing = 2.0F);
void Auto_Size_Columns_Include_Contents (float col_spacing = 2.0F);
void Add_Column (const WCHAR *column_name, float width, const Vector3 &color);
void Set_Column_Color (int col_index, const Vector3 &color);
bool Remove_Column (int col_index);
void Delete_All_Columns (void);
int Get_Column_Count(void) const;
//
// Content control
//
int Find_Entry(int col_index, const WCHAR* text);
int Insert_Entry (int index, const WCHAR *text);
bool Set_Entry_Text (int index, int col_index, const WCHAR *text);
bool Set_Entry_Int (int index, int col_index, int value);
bool Set_Entry_Color (int index, int col_index, const Vector3 &color);
bool Set_Entry_Data (int index, int col_index, uint32 user_data);
bool Select_Entry (int index, bool onoff);
uint32 Get_Entry_Data (int index, int col_index);
const WCHAR * Get_Entry_Text (int index, int col_index);
bool Is_Entry_Selected (int index);
bool Delete_Entry (int index);
void Delete_All_Entries (void);
int Get_Entry_Count (void) const;
//
// Row height support
//
void Set_Min_Row_Height (int height);
int Get_Min_Row_Height (void) const { return MinRowHeight; }
//
// Icon support
//
void Add_Icon (int index, int col_index, const char *texture_name);
void Reset_Icons (int index, int col_index);
void Set_Icon_Size (float width, float height);
//
// Selection support
//
int Get_Curr_Sel (void) const { return CurrSel; }
void Set_Curr_Sel (int new_sel);
void Allow_Selection(bool onoff) {IsSelectionAllowed = onoff;}
void Allow_NoSelection(bool onoff) {IsNoSelectionAllowed = onoff;}
void Allow_Multiple_Selection (bool onoff) { IsMultipleSelection = onoff; }
int Get_First_Selected (void) const;
int Get_Next_Selected (int index) const;
void Select_All (bool select = true);
bool Toggle_Entry_Selection (int index);
//
// Sort support
//
void Sort (LISTCTRL_SORT_CALLBACK sort_callback, uint32 user_param);
void Set_Sort_Designator (int col_index, SORT_TYPE type);
void Sort_Alphabetically (int col_index, SORT_TYPE type);
//
// Scroll support
//
void Scroll_To_End (void);
//
// Advise-sink callbacks
//
void On_VScroll (ScrollBarCtrlClass *scrollbar, int ctrl_id, int new_position);
void On_VScroll_Page (ScrollBarCtrlClass *scrollbar, int ctrl_id, int direction);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Set_Sel (int new_sel, bool notify);
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_DblClk (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Mouse_Wheel (int direction);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *focus);
bool On_Key_Down (uint32 key_id, uint32 key_data);
void On_Create (void);
void On_Destroy (void);
void Update_Client_Rect (void);
void Create_Control_Renderer (void);
void Create_Text_Renderers (void);
int Entry_From_Pos (const Vector2 &mouse_pos);
int Col_From_Pos (const Vector2 &mouse_pos);
void Get_Entry_Rect (int index, RectClass &rect);
void Update_Scroll_Pos (void);
void Update_Scroll_Bar_Visibility (void);
void Update_Row_Height (int row_index);
void Quick_Sort (int start_index, int end_index, LISTCTRL_SORT_CALLBACK sort_callback, uint32 user_param);
int Find_Last_Page_Top_Entry (void);
void Scroll_Page (int direction);
int Find_End_Of_Page (void);
int Find_Top_Of_Page (int bottom_index);
void Render_Entry (const RectClass &rect, int col_index, int row_index);
static int CALLBACK Default_Sort_Callback (ListCtrlClass *list_ctrl, int item_index1, int item_index2, uint32 user_param);
////////////////////////////////////////////////////////////////
// Protected constants
////////////////////////////////////////////////////////////////
enum
{
NORMAL = 0,
DISABLED,
STATE_MAX
};
////////////////////////////////////////////////////////////////
// Protected typedefs
////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<ListColumnClass *> COL_LIST;
typedef DynamicVectorClass<ListRowClass *> ROW_LIST;
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DClass HilightRenderer;
Render2DClass ControlRenderer;
Render2DClass UnderlineRenderer;
Render2DSentenceClass HeaderRenderer;
Render2DSentenceClass TextRenderer;
ListIconMgrClass IconMgr;
int RowBorderHeight;
int ScrollPos;
int CurrSel;
int CurrState;
int LastPageTopEntryIndex;
ScrollBarCtrlClass ScrollBarCtrl;
bool IsScrollBarDisplayed;
bool IsSelectionAllowed;
bool IsNoSelectionAllowed;
bool IsMultipleSelection;
int SortColumn;
SORT_TYPE SortType;
float PulsePercent;
float PulseDirection;
float MinRowHeight;
RectClass TextRect;
RectClass HeaderRect;
COL_LIST ColList;
ROW_LIST RowInfoList;
};
////////////////////////////////////////////////////////////////
//
// ListEntryClass
//
////////////////////////////////////////////////////////////////
class ListEntryClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ListEntryClass (void) :
Name (L""),
Color (1, 1, 1),
UserData (0) {}
ListEntryClass (const WCHAR *name) :
Name (name),
Color (1, 1, 1),
UserData (0) {}
~ListEntryClass (void) { Reset_Icons (); }
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Name access
//
const WCHAR * Get_Name (void) const { return Name; }
void Set_Name (const WCHAR *name) { Name = name; }
//
// Color access
//
const Vector3 & Get_Color (void) const { return Color; }
void Set_Color (const Vector3 &color) { Color = color; }
//
// User data access
//
uint32 Get_User_Data (void) const { return UserData; }
void Set_User_Data (uint32 user_data) { UserData = user_data; }
//
// Icon support
//
int Get_Icon_Count (void) const { return IconList.Count (); }
const char * Get_Icon (int index) { return IconList[index]; }
void Add_Icon (const char *name) { IconList.Add (name); }
void Reset_Icons (void) { IconList.Delete_All (); }
private:
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
WideStringClass Name;
Vector3 Color;
uint32 UserData;
DynamicVectorClass<StringClass> IconList;
};
////////////////////////////////////////////////////////////////
//
// ListColumnClass
//
////////////////////////////////////////////////////////////////
class ListColumnClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ListColumnClass (void) :
Width (0) { Reset_Contents (); }
~ListColumnClass (void) { Free_Data (); }
////////////////////////////////////////////////////////////////
// Public operators
////////////////////////////////////////////////////////////////
bool operator== (const ListColumnClass &src) const { return false; }
bool operator!= (const ListColumnClass &src) const { return true; }
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Name access
//
const WCHAR * Get_Name (void) const { return Header.Get_Name (); }
void Set_Name (const WCHAR *name) { Header.Set_Name (name); }
//
// Width access
//
float Get_Width (void) const { return Width; }
void Set_Width (float width) { Width = width; }
//
// Color access
//
const Vector3 & Get_Color (void) const { return Header.Get_Color (); }
void Set_Color (const Vector3 &color) { Header.Set_Color (color); }
//
// Entry access
//
void Move_Entry (int old_index, int new_index);
void Swap_Entries (int index1, int index2);
int Insert_Entry (int index, const WCHAR *entry_name);
int Get_Entry_Count (void) const { return EntryList.Count (); }
bool Delete_Entry (int index);
void Delete_All_Entries (void);
void Set_Entry_Text (int index, const WCHAR *text) { EntryList[index]->Set_Name (text); }
const WCHAR * Get_Entry_Text (int index) const { return EntryList[index]->Get_Name (); }
void Set_Entry_Color (int index, const Vector3 &color) { EntryList[index]->Set_Color (color); }
const Vector3 & Get_Entry_Color (int index) const { return EntryList[index]->Get_Color (); }
void Set_Entry_Data (int index, uint32 data) { EntryList[index]->Set_User_Data (data); }
uint32 Get_Entry_Data (int index) const { return EntryList[index]->Get_User_Data (); }
int Get_Icon_Count (int index) const { return EntryList[index]->Get_Icon_Count (); }
const char * Get_Icon (int index, int icon_index) { return EntryList[index]->Get_Icon (icon_index); }
void Add_Icon (int index, const char *name) { EntryList[index]->Add_Icon (name); }
void Reset_Icons (int index) { EntryList[index]->Reset_Icons (); }
//
// Cleanup
//
void Reset_Contents (void);
private:
////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////
void Free_Data (void);
////////////////////////////////////////////////////////////////
// Private data types
////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<ListEntryClass *> ENTRY_LIST;
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
ListEntryClass Header;
ENTRY_LIST EntryList;
float Width;
};
////////////////////////////////////////////////////////////////
//
// ListRowClass
//
////////////////////////////////////////////////////////////////
class ListRowClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ListRowClass (void) :
Height (0),
IsSelected (false) { }
~ListRowClass (void) { }
////////////////////////////////////////////////////////////////
// Public operators
////////////////////////////////////////////////////////////////
bool operator== (const ListRowClass &src) const { return false; }
bool operator!= (const ListRowClass &src) const { return true; }
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Height access
//
float Get_Height (void) const { return Height; }
void Set_Height (float height) { Height = height; }
//
// Selection access
//
bool Is_Selected (void) const { return IsSelected; }
void Select (bool onoff) { IsSelected = onoff; }
private:
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
float Height;
bool IsSelected;
};
#endif //__LIST_CTRL_H

236
Code/wwui/listiconmgr.cpp Normal file
View File

@@ -0,0 +1,236 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwui *
* *
* $Archive:: /Commando/Code/wwui/listiconmgr.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/26/01 2:48p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "listiconmgr.h"
#include "stylemgr.h"
#include "assetmgr.h"
#include "texture.h"
#include "render2d.h"
////////////////////////////////////////////////////////////////
//
// ListIconMgrClass
//
////////////////////////////////////////////////////////////////
ListIconMgrClass::ListIconMgrClass (void) :
IconWidth (16),
IconHeight (16)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Add_Icon
//
////////////////////////////////////////////////////////////////
void
ListIconMgrClass::Add_Icon (const char *texture_name)
{
//
// Make sure this texture isn't already in our lists
//
int index = Find_Texture (texture_name);
if (index == -1) {
//
// Load the texture
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_name, TextureClass::MIP_LEVELS_1);
if (texture != NULL) {
//
// Create a new renderer and assign it the texture
//
Render2DClass *renderer = new Render2DClass;
StyleMgrClass::Configure_Renderer (renderer);
renderer->Set_Texture (texture);
renderer->Enable_Alpha (true);
//
// Add this renderer to our list
//
Renderers.Add (renderer);
TextureNames.Add (texture_name);
//
// Release our hold on the texture
//
REF_PTR_RELEASE (texture);
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Remove_Icon
//
////////////////////////////////////////////////////////////////
void
ListIconMgrClass::Remove_Icon (const char *texture_name)
{
//
// Try to find the texture in our list
//
int index = Find_Texture (texture_name);
if (index >= 0) {
//
// Remove this entry from out lists
//
delete Renderers[index];
Renderers.Delete (index);
TextureNames.Delete (index);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Reset_Icons
//
////////////////////////////////////////////////////////////////
void
ListIconMgrClass::Reset_Icons (void)
{
//
// First, free each renderer
//
for (int index = 0; index < Renderers.Count (); index ++) {
delete Renderers[index];
}
//
// Now, reset the lists
//
Renderers.Delete_All ();
TextureNames.Delete_All ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render_Icon
//
////////////////////////////////////////////////////////////////
void
ListIconMgrClass::Render_Icon (const RectClass &clip_rect, const char *texture_name)
{
//
// Try to find the texture in our list
//
int index = Find_Texture (texture_name);
if (index >= 0) {
float icon_size_x = IconWidth * StyleMgrClass::Get_X_Scale ();
float icon_size_y = IconHeight * StyleMgrClass::Get_Y_Scale ();
//
// Render the texture left-aligned and v-centered in the clip rectangle
//
RectClass rect;
rect.Left = clip_rect.Left;
rect.Right = clip_rect.Left + icon_size_x;
rect.Top = int (clip_rect.Center ().Y - (icon_size_y * 0.5F));
rect.Bottom = int (clip_rect.Center ().Y + (icon_size_y * 0.5F));
Renderers[index]->Add_Quad (rect);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Render_Icons
//
////////////////////////////////////////////////////////////////
void
ListIconMgrClass::Render_Icons (void)
{
for (int index = 0; index < Renderers.Count (); index ++) {
Renderers[index]->Render ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Find_Texture
//
////////////////////////////////////////////////////////////////
int
ListIconMgrClass::Find_Texture (const char *texture_name)
{
int retval = -1;
//
// Try to find a texture with this name in our list
//
for (int index = 0; index < TextureNames.Count (); index ++) {
if (::lstrcmpi (texture_name, TextureNames[index]) == 0) {
retval = index;
break;
}
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Reset_Renderers
//
////////////////////////////////////////////////////////////////
void
ListIconMgrClass::Reset_Renderers (void)
{
for (int index = 0; index < Renderers.Count (); index ++) {
Renderers[index]->Reset ();
}
return ;
}

115
Code/wwui/listiconmgr.h Normal file
View File

@@ -0,0 +1,115 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwui *
* *
* $Archive:: /Commando/Code/wwui/listiconmgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/26/01 2:49p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __LISTICONMGR_H
#define __LISTICONMGR_H
#include "vector.h"
#include "wwstring.h"
#include "stylemgr.h"
//////////////////////////////////////////////////////////////////////
// Forward declarations
//////////////////////////////////////////////////////////////////////
class Render2DClass;
class RectClass;
//////////////////////////////////////////////////////////////////////
//
// ListIconMgrClass
//
//////////////////////////////////////////////////////////////////////
class ListIconMgrClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ListIconMgrClass (void);
~ListIconMgrClass (void) { Reset_Icons (); }
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Configuration
//
void Add_Icon (const char *texture_name);
void Remove_Icon (const char *texture_name);
void Reset_Icons (void);
//
// Rendering
//
void Reset_Renderers (void);
void Render_Icon (const RectClass &clip_rect, const char *texture_name);
void Render_Icons (void);
//
// Informational
//
float Get_Icon_Width (void) { return IconWidth * StyleMgrClass::Get_X_Scale (); }
float Get_Icon_Height (void) { return IconHeight * StyleMgrClass::Get_Y_Scale (); }
void Set_Icon_Width (float width) { IconWidth = width; }
void Set_Icon_Height (float height) { IconHeight = height; }
private:
////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////
int Find_Texture (const char *texture_name);
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
DynamicVectorClass<Render2DClass *> Renderers;
DynamicVectorClass<StringClass> TextureNames;
float IconWidth;
float IconHeight;
};
#endif //__LISTICONMGR_H

1246
Code/wwui/mapctrl.cpp Normal file

File diff suppressed because it is too large Load Diff

274
Code/wwui/mapctrl.h Normal file
View File

@@ -0,0 +1,274 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/mapctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/26/01 10:44a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __MAP_CTRL_H
#define __MAP_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "vector2i.h"
#include "vector.h"
#include "render2dsentence.h"
#include "bittype.h"
////////////////////////////////////////////////////////////////
//
// MapMarkerClass
//
////////////////////////////////////////////////////////////////
class MapMarkerClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
MapMarkerClass (void) :
Position (0, 0, 0),
UVRect (0, 0, 0, 0),
Color (0xFFFFFFFF),
UserData (0) {}
virtual ~MapMarkerClass (void) {}
////////////////////////////////////////////////////////////////
// Public operators
////////////////////////////////////////////////////////////////
bool operator== (const MapMarkerClass &src) const { return false; }
bool operator!= (const MapMarkerClass &src) const { return true; }
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Accessors
//
const Vector3 & Get_Position (void) const { return Position; }
const WCHAR * Get_Name (void) const { return Name; }
const RectClass & Get_Rect (void) const { return UVRect; }
uint32 Get_User_Data (void) const { return UserData; }
uint32 Get_Color (void) const { return Color; }
void Set_Position (const Vector3 &pos) { Position = pos; }
void Set_Name (const WCHAR *name) { Name = name; }
void Set_Rect (const RectClass &rect) { UVRect = rect; }
void Set_User_Data (uint32 data) { UserData = data; }
void Set_Color (uint32 color) { Color = color; }
protected:
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Vector3 Position;
WideStringClass Name;
RectClass UVRect;
uint32 UserData;
uint32 Color;
};
////////////////////////////////////////////////////////////////
//
// MapCtrlClass
//
////////////////////////////////////////////////////////////////
class MapCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
MapCtrlClass (void);
virtual ~MapCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void Render (void);
//
// Map configuration
//
void Set_Map_Texture (const char *filename);
void Set_Marker_Texture (const char *filename);
//
// Zoom support
//
float Get_Zoom (void) const { return Zoom; }
void Set_Zoom (float factor) { Zoom = factor; Set_Dirty (); }
//
// Map centering and scale.
//
// Note: The scale means "how many pixels (of map) per meter (of world space)".
// This value can differ in the X and Y axes.
//
// The map center is the pixel position (x,y) where world space (0, 0, 0) is.
//
const Vector2 &Get_Map_Scale (void) const { return MapScale; }
void Set_Map_Scale (const Vector2 &scale) { MapScale = scale; Set_Dirty (); }
const Vector2 &Get_Map_Center (void) const { return MapCenterPoint; }
void Set_Map_Center (const Vector2 &pos) { MapCenterPoint = pos; Set_Dirty (); }
//
// Marker control
//
int Add_Marker (const WCHAR *name, const Vector3 &pos, const RectClass &uv_rect, int color = 0xFFFFFFFF);
uint32 Get_Marker_Data (int index);
void Set_Marker_Data (int index, uint32 user_data);
void Remove_Marker (int index);
//
// View support
//
void Center_View_About_Marker (int marker_index);
//
// Cloud support
//
void Initialize_Cloud (int cells_x, int cells_y);
void Reset_Cloud (void);
void Set_Cloud_Cell (int cell_x, int cell_y, bool is_visible);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *focus);
void On_Frame_Update (void);
void Update_Client_Rect (void);
void Create_Control_Renderers (void);
void Create_Text_Renderers (void);
void Create_Cloud_Renderer (void);
int Marker_From_Pos (const Vector2 &mouse_pos);
void Clamp_Scroll_Pos (void);
Vector3 Position_To_Coord (const Vector2 &mouse_pos);
bool Is_Cell_Shrouded (int cell_x, int cell_y);
void Free_Cloud_Data (void);
void Update_Pulse (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass TextRenderer;
Render2DClass ControlRenderer;
Render2DClass ButtonRenderer;
Render2DClass MapRenderer;
Render2DClass MapOverlayRenderer;
Render2DClass CloudRenderer;
Render2DClass EdgeRenderer;
Render2DClass IconRenderer;
float Zoom;
Vector2 ScrollPos;
Vector2 MapSize;
Vector2 IconTextureSize;
bool IsDragging;
bool IsZoomingIn;
bool IsZoomingOut;
bool IsUsingOverlay;
Vector2 InitialMousePos;
Vector2 InitialScrollPos;
RectClass ZoomInButtonRect;
RectClass ZoomOutButtonRect;
float PulseDirection;
float OverlayOpacity;
Vector2 MapCenterPoint;
Vector2 MapScale;
uint32 * CloudVector;
Vector2i CloudSize;
DynamicVectorClass<MapMarkerClass> MarkerList;
};
////////////////////////////////////////////////////////////////
// Is_Cell_Shrouded
////////////////////////////////////////////////////////////////
inline bool
MapCtrlClass::Is_Cell_Shrouded (int cell_x, int cell_y)
{
bool retval = true;
//
// Is this cell in bounds?
//
if ( cell_x >= 0 && cell_x < CloudSize.I &&
cell_y >= 0 && cell_y < CloudSize.J)
{
int bit_offset = (cell_y * CloudSize.I) + cell_x;
int index = bit_offset / 32;
int bit = (bit_offset - (index * 32)) + 1;
//
// Check this bit
//
retval = ((CloudVector[index] & (1 << bit)) != 0);
}
return retval;
}
#endif //__MAP_CTRL_H

272
Code/wwui/menubackdrop.cpp Normal file
View File

@@ -0,0 +1,272 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/menubackdrop.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/21/01 11:30a $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "menubackdrop.h"
#include "scene.h"
#include "camera.h"
#include "ww3d.h"
#include "assetmgr.h"
#include "render2d.h"
#include "light.h"
#include "hanim.h"
////////////////////////////////////////////////////////////////
//
// MenuBackDropClass
//
////////////////////////////////////////////////////////////////
MenuBackDropClass::MenuBackDropClass (void) :
Scene (NULL),
Camera (NULL),
Model (NULL),
Anim (NULL),
ClearScreen (true)
{
//
// Create a scene to use for the background
//
Scene = new SimpleSceneClass;
Scene->Set_Ambient_Light (Vector3(1, 1, 1));
//
// Create a single scene light
//
LightClass *light = new LightClass;
if (light != NULL) {
//
// Configure the light
//
light->Set_Position (Vector3 (0, 0, 15000.0F));
light->Set_Intensity (1.0F);
light->Set_Force_Visible(true);
light->Set_Flag (LightClass::NEAR_ATTENUATION, false);
light->Set_Far_Attenuation_Range (1000000, 1000000);
light->Set_Ambient(Vector3 (0,0,0));
light->Set_Diffuse (Vector3 (1.0F, 1.0F, 1.0F));
light->Set_Specular (Vector3 (1.0F, 1.0F, 1.0F));
//
// Add this light to the scene
//
Scene->Add_Render_Object (light);
REF_PTR_RELEASE(light);
}
//
// Create a camera to use in background-scene
//
Camera = new CameraClass();
Camera->Set_Position (Vector3 (0, 0, 800));
//
// Configure the view plane
//
const RectClass &screen_size = Render2DClass::Get_Screen_Resolution ();
float hfov = DEG_TO_RAD(45.0F);
float vfov = (screen_size.Height () / screen_size.Width ()) * hfov;
Camera->Set_View_Plane (hfov, vfov);
//
// Set the clip planes
//
Camera->Set_Clip_Planes (5.0F, 12000.0F);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~MenuBackDropClass
//
////////////////////////////////////////////////////////////////
MenuBackDropClass::~MenuBackDropClass (void)
{
Remove_Model();
REF_PTR_RELEASE (Camera);
REF_PTR_RELEASE (Scene);
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
MenuBackDropClass::Render (void)
{
//
// Simple render the scene
//
WW3D::Render (Scene, Camera, ClearScreen, ClearScreen);
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Model
//
////////////////////////////////////////////////////////////////
void
MenuBackDropClass::Set_Model (const char *name)
{
// Get rid of the old model.
Remove_Model();
//
// Load the new model
//
Model = WW3DAssetManager::Get_Instance ()->Create_Render_Obj (name);
if (Model != NULL) {
//
// Check to see if this model has a camera bone
//
int camera_bone_index = Model->Get_Bone_Index ("CAMERA");
if (camera_bone_index > 0) {
//
// Convert the bone's transform into a camera transform
//
const Matrix3D &tm = Model->Get_Bone_Transform (camera_bone_index);
Matrix3D cam_tm (Vector3 (0, -1, 0), Vector3 (0, 0, 1), Vector3 (-1, 0, 0), Vector3 (0, 0, 0));
Matrix3D new_tm = tm * cam_tm;
//
// Set the camera's new transform
//
Camera->Set_Transform (new_tm);
}
//
// Add the model to the scene
//
Scene->Add_Render_Object (Model);
}
//
// Update the animation
//
Play_Animation ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Remove_Model
//
////////////////////////////////////////////////////////////////
void
MenuBackDropClass::Remove_Model (void)
{
if (Model != NULL) {
Model->Remove();
}
REF_PTR_RELEASE (Model);
REF_PTR_RELEASE (Anim);
}
////////////////////////////////////////////////////////////////
//
// Set_Animation
//
////////////////////////////////////////////////////////////////
void
MenuBackDropClass::Set_Animation (const char *anim_name)
{
REF_PTR_RELEASE (Anim);
AnimationName = anim_name;
Play_Animation ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Animation_Percentage
//
////////////////////////////////////////////////////////////////
void
MenuBackDropClass::Set_Animation_Percentage (float percent)
{
if ( Model != NULL && Anim != NULL ) {
float frame = (float)(Anim->Get_Num_Frames()-1) * WWMath::Clamp( percent, 0, 1 );
Model->Set_Animation (Anim, frame, RenderObjClass::ANIM_MODE_MANUAL);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Play_Animation
//
////////////////////////////////////////////////////////////////
void
MenuBackDropClass::Play_Animation (void)
{
if (Model == NULL) {
return ;
}
if (AnimationName.Get_Length () > 0) {
//
// Play the animation on the background (if necessary)
//
REF_PTR_RELEASE (Anim);
Anim = WW3DAssetManager::Get_Instance ()->Get_HAnim (AnimationName);
if (Anim != NULL) {
Model->Set_Animation (Anim, 0, RenderObjClass::ANIM_MODE_LOOP);
}
} else {
//
// Stop the animation
//
REF_PTR_RELEASE (Anim);
Model->Set_Animation (NULL);
}
return ;
}

115
Code/wwui/menubackdrop.h Normal file
View File

@@ -0,0 +1,115 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/menubackdrop.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/21/01 11:30a $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __MENU_BACKDROP_H
#define __MENU_BACKDROP_H
#include "wwstring.h"
#include "rendobj.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class SimpleSceneClass;
class CameraClass;
////////////////////////////////////////////////////////////////
//
// MenuBackDropClass
//
////////////////////////////////////////////////////////////////
class MenuBackDropClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
MenuBackDropClass (void);
virtual ~MenuBackDropClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Display methods
//
void Render (void);
//
// Configuration
//
void Set_Model (const char *name);
void Remove_Model (void);
void Set_Animation (const char *anim_name);
void Set_Animation_Percentage( float percent );
void Clear_Screen (bool onoff) { ClearScreen = onoff; }
//
// Accessors
//
SimpleSceneClass * Peek_Scene (void) { return Scene; };
CameraClass * Peek_Camera (void) { return Camera; };
RenderObjClass * Peek_Model (void) const { return Model; }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Play_Animation (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
SimpleSceneClass * Scene;
CameraClass * Camera;
StringClass AnimationName;
RenderObjClass * Model;
HAnimClass * Anim;
bool ClearScreen;
};
#endif //__MENU_BACKDROP_H

264
Code/wwui/menudialog.cpp Normal file
View File

@@ -0,0 +1,264 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/menudialog.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/02/02 11:10a $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "menudialog.h"
#include "menubackdrop.h"
#include "render2d.h"
#include "stylemgr.h"
#include "dialogmgr.h"
#include "childdialog.h"
#include "dialogcontrol.h"
////////////////////////////////////////////////////////////////
// Static member initialization
////////////////////////////////////////////////////////////////
MenuDialogClass * MenuDialogClass::ActiveMenu = NULL;
MenuBackDropClass * MenuDialogClass::BackDrop = NULL;
DynamicVectorClass<MenuDialogClass *> MenuDialogClass::MenuStack;
////////////////////////////////////////////////////////////////
//
// MenuDialogClass
//
////////////////////////////////////////////////////////////////
MenuDialogClass::MenuDialogClass (int res_id) :
DialogBaseClass (res_id)
{
//
// Add ourselves to the global stack of menus
//
MenuStack.Add (this);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~MenuDialogClass
//
////////////////////////////////////////////////////////////////
MenuDialogClass::~MenuDialogClass (void)
{
if (ActiveMenu == this) {
ActiveMenu = NULL;
}
//
// Remove ourselves from the stack
//
int index = MenuStack.ID (this);
if (index != -1) {
MenuStack.Delete (index);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Initialize
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::Initialize (void)
{
BackDrop = new MenuBackDropClass;
return ;
}
////////////////////////////////////////////////////////////////
//
// Shutdown
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::Shutdown (void)
{
if (BackDrop != NULL) {
delete BackDrop;
BackDrop = NULL;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::Render (void)
{
//
// Don't render if we aren't the active menu
//
if (ActiveMenu == this || DialogMgrClass::Peek_Transitioning_Dialog () == this) {
//
// Render the background scene first
//
BackDrop->Render ();
//
// Now, let the dialog subsystem render the controls and
// such...
//
DialogBaseClass::Render ();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Init_Dialog
//
////////////////////////////////////////////////////////////////
/*void
MenuDialogClass::On_Init_Dialog (void)
{
DialogBaseClass::Set_Default_Focus ();
return ;
}*/
////////////////////////////////////////////////////////////////
//
// Start_Dialog
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::Start_Dialog (void)
{
//
// As a menu dialog we use the whole screen
//
Rect = Render2DClass::Get_Screen_Resolution ();
DialogBaseClass::Start_Dialog ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Activate
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::On_Activate (bool onoff)
{
if (onoff) {
//
// Notify the old menu
//
if (ActiveMenu != NULL) {
ActiveMenu->On_Menu_Activate (false);
}
//
// Switch to active state
//
ActiveMenu = this;
On_Menu_Activate (true);
}
DialogBaseClass::On_Activate (onoff);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Menu_Activate
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::On_Menu_Activate (bool onoff)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// End_Dialog
//
////////////////////////////////////////////////////////////////
void
MenuDialogClass::End_Dialog (void)
{
//
// Is this the last menu? If so, send a notification
//
if (DialogMgrClass::Is_Flushing_Dialogs () == false) {
if (MenuStack.Count () == 1) {
On_Last_Menu_Ending ();
} else {
//
// Play the sound effect
//
StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MENU_BACK);
}
}
DialogBaseClass::End_Dialog ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Replace_BackDrop
//
////////////////////////////////////////////////////////////////
MenuBackDropClass *
MenuDialogClass::Replace_BackDrop (MenuBackDropClass *backdrop)
{
MenuBackDropClass *retval = BackDrop;
BackDrop = backdrop;
return retval;
}

131
Code/wwui/menudialog.h Normal file
View File

@@ -0,0 +1,131 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/menudialog.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/25/01 5:15p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __MENU_DIALOG_H
#define __MENU_DIALOG_H
#include "dialogbase.h"
#include "wwstring.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class MenuBackDropClass;
////////////////////////////////////////////////////////////////
//
// MenuDialogClass
//
////////////////////////////////////////////////////////////////
class MenuDialogClass : public DialogBaseClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
MenuDialogClass (int res_id);
virtual ~MenuDialogClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Initialization
//
static void Initialize (void);
static void Shutdown (void);
//
// RTTI
//
virtual MenuDialogClass * As_MenuDialogClass (void) { return this; }
//
// Configuration methods
//
static MenuBackDropClass * Get_BackDrop (void) { return BackDrop; }
static MenuBackDropClass * Replace_BackDrop (MenuBackDropClass *backdrop);
//
// Informational
//
bool Is_Active_Menu (void) const { return (ActiveMenu == this); }
//
// From DialogBaseClass
//
virtual void Start_Dialog (void);
virtual void Render (void);
virtual void End_Dialog (void);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
//
// From DialogBaseClass
//
virtual void On_Activate (bool onoff);
//
// New notifications
//
virtual void On_Menu_Activate (bool onoff);
virtual void On_Last_Menu_Ending (void) {}
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
static MenuDialogClass * ActiveMenu;
static MenuBackDropClass * BackDrop;
static DynamicVectorClass<MenuDialogClass *> MenuStack;
};
#endif //__MENU_DIALOG_H

789
Code/wwui/menuentryctrl.cpp Normal file
View File

@@ -0,0 +1,789 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/menuentryctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/02/02 11:01a $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "menuentryctrl.h"
#include "assetmgr.h"
#include "font3d.h"
#include "dialogbase.h"
#include "mousemgr.h"
#include "stylemgr.h"
#include "dialogmgr.h"
#include "texture.h"
#include "ww3d.h"
////////////////////////////////////////////////////////////////
// Static member initialization
////////////////////////////////////////////////////////////////
int MenuEntryCtrlClass::MaxDefaultRedValue = 9;
int MenuEntryCtrlClass::MaxHilightRedValue = 16;
////////////////////////////////////////////////////////////////
//
// MenuEntryCtrlClass
//
////////////////////////////////////////////////////////////////
MenuEntryCtrlClass::MenuEntryCtrlClass (void) :
CurrState (UP),
WasButtonPressedOnMe (false),
IsMouseOverMe (false),
CurrRadiusX (5),
CurrRadiusY (5),
StartTime (0),
EndTime (0),
CurrColor (RGB_TO_INT32 (0, MaxDefaultRedValue, 0))
{
//
// Get the current bits-per-pixel of the display
//
int foo = 0;
int bits = 0;
bool windowed = 0;
WW3D::Get_Device_Resolution (foo, foo, bits, windowed);
//
// If we are running at anything less then 32bpp, then
// scale the glow colors
//
if (bits < 32) {
MaxDefaultRedValue = 11;
MaxHilightRedValue = 22;
}
//
// Set the font for the text renderer
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_MENU);
StyleMgrClass::Assign_Font (&GlowRenderer, StyleMgrClass::FONT_MENU);
return ;
}
////////////////////////////////////////////////////////////////
//
// ~MenuEntryCtrlClass
//
////////////////////////////////////////////////////////////////
MenuEntryCtrlClass::~MenuEntryCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Render (void)
{
//
// Refresh the cached renderer (if necessary)
//
if (Is_Dirty ()) {
Create_Text_Renderer ();
}
//
// Render the menu text
//
GlowRenderer.Render ();
TextRenderer.Render ();
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Frame_Update (void)
{
//
// Allow the current state to update
//
Update_State ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Create (void)
{
if ((Style & 0xF) == BS_OWNERDRAW) {
//
// Set the font for the text renderer
//
StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_SM_MENU);
StyleMgrClass::Assign_Font (&GlowRenderer, StyleMgrClass::FONT_SM_MENU);
/*FontCharsClass *font = WW3DAssetManager::Get_Instance()->Get_FontChars ("Lucida Sans Unicode", 12);
TextRenderer.Set_Font (font);
GlowRenderer.Set_Font (font);
font->Release_Ref ();*/
}
TextRenderer.Build_Sentence (Title);
GlowRenderer.Build_Sentence (Title);
//
// Determine what rectangle should be clickable
//
Vector2 extents = TextRenderer.Get_Text_Extents (Title);
Rect = MaxRect;
//
// Should we left justify?
//
if ((Style & 0xF00) == BS_LEFT) {
Rect.Right = Rect.Left + extents.X + TextRenderer.Get_Text_Extents (L"W").X;
} else {
Rect.Left = int(Rect.Left + (Rect.Width () / 2) - (extents.X / 2));
Rect.Right = Rect.Left + extents.X + TextRenderer.Get_Text_Extents (L"W").X;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Update_Client_Rect (void)
{
MaxRect = Rect;
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Wheel
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Mouse_Wheel (int direction)
{
if (HasFocus) {
//
// Find the next control to set the focus to...
//
DialogControlClass *control = Parent->Find_Next_Group_Control (this, direction);
if (control != NULL) {
control->Set_Focus ();
control->Center_Mouse ();
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
Set_Capture ();
//
// Update our mouse flags
//
WasButtonPressedOnMe = true;
IsMouseOverMe = Rect.Contains (mouse_pos);
if (IsMouseOverMe) {
Set_State (DOWN);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
Release_Capture ();
//
// Update our mouse flags
//
WasButtonPressedOnMe = false;
IsMouseOverMe = Rect.Contains (mouse_pos);
//
// Switch states
//
if (CurrState != DOWN) {
if (HasFocus) {
if (IsMouseOverMe == false || CurrState != DOWN) {
Set_State (HILIGHT);
}
} else {
Set_State (UP);
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Move
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
{
//
// Force focus onto the control
//
Set_Focus ();
//
// Check to see whether or not the mouse is over the control
//
IsMouseOverMe = Rect.Contains (mouse_pos);
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_State
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Set_State (int new_state)
{
if (new_state != CurrState) {
//
// Update the state and force a repaint
//
CurrState = new_state;
Set_Dirty ();
//
// Switch to the new state
//
switch (CurrState)
{
case UP:
CurrRadiusX = 5;
CurrRadiusY = 5;
break;
case DOWN:
StartTime = DialogMgrClass::Get_Time ();
EndTime = StartTime + 300;
CurrColor = RGB_TO_INT32 (MaxHilightRedValue, 0, 0);
//
// Play the sound effect
//
StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MOUSE_CLICK);
break;
case HILIGHT:
StartTime = DialogMgrClass::Get_Time ();
EndTime = StartTime + 1000;
CurrColor = RGB_TO_INT32 (MaxHilightRedValue, 0, 0);
break;
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_State
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Update_State (void)
{
switch (CurrState)
{
case UP:
break;
case DOWN:
{
//
// Do we need to animate the glow?
//
int curr_time = DialogMgrClass::Get_Time ();
if (curr_time < EndTime) {
//
// Expand the glow
//
float percent = float(curr_time - StartTime) / float(EndTime - StartTime);
CurrRadiusX = int(5.0F + (155.0F * percent));
CurrRadiusY = int(5.0F + (25.0F * percent));
CurrColor = RGB_TO_INT32 (MaxHilightRedValue * 3, 0, 0);
uint32 time1 = StartTime;
uint32 time2 = time1 + (EndTime - StartTime) / 2;
uint32 time3 = EndTime;
if (curr_time >= (int)time2) {
Vector3 start_color (MaxHilightRedValue * 3, MaxHilightRedValue * 3.0F * 0.6F, 0);
Vector3 end_color (0, 0, 0);
//
// Transition the color from start to finish
//
uint32 start_time = time2;
uint32 end_time = time3;
float percent = float(float(curr_time - start_time) / float(end_time - start_time));
Vector3 color = start_color + (end_color - start_color) * percent;
CurrColor = RGB_TO_INT32 (color.X, color.Y, color.Z);
} else {
Vector3 start_color (MaxHilightRedValue * 3, 0, 0);
Vector3 end_color (MaxHilightRedValue * 3, MaxHilightRedValue * 3.0F * 0.6F, 0);
uint32 start_time = time1;
uint32 end_time = time2;
float percent = float(float(curr_time - start_time) / float(end_time - start_time));
Vector3 color = start_color + (end_color - start_color) * percent;
CurrColor = RGB_TO_INT32 (color.X, color.Y, color.Z);
}
//
// Force update the display
//
Set_Dirty ();
} else {
if (CurrRadiusX != 160.0F) {
//
// Snap the glow to its max
//
CurrRadiusX = 160.0F;
CurrRadiusY = 60.0F;
CurrColor = RGB_TO_INT32 (0, 0, 0);
}
//
// Send the command (if necessary)
//
On_Pushed ();
if (HasFocus) {
Set_State (HILIGHT);
} else {
Set_State (UP);
}
}
break;
}
case HILIGHT:
{
//
// Do we need to animate the glow?
//
int curr_time = DialogMgrClass::Get_Time ();
if (curr_time < EndTime) {
//
// Expand the glow
//
float percent = float(curr_time - StartTime) / float(EndTime - StartTime);
CurrRadiusX = int(5.0F + (55.0F * percent));
CurrRadiusY = CurrRadiusX;
//
// Fade out the color
//
if (curr_time > (EndTime - 500)) {
float start_time = EndTime - 500;
float red_percent = float(float(curr_time - start_time) / float(EndTime - start_time));
int red_value = (1.0F - red_percent) * MaxHilightRedValue;
CurrColor = RGB_TO_INT32 (red_value, 0, 0);
}
//
// Force update the display
//
Set_Dirty ();
} else {
//
// Snap the glow to its max
//
CurrRadiusX = 5;
CurrRadiusY = 5;
CurrColor = RGB_TO_INT32 (MaxHilightRedValue, 0, 0);
//
// Restart the animation
//
StartTime = curr_time;
EndTime = curr_time + 1000;
}
break;
}
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderer
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Create_Text_Renderer (void)
{
TextRenderer.Reset_Polys ();
GlowRenderer.Reset_Polys ();
//
// Get the extents of the text we will be drawing
//
Vector2 text_extent = TextRenderer.Get_Text_Extents (Title);
//
// Assume cenetered text
//
int x_pos = int(Rect.Left + (Rect.Width () / 2) - (text_extent.X / 2));
int y_pos = int(Rect.Top + (Rect.Height () / 2) - (text_extent.Y / 2));
//
// Should we left justify?
//
if ((Style & 0xF00) == BS_LEFT) {
x_pos = int(Rect.Left + 1);
}
if (CurrState == UP) {
//
// Render the glow
//
Create_Glow (CurrRadiusX, CurrRadiusY, RGB_TO_INT32 (MaxDefaultRedValue, 0, 0));
//
// Render the text
//
TextRenderer.Set_Location (Vector2 (x_pos, y_pos));
TextRenderer.Draw_Sentence (StyleMgrClass::Get_Text_Color ());
} else if (CurrState == DOWN) {
//
// Render the glow
//
Create_Glow (CurrRadiusX, CurrRadiusY, CurrColor);
//
// Render the text
//
TextRenderer.Set_Location (Vector2 (x_pos + 1, y_pos + 1));
TextRenderer.Draw_Sentence (RGB_TO_INT32 (0, 0, 0));
TextRenderer.Set_Location (Vector2 (x_pos, y_pos));
TextRenderer.Draw_Sentence (RGB_TO_INT32 (0, 0, 0));
} else if (CurrState == HILIGHT) {
//
// Render the glow
//
Create_Glow (CurrRadiusX, CurrRadiusY, CurrColor);
TextRenderer.Set_Location (Vector2 (x_pos-1, y_pos-1));
TextRenderer.Draw_Sentence (StyleMgrClass::Get_Text_Color ());
TextRenderer.Set_Location (Vector2 (x_pos, y_pos));
TextRenderer.Draw_Sentence (RGB_TO_INT32 (0, 0, 0));
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor if necessary
//
if (Rect.Contains (mouse_pos)) {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
} else {
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ARROW);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Glow
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Create_Glow (int radiusx, int radiusy, int color)
{
GlowRenderer.Reset_Polys ();
//
// Determine how to justify the text
//
StyleMgrClass::JUSTIFICATION justification = StyleMgrClass::CENTER_JUSTIFY;
if ((Style & 0xF00) == BS_LEFT) {
justification = StyleMgrClass::LEFT_JUSTIFY;
}
//
// Render the text in "glow" fashion
//
StyleMgrClass::Render_Glow (Title, &GlowRenderer, Rect, radiusx, radiusy,
color, justification);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Focus
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Set_Focus (void)
{
//
// Set the state to hilight if the mouse button
// isn't down
//
if (WasButtonPressedOnMe == false) {
Set_State (HILIGHT);
//
// Play the sound effect
//
StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MOUSE_OVER);
}
DialogControlClass::On_Set_Focus ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
//
// Restore the entry to its default state
//
if (CurrState != DOWN) {
Set_State (UP);
}
WasButtonPressedOnMe = false;
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
MenuEntryCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
bool handled = true;
switch (key_id)
{
case VK_RETURN:
case VK_SPACE:
Set_State (DOWN);
break;
case VK_LEFT:
case VK_UP:
{
//
// Set the focus to the previous control in our group
//
DialogControlClass *control = Parent->Find_Next_Group_Control (this, -1);
if (control != NULL) {
control->Set_Focus ();
}
break;
}
case VK_RIGHT:
case VK_DOWN:
{
//
// Set the focus to the next control in our group
//
DialogControlClass *control = Parent->Find_Next_Group_Control (this, 1);
if (control != NULL) {
control->Set_Focus ();
}
break;
}
default:
handled = false;
break;
}
return handled;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Up
//
////////////////////////////////////////////////////////////////
bool
MenuEntryCtrlClass::On_Key_Up (uint32 key_id)
{
return false;
}
////////////////////////////////////////////////////////////////
//
// On_Pushed
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::On_Pushed (void)
{
Parent->On_Command (ID, BN_CLICKED, 0);
return ;
}
////////////////////////////////////////////////////////////////
//
// Center_Mouse
//
////////////////////////////////////////////////////////////////
void
MenuEntryCtrlClass::Center_Mouse (void)
{
//
// Get the extents of the text we will be drawing
//
Vector2 text_extent = TextRenderer.Get_Text_Extents (Title);
int x_pos = 0;
//
// Should we left justify?
//
if ((Style & 0xF00) == BS_LEFT) {
x_pos = int(Rect.Left + (text_extent.X / 2));
} else {
x_pos = int(Rect.Left + (Rect.Width () / 2) - (text_extent.X / 2));
}
int y_pos = int(Rect.Top + (Rect.Height () / 2));
//
// Put the mouse cursor in the middle of this control
//
Vector3 mouse_pos = DialogMgrClass::Get_Mouse_Pos ();
mouse_pos.X = x_pos;
mouse_pos.Y = y_pos;
DialogMgrClass::Set_Mouse_Pos (mouse_pos);
return ;
}

138
Code/wwui/menuentryctrl.h Normal file
View File

@@ -0,0 +1,138 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/menuentryctrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 9/19/01 11:12a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __MENU_ENTRY_CTRL_H
#define __MENU_ENTRY_CTRL_H
#include "dialogcontrol.h"
#include "vector3.h"
#include "render2dsentence.h"
////////////////////////////////////////////////////////////////
//
// MenuEntryCtrlClass
//
////////////////////////////////////////////////////////////////
class MenuEntryCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
MenuEntryCtrlClass (void);
virtual ~MenuEntryCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void Render (void);
bool Wants_Tooltip (void) const { return false; }
void Center_Mouse (void);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_Up (const Vector2 &mouse_pos);
void On_Mouse_Move (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void On_Create (void);
void On_Set_Focus (void);
void On_Kill_Focus (DialogControlClass *);
bool On_Key_Down (uint32 key_id, uint32 key_data);
bool On_Key_Up (uint32 key_id);
void On_Mouse_Wheel (int direction);
void On_Frame_Update (void);
void Update_Client_Rect (void);
void Create_Text_Renderer (void);
void Set_State (int new_state);
void Update_State (void);
void Create_Glow (int radiusx, int radiusy, int color);
void On_Pushed (void);
////////////////////////////////////////////////////////////////
// Protected constants
////////////////////////////////////////////////////////////////
enum
{
UP = 0,
DOWN,
HILIGHT,
STATE_MAX
};
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass GlowRenderer;
Render2DSentenceClass TextRenderer;
RectClass MaxRect;
bool WasButtonPressedOnMe;
bool IsMouseOverMe;
bool TriggerCommand;
int CurrState;
int CurrRadiusX;
int CurrRadiusY;
int StartTime;
int EndTime;
int CurrColor;
static int MaxDefaultRedValue;
static int MaxHilightRedValue;
};
#endif //__MENU_ENTRY_CTRL_H

View File

@@ -0,0 +1,471 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWUI *
* *
* $Archive:: /Commando/Code/wwui/merchandisectrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/10/02 2:55p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "merchandisectrl.h"
#include "stylemgr.h"
#include "mousemgr.h"
#include "assetmgr.h"
#include "texture.h"
#include "dialogbase.h"
#include "vector4.h"
//////////////////////////////////////////////////////////////////////
// Local constants
//////////////////////////////////////////////////////////////////////
static const float BUTTON_WIDTH = 16.0F;
static const float BUTTON_HEIGHT = 16.0F;
//////////////////////////////////////////////////////////////////////
//
// MerchandiseCtrlClass
//
//////////////////////////////////////////////////////////////////////
MerchandiseCtrlClass::MerchandiseCtrlClass (void) :
UserData (0),
Cost (0),
CurrentTextureIndex (0),
Count (0)
{
//
// Set the font for the text renderer
//
StyleMgrClass::Assign_Font (&NameTextRenderer, StyleMgrClass::FONT_TOOLTIPS);
StyleMgrClass::Assign_Font (&CostTextRenderer, StyleMgrClass::FONT_HEADER);
StyleMgrClass::Assign_Font (&CountTextRenderer, StyleMgrClass::FONT_TOOLTIPS);
StyleMgrClass::Configure_Renderer (&ControlRenderer);
StyleMgrClass::Configure_Renderer (&TextureRenderer);
StyleMgrClass::Configure_Renderer (&ButtonRenderer);
StyleMgrClass::Configure_Renderer (&HilightRenderer);
StyleMgrClass::Configure_Hilighter (&HilightRenderer);
TextureRenderer.Enable_Texturing (true);
ButtonRenderer.Enable_Texturing (true);
//
// Pass the texture onto the renderer
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("hud_cnc_Button.tga", TextureClass::MIP_LEVELS_1);
ButtonRenderer.Set_Texture (texture);
REF_PTR_RELEASE (texture);
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~MerchandiseCtrlClass
//
//////////////////////////////////////////////////////////////////////
MerchandiseCtrlClass::~MerchandiseCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Text_Renderer
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Create_Text_Renderer (void)
{
//
// Convert the cost to a string
//
WideStringClass cost_text;
cost_text.Format (L"%d", Cost);
//
// Render the text
//
NameTextRenderer.Reset ();
CostTextRenderer.Reset ();
CountTextRenderer.Reset ();
StyleMgrClass::Render_Text (Title, &NameTextRenderer, RGB_TO_INT32 (255, 255, 255), RGB_TO_INT32 (0, 0, 0), TextRect, true, true, StyleMgrClass::LEFT_JUSTIFY, true);
StyleMgrClass::Render_Text (cost_text, &CostTextRenderer, RGB_TO_INT32 (255, 255, 255), RGB_TO_INT32 (0, 0, 0), CostRect, true, true, StyleMgrClass::LEFT_JUSTIFY, true);
//
// Render the counter (if necessary)
//
if (Count > 1) {
//
// Convert the count to a string
//
WideStringClass count_text;
count_text.Format (L"%d", Count);
StyleMgrClass::Render_Text (count_text, &CountTextRenderer, RGB_TO_INT32 (255, 255, 255), RGB_TO_INT32 (0, 0, 0), CountRect, true, true, StyleMgrClass::CENTER_JUSTIFY, true);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Render
//
//////////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Render (void)
{
//
// Update the text renderer (if necessary)
//
if (IsDirty) {
Create_Text_Renderer ();
Create_Control_Renderer ();
Create_Texture_Renderer ();
}
//
// Render the parts of the control
//
TextureRenderer.Render ();
ControlRenderer.Render ();
NameTextRenderer.Render ();
CostTextRenderer.Render ();
CountTextRenderer.Render ();
ButtonRenderer.Render ();
HilightRenderer.Render ();
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Update_Client_Rect (void)
{
//
// Set the client area
//
ClientRect = Rect;
ClientRect.Inflate (Vector2 (-1, -1));
//
// Make the texture rectangle the 2/3 of the space
//
TextureRect = Rect;
TextureRect.Bottom = int(TextureRect.Top + (Rect.Height () * 0.667F));
//
// Make the cost rect use up 60% of the remaining space
//
CostRect = Rect;
CostRect.Top = int(TextureRect.Bottom + 1);
CostRect.Bottom = CostRect.Top + int((Rect.Bottom - TextureRect.Bottom) * 0.6F);
//
// The rest of the space goes to the text rect
//
TextRect = Rect;
TextRect.Top = CostRect.Bottom;
//
// The counter lives in the upper-right corner
//
CountRect = Rect;
CountRect.Left = CountRect.Left + int(Rect.Width () * 0.75F);
CountRect.Bottom = CountRect.Top + int(TextureRect.Height () * 0.25F);
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor
//
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Control_Renderer
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Create_Control_Renderer (void)
{
Render2DClass &renderer = ControlRenderer;
//
// Configure this renderer
//
renderer.Reset ();
HilightRenderer.Reset ();
ButtonRenderer.Reset ();
renderer.Enable_Texturing (false);
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
}
//
// Draw the outlines
//
if (Count > 0) {
StyleMgrClass::Render_Hilight (&HilightRenderer, Rect);
}
//
// Draw the cycle button in the upper right corner...
//
if (TextureNameList.Count () > 1) {
//
// Draw the button
//
RectClass button_rect;
button_rect.Right = Rect.Right - 1;
button_rect.Top = Rect.Top + 2;
button_rect.Left = int(button_rect.Right - (BUTTON_WIDTH * StyleMgrClass::Get_X_Scale ()));
button_rect.Bottom = int(button_rect.Top + (BUTTON_HEIGHT * StyleMgrClass::Get_Y_Scale ()));
ButtonRenderer.Add_Quad (button_rect);
}
//
// Convert the cost to a string
//
WideStringClass cost_text;
cost_text.Format (L"%d", Cost);
//
// Get the dimensions of the text
//
Vector2 name_extents = NameTextRenderer.Get_Text_Extents (Title);
Vector2 cost_extents = CostTextRenderer.Get_Text_Extents (cost_text);
//
// Build rectangles for the backdrops of the cost and text
//
RectClass text_rect = TextRect;
RectClass cost_rect = CostRect;
text_rect.Right = int(text_rect.Left + name_extents.X + 4.0F);
cost_rect.Right = int(cost_rect.Left + cost_extents.X + 4.0F);
//
// Clip the backdrop to the bounding rectangle
//
text_rect.Right = min (text_rect.Right, Rect.Right);
cost_rect.Right = min (cost_rect.Right, Rect.Right);
//
// Render the text backdrops
//
Vector4 vector_color;
INT32_TO_VRGBA (color, vector_color);
vector_color.W = 0.0F;
renderer.Add_Quad_HGradient (text_rect, color, VRGBA_TO_INT32 (vector_color));
renderer.Add_Quad_HGradient (cost_rect, color, VRGBA_TO_INT32 (vector_color));
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Texture_Renderer
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Create_Texture_Renderer (void)
{
/*float smallest_dim = min (TextureRect.Width (), TextureRect.Height ());
RectClass rect;
rect.Left = int(TextureRect.Left + (TextureRect.Width () * 0.5F) - (smallest_dim * 0.5F));
rect.Top = int(TextureRect.Top + (TextureRect.Height () * 0.5F) - (smallest_dim * 0.5F));
rect.Right = int(rect.Left + smallest_dim);
rect.Bottom = int(rect.Top + smallest_dim);*/
//
// Darken the bitmap if its disabled
//
int color = 0xFFFFFFFF;
if (IsEnabled == false) {
color = RGB_TO_INT32 (96, 96, 96);
}
//
// Configure this renderer
//
TextureRenderer.Reset ();
TextureRenderer.Add_Quad (Rect, color);
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Texture
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Set_Texture (const char *texture_name)
{
CurrentTextureIndex = 0;
//
// Cache the texture name
//
TextureNameList.Delete_All ();
TextureNameList.Add (texture_name);
//
// Pass the texture onto the renderer
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_name, TextureClass::MIP_LEVELS_1);
TextureRenderer.Set_Texture (texture);
REF_PTR_RELEASE (texture);
return ;
}
////////////////////////////////////////////////////////////////
//
// Add_Alternate_Texture
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::Add_Alternate_Texture (const char *texture_name)
{
TextureNameList.Add (texture_name);
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
RectClass button_rect;
button_rect.Right = Rect.Right - 1;
button_rect.Top = Rect.Top + 2;
button_rect.Left = int(button_rect.Right - (BUTTON_WIDTH * StyleMgrClass::Get_X_Scale ()));
button_rect.Bottom = int(button_rect.Top + (BUTTON_HEIGHT * StyleMgrClass::Get_Y_Scale ()));
//
// Did the user click in the cycle button?
//
if (TextureNameList.Count () > 1 && button_rect.Contains (mouse_pos)) {
//
// Cycle to the next texture
//
CurrentTextureIndex ++;
if (CurrentTextureIndex >= TextureNameList.Count ()) {
CurrentTextureIndex = 0;
}
//
// Pass the texture onto the renderer
//
TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture (TextureNameList[CurrentTextureIndex], TextureClass::MIP_LEVELS_1);
if (texture != NULL) {
TextureRenderer.Set_Texture (texture);
REF_PTR_RELEASE (texture);
}
Set_Dirty ();
} else {
//
// Notify the owner that this item has been purchased
//
ADVISE_NOTIFY (On_Merchandise_Selected (this, Get_ID ()));
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_DblClk
//
////////////////////////////////////////////////////////////////
void
MerchandiseCtrlClass::On_LButton_DblClk (const Vector2 &mouse_pos)
{
RectClass button_rect;
button_rect.Right = Rect.Right - 1;
button_rect.Top = Rect.Top + 2;
button_rect.Left = int(button_rect.Right - (BUTTON_WIDTH * StyleMgrClass::Get_X_Scale ()));
button_rect.Bottom = int(button_rect.Top + (BUTTON_HEIGHT * StyleMgrClass::Get_Y_Scale ()));
//
// Did the user click in the cycle button?
//
if (TextureNameList.Count () == 0 || button_rect.Contains (mouse_pos) == false) {
//
// Notify the owner that this item has been double-clicked
//
ADVISE_NOTIFY (On_Merchandise_DblClk (this, Get_ID ()));
}
return ;
}

132
Code/wwui/merchandisectrl.h Normal file
View File

@@ -0,0 +1,132 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWUI *
* *
* $Archive:: /Commando/Code/wwui/merchandisectrl.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/10/02 2:56p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __MERCHANDISECTRL_H
#define __MERCHANDISECTRL_H
#include "dialogcontrol.h"
#include "render2dsentence.h"
////////////////////////////////////////////////////////////////
//
// MerchandiseCtrlClass
//
////////////////////////////////////////////////////////////////
class MerchandiseCtrlClass : public DialogControlClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
MerchandiseCtrlClass (void);
virtual ~MerchandiseCtrlClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// From DialogControlClass
//
void Render (void);
//
// Configuration
//
int Get_Cost (void) const { return Cost; }
//const char * Get_Texture (void) const { return TextureName; }
void Set_Cost (int cost) { Cost = cost; Set_Dirty (); }
void Set_Texture (const char *texture_name);
void Add_Alternate_Texture (const char *texture_name);
int Get_Selected_Alternate (void) { return (CurrentTextureIndex - 1); }
DWORD Get_User_Data (void) const { return UserData; }
void Set_User_Data (DWORD data) { UserData = data; }
void Increment_Purchase_Count (void) { Count ++; Set_Dirty (); }
void Reset_Purchase_Count (void) { Count = 0; Set_Dirty (); }
int Get_Purchase_Count (void) { return Count; }
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void On_LButton_Down (const Vector2 &mouse_pos);
void On_LButton_DblClk (const Vector2 &mouse_pos);
void On_Set_Cursor (const Vector2 &mouse_pos);
void Update_Client_Rect (void);
void Create_Control_Renderer (void);
void Create_Text_Renderer (void);
void Create_Texture_Renderer (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
Render2DSentenceClass NameTextRenderer;
Render2DSentenceClass CostTextRenderer;
Render2DSentenceClass CountTextRenderer;
Render2DClass ControlRenderer;
Render2DClass TextureRenderer;
Render2DClass HilightRenderer;
Render2DClass ButtonRenderer;
RectClass TextureRect;
RectClass TextRect;
RectClass CostRect;
RectClass CountRect;
DWORD UserData;
int Cost;
int Count;
DynamicVectorClass<StringClass> TextureNameList;
int CurrentTextureIndex;
};
#endif //__MERCHANDISECTRL_H

219
Code/wwui/mousemgr.cpp Normal file
View File

@@ -0,0 +1,219 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/mousemgr.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/22/01 4:49p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "mousemgr.h"
#include "screencursor.h"
#include "assetmgr.h"
#include "texture.h"
////////////////////////////////////////////////////////////////
// Local constants
////////////////////////////////////////////////////////////////
static const char * TEXTURE_NAME[MouseMgrClass::CURSOR_COUNT] =
{
"cursor_arrow.tga",
"cursor_text.tga",
"cursor_action.tga",
"cursor_busy.tga",
"cursor_pan_up.tga",
"cursor_rotate.tga"
};
static Vector2 HOTSPOTS[MouseMgrClass::CURSOR_COUNT] =
{
Vector2 (0, 0),
Vector2 (15, 15),
Vector2 (7, 1),
Vector2 (15, 15),
Vector2 (15, 17),
Vector2 (15, 15)
};
////////////////////////////////////////////////////////////////
// Local constants
////////////////////////////////////////////////////////////////
TextureClass * MouseMgrClass::Textures[CURSOR_COUNT] = { 0 };
ScreenCursorClass * MouseMgrClass::MouseCursor = NULL;
MouseMgrClass::CURSOR_TYPE MouseMgrClass::CursorType = MouseMgrClass::CURSOR_ARROW;
unsigned int MouseMgrClass::CursorWaitCount = 0;
////////////////////////////////////////////////////////////////
//
// Initialize
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::Initialize (void)
{
//
// Load each mouse cursor texture
//
for (int index = 0; index < CURSOR_COUNT; index ++) {
Textures[index] = WW3DAssetManager::Get_Instance()->Get_Texture (TEXTURE_NAME[index], TextureClass::MIP_LEVELS_1);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Shutdown
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::Shutdown (void)
{
//
// Free each mouse cursor texture
//
for (int index = 0; index < CURSOR_COUNT; index ++) {
REF_PTR_RELEASE (Textures[index]);
}
//
// This will free the cursor object
//
Show_Cursor (false);
return ;
}
////////////////////////////////////////////////////////////////
//
// Show_Cursor
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::Show_Cursor (bool onoff)
{
if (MouseCursor == NULL && onoff) {
//
// Create the mouse cursor
//
MouseCursor = new ScreenCursorClass;
MouseCursor->Set_Texture (Textures[CursorType]);
MouseCursor->Set_Hotspot (HOTSPOTS[CursorType]);
CursorWaitCount = 0;
} else if (MouseCursor != NULL && onoff == false) {
//
// Free the mouse cursor
//
delete MouseCursor;
MouseCursor = NULL;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Cursor
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::Set_Cursor (CURSOR_TYPE type)
{
if (CursorType != type && MouseCursor != NULL && CursorWaitCount == 0) {
MouseCursor->Set_Texture (Textures[type]);
MouseCursor->Set_Hotspot (HOTSPOTS[type]);
CursorType = type;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Begin_Wait_Cursor
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::Begin_Wait_Cursor(void)
{
if (CursorWaitCount == 0) {
Set_Cursor(CURSOR_BUSY);
}
++CursorWaitCount;
}
////////////////////////////////////////////////////////////////
//
// End_Wait_Cursor
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::End_Wait_Cursor(void)
{
assert(CursorWaitCount > 0 && "End_Wait_Cursor() mismatch");
if (CursorWaitCount > 0) {
--CursorWaitCount;
if (CursorWaitCount == 0) {
Set_Cursor(CURSOR_ARROW);
}
}
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
MouseMgrClass::Render (void)
{
if (MouseCursor != NULL) {
MouseCursor->Render ();
}
return ;
}

111
Code/wwui/mousemgr.h Normal file
View File

@@ -0,0 +1,111 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/mousemgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/22/01 4:36p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __MOUSE_MGR_H
#define __MOUSE_MGR_H
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class TextureClass;
class ScreenCursorClass;
////////////////////////////////////////////////////////////////
//
// MouseMgrClass
//
////////////////////////////////////////////////////////////////
class MouseMgrClass
{
public:
////////////////////////////////////////////////////////////////
// Public constants
////////////////////////////////////////////////////////////////
typedef enum
{
CURSOR_ARROW = 0,
CURSOR_TEXT,
CURSOR_ACTION,
CURSOR_BUSY,
CURSOR_PAN_UP,
CURSOR_ROTATE,
CURSOR_COUNT
} CURSOR_TYPE;
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Initialization
//
static void Initialize (void);
static void Shutdown (void);
//
// Display methods
//
static void Show_Cursor (bool onoff);
static void Set_Cursor (CURSOR_TYPE type);
static void Begin_Wait_Cursor(void);
static void End_Wait_Cursor(void);
//
// Render methods
//
static void Render (void);
private:
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
static TextureClass * Textures[CURSOR_COUNT];
static ScreenCursorClass * MouseCursor;
static CURSOR_TYPE CursorType;
static unsigned int CursorWaitCount;
};
#endif //__MOUSE_MGR_H

Some files were not shown because too many files have changed in this diff Show More