This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
// AnimSequences.cpp : implementation file
//
#include "stdafx.h"
#include "AnimSequences.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAnimSequences
CAnimSequences::CAnimSequences()
{
}
CAnimSequences::~CAnimSequences()
{
}
BEGIN_MESSAGE_MAP(CAnimSequences, CComboBox)
//{{AFX_MSG_MAP(CAnimSequences)
ON_WM_CTLCOLOR()
ON_WM_CREATE()
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAnimSequences message handlers
HBRUSH CAnimSequences::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
////////////////////////////////////////////////////////////////////////
// The combox box should be drawn with a different font
////////////////////////////////////////////////////////////////////////
CFont cComboBoxFont;
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_LISTBOX)
{
VERIFY(cComboBoxFont.CreatePointFont(60, "Terminal"));
pDC->SelectObject(&cComboBoxFont);
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
int CAnimSequences::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
// Change some states of the controls
////////////////////////////////////////////////////////////////////////
static CFont cComboBoxFont;
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
// Set item size and list box heigt
VERIFY(SetItemHeight(0, 11) != CB_ERR);
VERIFY(SetItemHeight(-1, 150) != CB_ERR);
// Change the font to a smaller one
VERIFY(cComboBoxFont.CreatePointFont(60, "Terminal"));
SetFont(&cComboBoxFont, TRUE);
return 0;
}
void CAnimSequences::OnDropdown()
{
}

View File

@@ -0,0 +1,50 @@
#if !defined(AFX_ANIMSEQUENCES_H__AF987D7B_1EC7_403A_B190_E05E2B2D3FD6__INCLUDED_)
#define AFX_ANIMSEQUENCES_H__AF987D7B_1EC7_403A_B190_E05E2B2D3FD6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// AnimSequences.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CAnimSequences window
class CAnimSequences : public CComboBox
{
// Construction
public:
CAnimSequences();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAnimSequences)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CAnimSequences();
// Generated message map functions
protected:
//{{AFX_MSG(CAnimSequences)
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDropdown();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ANIMSEQUENCES_H__AF987D7B_1EC7_403A_B190_E05E2B2D3FD6__INCLUDED_)

View File

@@ -0,0 +1,179 @@
// AnimationToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "AnimationToolBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAnimationToolBar
CAnimationToolBar::CAnimationToolBar()
{
}
CAnimationToolBar::~CAnimationToolBar()
{
}
BEGIN_MESSAGE_MAP(CAnimationToolBar, CToolBar)
//{{AFX_MSG_MAP(CAnimationToolBar)
ON_WM_SIZE()
ON_WM_CTLCOLOR()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAnimationToolBar message handlers
void CAnimationToolBar::OnSize(UINT nType, int cx, int cy)
{
////////////////////////////////////////////////////////////////////////
// Resize the keyframe slider
////////////////////////////////////////////////////////////////////////
unsigned int iIndex;
RECT rcCtrl, rcToolbar;
CToolBar::OnSize(nType, cx, cy);
if (!GetToolBarCtrl().GetButtonCount())
return;
// Get the index of the keyframe slider position in the toolbar
iIndex = 0;
while (GetItemID(iIndex) != IDR_KEYFRAMES)
iIndex++;
if (GetItemID(iIndex) != IDR_KEYFRAMES)
return;
// Get size and position of toolbar and slider control
GetItemRect(iIndex, &rcCtrl);
GetClientRect(&rcToolbar);
// Get new slider width
rcCtrl.right = rcToolbar.right;
// Set in if the slider is created
if (m_cKeyframes.m_hWnd)
{
m_cKeyframes.SetWindowPos(NULL, 0, 0, (rcToolbar.right - rcCtrl.left) / 2,
18, SWP_NOMOVE | SWP_NOOWNERZORDER);
}
// Get the index of the animation sequence combo box position in the toolbar
iIndex = 0;
while (GetItemID(iIndex) != IDR_ANIM_SEQUENCES)
iIndex++;
if (GetItemID(iIndex) != IDR_ANIM_SEQUENCES)
return;
// Get size and position of toolbar and combo box control
GetItemRect(iIndex, &rcCtrl);
GetClientRect(&rcToolbar);
// Get new combo box width
rcCtrl.right = rcToolbar.right;
// Set in if the combo box is created
if (m_cAnimSequences.m_hWnd)
{
m_cAnimSequences.SetWindowPos(NULL, 0, 0, (rcToolbar.right - rcCtrl.left) / 2,
18, SWP_NOMOVE | SWP_NOOWNERZORDER);
// Place the combox box right of the keyframe slider
GetItemRect(iIndex, &rcCtrl);
rcCtrl.top += 3;
rcCtrl.bottom += 200;
rcCtrl.left = (rcToolbar.right) / 2 + 65;
rcCtrl.right = (rcToolbar.right) / 2 - 75;
::SetWindowPos(m_cAnimSequences.m_hWnd, NULL, rcCtrl.left, rcCtrl.top,
rcCtrl.right, rcCtrl.bottom, SWP_NOZORDER);
}
}
HBRUSH CAnimationToolBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CToolBar::OnCtlColor(pDC, pWnd, nCtlColor);
CFont cComboBoxFont;
if (nCtlColor == CTLCOLOR_EDIT)
{
VERIFY(cComboBoxFont.CreatePointFont(60, "Terminal"));
pDC->SelectObject(&cComboBoxFont);
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
int CAnimationToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CToolBar::OnCreate(lpCreateStruct) == -1)
return -1;
if (!LoadToolBar(IDR_ANIMATION))
return -1;
// Create controls in the animation bar
CRect rect;
GetClientRect( &rect );
// Get the index of the keyframe slider position in the toolbar
int iIndex = 0;
while (GetItemID(iIndex) != IDR_KEYFRAMES)
iIndex++;
// Convert that button to a seperator and get its position
SetButtonInfo(iIndex, IDR_KEYFRAMES, TBBS_SEPARATOR, 0);
GetItemRect(iIndex, &rect);
// Expand the rectangle
rect.top += 2;
rect.bottom -= 2;
// TODO: Remove WS_DISABLED when animation is implemented
m_cKeyframes.Create(WS_CHILD|WS_VISIBLE|TBS_HORZ|TBS_BOTTOM|TBS_AUTOTICKS,rect,this,NULL);
// Get the index of the animation sequence combo box position in the toolbar
iIndex = 0;
while (GetItemID(iIndex) != IDR_ANIM_SEQUENCES)
iIndex++;
// Convert that button to a seperator and get its position
//SetButtonInfo(iIndex, IDR_ANIM_SEQUENCES, TBBS_SEPARATOR, 252);
SetButtonInfo(iIndex, IDR_ANIM_SEQUENCES, TBBS_SEPARATOR, 0);
GetItemRect(iIndex, &rect);
// Expand the rectangle
rect.top += 2;
rect.bottom += 75;
// TODO: Remove WS_DISABLED when animation is implemented
m_cAnimSequences.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,rect,this,NULL);
m_cKeyframes.SetRange(0, 50);
return 0;
}
CString CAnimationToolBar::GetAnimName()
{
int sel = m_cAnimSequences.GetCurSel();
if (sel == CB_ERR)
{
return "";
}
CString str;
m_cAnimSequences.GetLBText( sel,str );
return str;
}

View File

@@ -0,0 +1,56 @@
#if !defined(AFX_ANIMATIONTOOLBAR_H__4ED3FCE4_CB04_487F_84B5_AE815BE2711D__INCLUDED_)
#define AFX_ANIMATIONTOOLBAR_H__4ED3FCE4_CB04_487F_84B5_AE815BE2711D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// AnimationToolBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CAnimationToolBar window
#include "AnimSequences.h"
class CAnimationToolBar : public CToolBar
{
// Construction
public:
CAnimationToolBar();
// Attributes
public:
// Operations
public:
CString GetAnimName();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAnimationToolBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CAnimationToolBar();
CSliderCtrl m_cKeyframes; // IDR_KEYFRAMES
CAnimSequences m_cAnimSequences; // IDR_ANIM_SEQUENCES
// Generated message map functions
protected:
//{{AFX_MSG(CAnimationToolBar)
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ANIMATIONTOOLBAR_H__4ED3FCE4_CB04_487F_84B5_AE815BE2711D__INCLUDED_)

View File

@@ -0,0 +1,61 @@
// ColorCheckBox.cpp : implementation file
//
#include "stdafx.h"
#include "ColorCheckBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CColorCheckBox
IMPLEMENT_DYNCREATE( CColorCheckBox,CButton )
CColorCheckBox::CColorCheckBox()
{
m_nChecked = 0;
}
CColorCheckBox::~CColorCheckBox()
{
}
//BEGIN_MESSAGE_MAP(CColorCheckBox, CColoredPushButton)
// //{{AFX_MSG_MAP(CColorCheckBox)
// // NOTE - the ClassWizard will add and remove mapping macros here.
// //}}AFX_MSG_MAP
//END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CColorCheckBox message handlers
void CColorCheckBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (m_nChecked == 1)
{
lpDrawItemStruct->itemState |= ODS_SELECTED;
}
CColoredPushButton::DrawItem( lpDrawItemStruct );
}
//////////////////////////////////////////////////////////////////////////
void CColorCheckBox::SetCheck(int nCheck)
{
if (m_nChecked != nCheck)
{
m_nChecked = nCheck;
if(::IsWindow(m_hWnd))
Invalidate();
}
};
//////////////////////////////////////////////////////////////////////////
void CColorCheckBox::PreSubclassWindow()
{
CColoredPushButton::PreSubclassWindow();
SetButtonStyle( BS_PUSHBUTTON|BS_OWNERDRAW );
}

View File

@@ -0,0 +1,62 @@
#if !defined(AFX_COLORCHECKBOX_H__8D5C1FE0_9A53_4247_8CF6_C23C0C829291__INCLUDED_)
#define AFX_COLORCHECKBOX_H__8D5C1FE0_9A53_4247_8CF6_C23C0C829291__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ColorCheckBox.h : header file
//
#define STD_PUSHED_COLOR (RGB(255,255,0))
typedef CColorCtrl<CColorPushButton<CButton> > CColoredPushButton;
typedef CColorCtrl<CColorPushButton<CButton> > CCustomButton;
/////////////////////////////////////////////////////////////////////////////
// CColorCheckBox window
class CColorCheckBox : public CColoredPushButton
{
DECLARE_DYNCREATE( CColorCheckBox )
// Construction
public:
CColorCheckBox();
int GetCheck() const { return m_nChecked; };
void SetCheck(int nCheck);
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorCheckBox)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CColorCheckBox();
// Generated message map functions
protected:
//{{AFX_MSG(CColorCheckBox)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// DECLARE_MESSAGE_MAP()
int m_nChecked;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORCHECKBOX_H__8D5C1FE0_9A53_4247_8CF6_C23C0C829291__INCLUDED_)

796
Editor/Controls/ColorCtrl.h Normal file
View File

@@ -0,0 +1,796 @@
#if !defined(AFX_COLORCTRL_H__CA4DE73C_CDC9_11D3_B261_00104BB13A66__INCLUDED_)
#define AFX_COLORCTRL_H__CA4DE73C_CDC9_11D3_B261_00104BB13A66__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "TemplDef.h" // message map extensions for templates
///////////////////////////////////////////////////////////////////////////////
// class CColorCtrl
//
// Author: Yury Goltsman
// email: ygprg@go.to
// page: http://go.to/ygprg
// Copyright <20> 2000, Yury Goltsman
//
// This code provided "AS IS," without any kind of warranty.
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// version : 1.5
// fixed - problem with transparency (CLR_NONE)
//
// version : 1.4
// added CColorPushButton - class that allows to change colors for button
//
// version : 1.3
// added pattern for background (for win9x restricted to 8*8 pixels)
// added posibility to use solid colors (in this case we don't
// select transparency for background color)
//
// version : 1.2
// bug fixing
// added typedefs for some mfc controls
// derived templates CColorCtrlEx and CBlinkCtrlEx with initial
// template parameters added
// message map macro added
//
// version : 1.1
// bug fixing
//
enum
{
CC_BLINK_NOCHANGE = 0,
CC_BLINK_FAST = 500,
CC_BLINK_NORMAL = 1000,
CC_BLINK_SLOW = 2000
};
enum
{
CC_BLINK_TEXT = 1,
CC_BLINK_BK = 2,
CC_BLINK_BOTH = CC_BLINK_TEXT|CC_BLINK_BK
};
#define CC_SYSCOLOR(ind) (0x80000000|((ind) & ~CLR_DEFAULT))
template<class BASE_TYPE = CWnd>
class CColorCtrl : public BASE_TYPE
{
public:
CColorCtrl();
virtual ~CColorCtrl(){}
public:
void SetTextColor(COLORREF rgbText = CLR_DEFAULT);
COLORREF GetTextColor(){ return GetColor(m_rgbText); }
void SetTextBlinkColors(COLORREF rgbBlinkText1, COLORREF rgbBlinkText2);
void SetBkColor(COLORREF rgbBk = CLR_DEFAULT);
COLORREF GetBkColor(){ return GetColor(m_rgbBk); }
void SetBkBlinkColors(COLORREF rgbBlinkBk1, COLORREF rgbBlinkBk2);
void SetBkPattern(UINT nBkID = 0);
void SetBkPattern(HBITMAP hbmpBk = 0);
void SetBkBlinkPattern(UINT nBkID1, UINT nBkID2);
void SetBkBlinkPattern(HBITMAP hbmpBk1, HBITMAP hbmpBk2);
void StartBlink(int iWho = CC_BLINK_BOTH, UINT nDelay = CC_BLINK_NOCHANGE);
void StopBlink(int iWho = CC_BLINK_BOTH);
UINT GetDelay() { return m_nDelay; }
void UseSolidColors(BOOL fSolid = TRUE);
void ForceOpaque(){m_fForceOpaque = TRUE;}
//protected:
void SetBlinkTimer()
{
// set timer if blinking mode
if(m_nTimerID <= 0 && (m_fBlinkText || m_fBlinkBk))
m_nTimerID = SetTimer(1, m_nDelay, NULL);
}
void KillBlinkTimer()
{
// reset timer
KillTimer(m_nTimerID);
m_nTimerID = 0;
m_iBlinkPhase = 0;
}
COLORREF GetColor(COLORREF clr)
{
if(clr == CLR_NONE)
return clr;
DWORD mask = clr & CLR_DEFAULT;
if(mask == 0x80000000)
return ::GetSysColor(clr & ~CLR_DEFAULT); // system color
if(mask == CLR_DEFAULT)
return CLR_DEFAULT; // default color
return clr & ~CLR_DEFAULT; // normal color
}
//protected:
UINT m_nTimerID;
int m_iBlinkPhase;
UINT m_nDelay;
BOOL m_fBlinkText;
BOOL m_fBlinkBk;
BOOL m_fSolid;
BOOL m_fForceOpaque;
COLORREF m_rgbText;
COLORREF m_rgbBlinkText[2];
COLORREF m_rgbBk;
CBitmap m_bmpBk;
COLORREF m_rgbBlinkBk[2];
CBitmap m_bmpBlinkBk[2];
CBrush m_brBk;
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorCtrl)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
//protected:
//{{AFX_MSG(CColorCtrl)
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnDestroy();
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_TEMPLATE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
typedef CColorCtrl<CEdit> CColoredEdit;
typedef CColorCtrl<CButton> CColoredButton;
typedef CColorCtrl<CStatic> CColoredStatic;
typedef CColorCtrl<CScrollBar> CColoredScrollBar;
typedef CColorCtrl<CListBox> CColoredListBox;
typedef CColorCtrl<CComboBox> CColoredComboBox;
typedef CColorCtrl<CDialog> CColoredDialog;
/////////////////////////////////////////////////////////////////////////////
template<class BASE_TYPE>
CColorCtrl<BASE_TYPE>::CColorCtrl()
{
// set control to non-blinking mode
m_nTimerID = 0;
m_iBlinkPhase = 0;
m_nDelay = CC_BLINK_NORMAL;
m_fSolid = FALSE;
m_fForceOpaque = FALSE;
m_fBlinkText = FALSE;
m_fBlinkBk = FALSE;
// set foreground colors
m_rgbText = CLR_DEFAULT;
m_rgbBlinkText[0] = m_rgbText;
m_rgbBlinkText[1] = m_rgbText;
// set background colors
m_rgbBk = CLR_DEFAULT;
m_rgbBlinkBk[0] = m_rgbBk;
m_rgbBlinkBk[1] = m_rgbBk;
}
BEGIN_TEMPLATE_MESSAGE_MAP(class BASE_TYPE, CColorCtrl<BASE_TYPE>, BASE_TYPE)
//{{AFX_MSG_MAP(CColorCtrl)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_CTLCOLOR()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_TEMPLATE_MESSAGE_MAP()
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetTextColor(COLORREF rgbText)
{
m_rgbText = rgbText;
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetTextBlinkColors(COLORREF rgbBlinkText1, COLORREF rgbBlinkText2)
{
m_rgbBlinkText[0] = rgbBlinkText1;
m_rgbBlinkText[1] = rgbBlinkText2;
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkColor(COLORREF rgbBk)
{
m_rgbBk = rgbBk;
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkBlinkColors(COLORREF rgbBlinkBk1, COLORREF rgbBlinkBk2)
{
m_rgbBlinkBk[0] = rgbBlinkBk1;
m_rgbBlinkBk[1] = rgbBlinkBk2;
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkPattern(UINT nBkID)
{
m_bmpBk.DeleteObject();
if(nBkID > 0)
m_bmpBk.LoadBitmap(nBkID);
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkPattern(HBITMAP hbmpBk)
{
m_bmpBk.DeleteObject();
if(hbmpBk != 0)
m_bmpBk.Attach(hbmpBk);
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkBlinkPattern(UINT nBkID1, UINT nBkID2)
{
m_bmpBlinkBk[0].DeleteObject();
m_bmpBlinkBk[1].DeleteObject();
if(nBkID1 > 0)
m_bmpBlinkBk[0].LoadBitmap(nBkID1);
if(nBkID2 > 0)
m_bmpBlinkBk[1].LoadBitmap(nBkID2);
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::SetBkBlinkPattern(HBITMAP hbmpBk1, HBITMAP hbmpBk2)
{
m_bmpBlinkBk[0].DeleteObject();
m_bmpBlinkBk[1].DeleteObject();
if(hbmpBk1 != 0)
m_bmpBlinkBk[0].Attach(hbmpBk1);
if(hbmpBk2 != 0)
m_bmpBlinkBk[1].Attach(hbmpBk2);
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::UseSolidColors(BOOL fSolid)
{
m_fSolid = fSolid;
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::StartBlink(int iWho, UINT nDelay)
{
if(iWho & CC_BLINK_TEXT)
m_fBlinkText = TRUE;
if(iWho & CC_BLINK_BK)
m_fBlinkBk = TRUE;
if(nDelay != CC_BLINK_NOCHANGE)
{
m_nDelay = nDelay;
if (m_nTimerID > 0)
{
ASSERT(::IsWindow(m_hWnd));
// reset old timer if delay changed
KillBlinkTimer();
}
}
ASSERT(m_fBlinkText||m_fBlinkBk);
if(!::IsWindow(m_hWnd))
return;
// if no timer - set it
SetBlinkTimer();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::StopBlink(int iWho)
{
if(iWho & CC_BLINK_TEXT)
m_fBlinkText = FALSE;
if(iWho & CC_BLINK_BK)
m_fBlinkBk = FALSE;
if(m_nTimerID > 0 && !m_fBlinkText && !m_fBlinkBk)
{
ASSERT(::IsWindow(m_hWnd));
// stop timer if no blinking and repaint
KillBlinkTimer();
Invalidate();
}
}
template<class BASE_TYPE>
HBRUSH CColorCtrl<BASE_TYPE>::CtlColor(CDC* pDC, UINT nCtlColor)
{
// Get foreground color
COLORREF rgbText = GetColor(m_fBlinkText ? m_rgbBlinkText[m_iBlinkPhase]
: m_rgbText);
// Get background color
COLORREF rgbBk = GetColor(m_fBlinkBk ? m_rgbBlinkBk[m_iBlinkPhase]
: m_rgbBk);
// Get background pattern
CBitmap& bmpBk = m_fBlinkBk ? m_bmpBlinkBk[m_iBlinkPhase] : m_bmpBk;
// if both colors are default - use default colors
if(rgbText == CLR_DEFAULT && rgbBk == CLR_DEFAULT && !bmpBk.GetSafeHandle())
return 0;
// if one of colors is default - get system color for it
if(rgbBk == CLR_DEFAULT)
{
// text color specified and background - not.
switch(nCtlColor)
{
case CTLCOLOR_EDIT:
case CTLCOLOR_LISTBOX:
rgbBk = GetSysColor(COLOR_WINDOW);
break;
case CTLCOLOR_BTN:
case CTLCOLOR_DLG:
case CTLCOLOR_MSGBOX:
case CTLCOLOR_STATIC:
default:
rgbBk = ::GetSysColor(COLOR_BTNFACE);
break;
case CTLCOLOR_SCROLLBAR:
// for scroll bar no meaning in text color - use parent OnCtlColor
return 0;
}
}
if(rgbText == CLR_DEFAULT)
{
// background color specified and text - not.
switch(nCtlColor)
{
default:
rgbText = ::GetSysColor(COLOR_WINDOWTEXT);
break;
case CTLCOLOR_BTN:
rgbText = ::GetSysColor(COLOR_BTNTEXT);
break;
}
}
ASSERT(rgbText != CLR_DEFAULT);
ASSERT(rgbBk != CLR_DEFAULT);
if(m_fSolid)
{
if(rgbBk != CLR_NONE)
rgbBk = ::GetNearestColor(pDC->m_hDC, rgbBk);
rgbText = ::GetNearestColor(pDC->m_hDC, rgbText);
}
if(m_fForceOpaque && rgbBk != CLR_NONE)
pDC->SetBkMode(OPAQUE);
else
pDC->SetBkMode(TRANSPARENT);
// set colors
pDC->SetTextColor(rgbText);
pDC->SetBkColor(rgbBk);
// update brush
m_brBk.DeleteObject();
if(bmpBk.GetSafeHandle())
m_brBk.CreatePatternBrush(&bmpBk);
else if(rgbBk != CLR_NONE)
m_brBk.CreateSolidBrush(rgbBk);
else
return (HBRUSH) ::GetStockObject (HOLLOW_BRUSH);
return (HBRUSH)m_brBk;
}
template<class BASE_TYPE>
HBRUSH CColorCtrl<BASE_TYPE>::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if(pWnd->m_hWnd == m_hWnd)
return BASE_TYPE::OnCtlColor(pDC, pWnd, nCtlColor); // for dialogs
return BASE_TYPE::OnCtlColor(pDC, this, nCtlColor); // send reflect message
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::OnDestroy()
{
// kill timer
KillBlinkTimer();
BASE_TYPE::OnDestroy();
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent != m_nTimerID)
{
BASE_TYPE::OnTimer(nIDEvent);
return;
}
// if there is active blinking
if (m_fBlinkBk || m_fBlinkText)
{
// change blinking phase and repaint
m_iBlinkPhase = !m_iBlinkPhase;
Invalidate();
}
}
template<class BASE_TYPE>
void CColorCtrl<BASE_TYPE>::PreSubclassWindow()
{
// set timer if blinking mode
SetBlinkTimer();
BASE_TYPE::PreSubclassWindow();
}
template<class BASE_TYPE>
int CColorCtrl<BASE_TYPE>::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (BASE_TYPE::OnCreate(lpCreateStruct) == -1)
return -1;
// set timer if blinking mode
SetBlinkTimer();
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// class CColorCtrlEx
template<class BASE_TYPE, int InitialTextColor = CLR_DEFAULT, int InitialBkColor = CLR_DEFAULT>
class CColorCtrlEx : public CColorCtrl<BASE_TYPE>
{
public:
CColorCtrlEx()
{
m_rgbText = InitialTextColor;
m_rgbBk = InitialBkColor;
}
};
///////////////////////////////////////////////////////////////////////////////
// class CBlinkCtrlEx
template<class BASE_TYPE,
int InitialTextColor0 = CLR_DEFAULT,
int InitialTextColor1 = CLR_DEFAULT,
int InitialBkColor0 = CLR_DEFAULT,
int InitialBkColor1 = CLR_DEFAULT,
int InitialDelay = CC_BLINK_NORMAL>
class CBlinkCtrlEx : public CColorCtrl<BASE_TYPE>
{
public:
CBlinkCtrlEx()
{
m_nDelay = InitialDelay;
m_rgbBlinkText[0] = InitialTextColor0;
m_rgbBlinkText[1] = InitialTextColor1;
if(InitialTextColor0 != CLR_DEFAULT || InitialTextColor1 != CLR_DEFAULT)
m_fBlinkText = TRUE;
m_rgbBlinkBk[0] = InitialBkColor0;
m_rgbBlinkBk[1] = InitialBkColor1;
if(InitialBkColor0 != CLR_DEFAULT || InitialBkColor1 != CLR_DEFAULT)
m_fBlinkBk = TRUE;
}
};
///////////////////////////////////////////////////////////////////////////////
// class CColorPushButton
template<class BASE_TYPE>
class CColorPushButton : public BASE_TYPE
{
public:
CColorPushButton();
~CColorPushButton();
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorPushButton)
protected:
virtual void PreSubclassWindow();
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
public:
void SetNoFocus(bool fNoFocus = true){m_fNoFocus = fNoFocus;}
void SetNoDisabledState(bool fNoDisabledState = true) {m_fNoDisabledState = fNoDisabledState;}
void SetPushedBkColor(COLORREF rgbBk = CLR_DEFAULT);
COLORREF GetPushedBkColor(){ return GetColor(m_rgbBk); }
//! Set icon to display on button, (must not be shared).
void SetIcon( HICON hIcon );
void SetIcon( LPCSTR lpszIconResource );
void SetToolTip( const char *tooltipText );
protected:
void ChangeStyle();
bool m_fNoFocus;
bool m_fNoDisabledState;
COLORREF m_rgbPushedBk;
CBrush m_pushedBk;
HICON m_hIcon;
CToolTipCtrl *m_tooltip;
//{{AFX_MSG(CColorPushButton)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_TEMPLATE_MESSAGE_MAP()
};
BEGIN_TEMPLATE_MESSAGE_MAP(class BASE_TYPE, CColorPushButton<BASE_TYPE>, BASE_TYPE)
//{{AFX_MSG_MAP(CColorPushButton)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_TEMPLATE_MESSAGE_MAP()
template<class BASE_TYPE>
CColorPushButton<BASE_TYPE>::CColorPushButton()
{
m_fNoFocus = true;
m_fNoDisabledState = false;
m_hIcon = 0;
m_tooltip=0;
// Yellow pushed button.
m_pushedBk.CreateSolidBrush( RGB(255,255,0) );
}
template<class BASE_TYPE>
CColorPushButton<BASE_TYPE>::~CColorPushButton()
{
if (m_tooltip)
delete m_tooltip;
m_tooltip = 0;
if (m_hIcon)
DestroyIcon(m_hIcon);
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetToolTip( const char *tooltipText )
{
if (!m_tooltip)
{
m_tooltip = new CToolTipCtrl;
m_tooltip->Create( this );
CRect rc;
GetClientRect(rc);
m_tooltip->AddTool( this,tooltipText,rc,1 );
}
else
{
m_tooltip->UpdateTipText( tooltipText,this,1 );
}
m_tooltip->Activate(TRUE);
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetIcon( LPCSTR lpszIconResource )
{
if (m_hIcon)
DestroyIcon(m_hIcon);
SetIcon( (HICON)::LoadImage( AfxGetInstanceHandle(),lpszIconResource,IMAGE_ICON,0,0,0 ) );
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetIcon( HICON hIcon )
{
m_hIcon = hIcon;
// Get tool tip from title.
CString sCaption;
GetWindowText(sCaption);
SetToolTip(sCaption);
};
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::SetPushedBkColor(COLORREF rgbBk)
{
m_rgbPushedBk = rgbBk;
m_pushedBk.DeleteObject();
m_pushedBk.CreateSolidBrush( m_rgbPushedBk );
if(::IsWindow(m_hWnd))
Invalidate();
}
template<class BASE_TYPE>
BOOL CColorPushButton<BASE_TYPE>::PreTranslateMessage(MSG* pMsg)
{
if (m_tooltip && m_tooltip->m_hWnd != 0)
m_tooltip->RelayEvent(pMsg);
return BASE_TYPE::PreTranslateMessage(pMsg);
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::PreSubclassWindow()
{
ChangeStyle();
BASE_TYPE::PreSubclassWindow();
}
template<class BASE_TYPE>
int CColorPushButton<BASE_TYPE>::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (BASE_TYPE::OnCreate(lpCreateStruct) == -1)
return -1;
ChangeStyle();
return 0;
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::ChangeStyle()
{
CString sClassName;
GetClassName(m_hWnd, sClassName.GetBuffer(10), 10);
sClassName.ReleaseBuffer();
DWORD style = GetStyle();
ASSERT(sClassName.CompareNoCase(_T("BUTTON")) == 0); // must be used only with buttons
ASSERT((style & (BS_BITMAP)) == 0); // dont supports bitmap buttons
//ASSERT((style & (BS_ICON|BS_BITMAP)) == 0); // dont supports icon/bitmap buttons
if((style & 0xf) == BS_PUSHBUTTON ||
(style & 0xf) == BS_DEFPUSHBUTTON)
{
ModifyStyle(0xf, BS_OWNERDRAW);
Invalidate(FALSE);
}
}
template<class BASE_TYPE>
void CColorPushButton<BASE_TYPE>::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rc(lpDrawItemStruct->rcItem);
UINT state = lpDrawItemStruct->itemState;
CString sCaption;
GetWindowText(sCaption);
DWORD style = GetStyle();
CRect rcFocus(rc);
rcFocus.DeflateRect(4, 4);
int iSavedDC = pDC->SaveDC();
//pDC->SetBkColor( m_rgbPushedBk );
// draw frame
if(((state & ODS_DEFAULT) || (state & ODS_FOCUS)) && !m_fNoFocus)
{
// draw def button black rectangle
pDC->Draw3dRect(rc, GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME));
rc.DeflateRect(1, 1);
}
if(style & BS_FLAT)
{
pDC->Draw3dRect(rc, GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME));
rc.DeflateRect(1, 1);
pDC->Draw3dRect(rc, GetSysColor(COLOR_WINDOW), GetSysColor(COLOR_WINDOW));
rc.DeflateRect(1, 1);
}
else
{
if(state & ODS_SELECTED)
{
pDC->Draw3dRect(rc, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DSHADOW));
rc.DeflateRect(1, 1);
//pDC->Draw3dRect(rc, GetSysColor(COLOR_3DFACE), GetSysColor(COLOR_3DFACE));
//rc.DeflateRect(1, 1);
}
else
{
pDC->Draw3dRect(rc, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
rc.DeflateRect(1, 1);
//pDC->Draw3dRect(rc, GetSysColor(COLOR_3DFACE), GetSysColor(COLOR_3DSHADOW));
//rc.DeflateRect(1, 1);
}
}
// fill background
HBRUSH brush = (HBRUSH)SendMessage(WM_CTLCOLORBTN, (WPARAM)pDC->m_hDC, (LPARAM)m_hWnd);
if(state & ODS_SELECTED)
{
pDC->SetBkMode(TRANSPARENT);
brush = m_pushedBk;
}
if(brush)
::FillRect(pDC->m_hDC, rc, brush);
if (m_hIcon)
{
// draw icon.
int w = GetSystemMetrics(SM_CXICON);
int h = GetSystemMetrics(SM_CYICON);
int x = rc.left + rc.Width()/2 - w/2+1;
int y = rc.top + rc.Height()/2 - h/2;
if(state & ODS_SELECTED)
{
x += 1; y += 1;
}
pDC->DrawIcon( CPoint(x,y),m_hIcon );
}
else
{
// draw text
UINT fTextStyle = 0;
switch(style & BS_CENTER)
{
case BS_LEFT : fTextStyle |= DT_LEFT; break;
case BS_RIGHT : fTextStyle |= DT_RIGHT; break;
default:
case BS_CENTER : fTextStyle |= DT_CENTER; break;
}
switch(style & BS_VCENTER)
{
case BS_TOP : fTextStyle |= DT_TOP; break;
case BS_BOTTOM : fTextStyle |= DT_BOTTOM; break;
default:
case BS_VCENTER : fTextStyle |= DT_VCENTER; break;
}
if(!(style & BS_MULTILINE)) fTextStyle |= DT_SINGLELINE;
else fTextStyle |= DT_WORDBREAK;
if(state & ODS_DISABLED && !m_fNoDisabledState)
{
pDC->SetBkMode(TRANSPARENT);
rc.DeflateRect(2, 2, 0, 0); // shift text down
pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
pDC->DrawText(sCaption, rc, fTextStyle);
rc.OffsetRect(-1, -1); // shift text up
pDC->SetTextColor(GetSysColor(COLOR_3DSHADOW));
pDC->DrawText(sCaption, rc, fTextStyle);
}
else
{
if(state & ODS_SELECTED)
rc.DeflateRect(2, 2, 0, 0); // shift text
pDC->DrawText(sCaption, rc, fTextStyle);
}
}
pDC->RestoreDC(iSavedDC);
// draw focus rect
if ((state & ODS_FOCUS) && !m_fNoFocus)
pDC->DrawFocusRect(rcFocus);
}
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORCTRL_H__CA4DE73C_CDC9_11D3_B261_00104BB13A66__INCLUDED_)

View File

@@ -0,0 +1,384 @@
// ConsoleSCB.cpp: implementation of the CConsoleSCB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ConsoleSCB.h"
#include "PropertiesDialog.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static CPropertiesDialog *gPropertiesDlg = 0;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CConsoleEdit, CEdit)
ON_WM_GETDLGCODE()
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CConsoleSCB, CWnd)
//{{AFX_MSG_MAP(CConsoleSCB)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_EN_SETFOCUS( IDC_EDIT,OnEditSetFocus )
ON_EN_KILLFOCUS( IDC_EDIT,OnEditKillFocus )
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static CVarBlock* VarBlockFromConsoleVars()
{
IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
std::vector<const char*> cmds;
cmds.resize( console->GetNumVars() );
console->GetSortedVars( &cmds[0],cmds.size() );
CVarBlock *vb = new CVarBlock;
IVariable* pVariable;
for (int i = 0; i < cmds.size(); i++)
{
ICVar *pCVar = console->GetCVar(cmds[i]);
int varType = pCVar->GetType();
switch(varType) {
case CVAR_INT:
pVariable = new CVariable<int>;
pVariable->SetName(cmds[i]);
pVariable->Set( pCVar->GetIVal() );
vb->AddVariable( pVariable );
pVariable->SetDescription( pCVar->GetHelp() );
pVariable->SetDescription( pCVar->GetHelp() );
break;
case CVAR_FLOAT:
pVariable = new CVariable<float>;
pVariable->SetName(cmds[i]);
pVariable->Set( pCVar->GetFVal() );
pVariable->SetDescription( pCVar->GetHelp() );
vb->AddVariable( pVariable );
break;
case CVAR_STRING:
pVariable = new CVariable<CString>;
pVariable->SetName(cmds[i]);
pVariable->Set( pCVar->GetString() );
pVariable->SetDescription( pCVar->GetHelp() );
vb->AddVariable( pVariable );
break;
}
}
return vb;
}
static void OnConsoleVariableUpdated( IVariable *pVar )
{
if (!pVar)
return;
CString varName = pVar->GetName();
ICVar *pCVar = GetIEditor()->GetSystem()->GetIConsole()->GetCVar(varName);
if (!pCVar)
return;
if (pVar->GetType() == IVariable::INT)
{
int val;
pVar->Get(val);
pCVar->Set(val);
}
else if (pVar->GetType() == IVariable::FLOAT)
{
float val;
pVar->Get(val);
pCVar->Set(val);
}
else if (pVar->GetType() == IVariable::STRING)
{
CString val;
pVar->Get(val);
pCVar->Set(val);
}
}
//////////////////////////////////////////////////////////////////////////
static CString popup_helper( HWND hwnd,int x,int y )
{
IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
std::vector<const char*> cmds;
cmds.resize( console->GetNumVars() );
console->GetSortedVars( &cmds[0],cmds.size() );
TSmartPtr<CVarBlock> vb = VarBlockFromConsoleVars();
XmlNodeRef node;
if (!gPropertiesDlg)
gPropertiesDlg = new CPropertiesDialog( "Console Variables",node,AfxGetMainWnd() );
if (!gPropertiesDlg->m_hWnd)
{
gPropertiesDlg->Create( CPropertiesDialog::IDD,AfxGetMainWnd() );
gPropertiesDlg->SetUpdateCallback( functor(OnConsoleVariableUpdated) );
}
gPropertiesDlg->ShowWindow( SW_SHOW );
gPropertiesDlg->GetPropertyCtrl()->AddVarBlock( vb );
/*
HMENU hm = CreatePopupMenu();
for (int i = 0; i < cmds.size(); i++) {
AppendMenu( hm,MF_STRING,i+1,cmds[i] );
}
int res = TrackPopupMenuEx( hm,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD,x,y,hwnd,NULL );
if (res > 0) {
return cmds[res-1];
}
*/
return "";
}
UINT CConsoleEdit::OnGetDlgCode()
{
UINT code = CEdit::OnGetDlgCode();
code |= DLGC_WANTMESSAGE;
return code;
}
BOOL CConsoleEdit::PreTranslateMessage(MSG* msg)
{
if (msg->message == WM_LBUTTONDBLCLK || msg->message == WM_RBUTTONDOWN)
{
CPoint pnt;
GetCursorPos(&pnt);
CString str = popup_helper( GetSafeHwnd(),pnt.x,pnt.y );
if (!str.IsEmpty())
{
SetWindowText( str+" " );
}
}
else if (msg->message == WM_CHAR)
{
switch (msg->wParam)
{
case '~':
case '`':
// disable log.
GetIEditor()->ShowConsole( false );
SetWindowText( "" );
break;
}
} else if (msg->message == WM_KEYDOWN)
{
switch (msg->wParam)
{
case VK_RETURN:
{
CString str;
GetWindowText( str );
// Execute this string as command.
if (!str.IsEmpty())
{
CLogFile::WriteLine( str );
GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( str );
m_history.erase( std::remove(m_history.begin(),m_history.end(),str),m_history.end() );
m_history.push_back(str);
}
SetWindowText( "" );
return 0;
}
return TRUE;
break;
case VK_TAB:
{
GetAsyncKeyState(VK_CONTROL);
bool bCtrl = GetAsyncKeyState(VK_CONTROL) != 0;
IConsole *console = GetIEditor()->GetSystem()->GetIConsole();
CString inputStr,newStr;
GetWindowText( inputStr );
inputStr = inputStr.SpanExcluding( " " );
if (!bCtrl)
{
newStr = console->AutoComplete( inputStr );
}
else
{
newStr = console->AutoCompletePrev( inputStr );
}
if (!newStr.IsEmpty())
{
newStr += " ";
SetWindowText( newStr );
}
CString str;
GetWindowText( str );
SetSel( str.GetLength(),str.GetLength() );
return TRUE;
}
return TRUE;
break;
case VK_UP:
case VK_DOWN:
{
CString str;
CMenu menu;
menu.CreatePopupMenu();
for (int i = 0; i < m_history.size(); i++) {
menu.AppendMenu( MF_STRING,i+1,m_history[i] );
}
CPoint pnt;
GetCursorPos(&pnt);
int res = ::TrackPopupMenuEx( menu.GetSafeHmenu(),TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD,pnt.x,pnt.y,GetSafeHwnd(),NULL );
if (res > 0) {
str = m_history[res-1];
}
if (!str.IsEmpty())
{
SetWindowText( str );
SetSel( str.GetLength(),str.GetLength() );
}
}
return TRUE;
case VK_ESCAPE:
// disable log.
GetIEditor()->ShowConsole( false );
return TRUE;
break;
}
}
return CEdit::PreTranslateMessage(msg);
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CConsoleSCB::CConsoleSCB()
{
CLogFile::WriteLine("Console created");
}
CConsoleSCB::~CConsoleSCB()
{
if (gPropertiesDlg)
delete gPropertiesDlg;
gPropertiesDlg = 0;
CLogFile::WriteLine("Console destroyed");
}
int CConsoleSCB::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
// Create the edit control and register it
////////////////////////////////////////////////////////////////////////
RECT rcEdit;
CFont cListBoxFont;
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
/*
// Create the edit control
VERIFY(m_cListBox.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_NOSEL, rcEdit, this, NULL));
m_cListBox.ShowWindow( SW_HIDE );
*/
m_dialog.Create( CConsoleDialog::IDD,this );
m_edit.Create( WS_CHILD|WS_VISIBLE|ES_MULTILINE|WS_VSCROLL|ES_AUTOVSCROLL|ES_AUTOHSCROLL|ES_READONLY, rcEdit, &m_dialog, NULL );
m_edit.SetFont( CFont::FromHandle( (HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );
m_edit.ModifyStyleEx( 0,WS_EX_STATICEDGE );
m_edit.SetLimitText(0);
m_input.Create( WS_CHILD|WS_VISIBLE|ES_WANTRETURN|ES_AUTOHSCROLL|WS_TABSTOP, rcEdit, &m_dialog, IDC_EDIT );
m_input.SetFont( CFont::FromHandle( (HFONT)::GetStockObject(SYSTEM_FONT)) );
m_input.ModifyStyleEx( 0,WS_EX_STATICEDGE );
m_input.SetWindowText( "" );
/*
// Change
cListBoxFont.Attach(::GetStockObject(DEFAULT_GUI_FONT));
m_cListBox.SetFont(&cListBoxFont);
cListBoxFont.Detach();
*/
// Attach / register the listbox control
//CLogFile::AttachListBox(m_cListBox.m_hWnd);
CLogFile::AttachEditBox(m_edit.GetSafeHwnd());
return 0;
}
void CConsoleSCB::OnSize(UINT nType, int cx, int cy)
{
////////////////////////////////////////////////////////////////////////
// Resize the edit control
////////////////////////////////////////////////////////////////////////
RECT rcEdit;
CWnd::OnSize(nType, cx, cy);
// Get the size of the client window
GetClientRect(&rcEdit);
/*
// Set the position of the listbox
m_cListBox.SetWindowPos(NULL, rcEdit.left + 3, rcEdit.top + 3, rcEdit.right - 6,
rcEdit.bottom - 6, SWP_NOZORDER);
*/
int inputH = 18;
m_dialog.MoveWindow( rcEdit.left,rcEdit.top,rcEdit.right,rcEdit.bottom );
m_edit.SetWindowPos(NULL, rcEdit.left, rcEdit.top + 2, rcEdit.right, rcEdit.bottom - 1 - inputH, SWP_NOZORDER);
m_input.SetWindowPos(NULL, rcEdit.left, rcEdit.bottom-inputH, rcEdit.right, rcEdit.bottom - 2, SWP_NOZORDER);
m_input.SetFocus();
}
void CConsoleSCB::OnDestroy()
{
////////////////////////////////////////////////////////////////////////
// Unregister the edit control
////////////////////////////////////////////////////////////////////////
CLogFile::AttachEditBox(NULL);
CLogFile::WriteLine("Console control bar destroied");
}
void CConsoleSCB::OnSetFocus( CWnd* pOldWnd )
{
m_input.SetFocus();
}
BOOL CConsoleSCB::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
return TRUE;
}
void CConsoleSCB::OnEditSetFocus()
{
// Disable accelerators when Edit gets focus.
GetIEditor()->EnableAcceleratos( false );
}
void CConsoleSCB::OnEditKillFocus()
{
// Enable accelerators when Edit loose focus.
GetIEditor()->EnableAcceleratos( true );
}
void CConsoleSCB::SetInputFocus()
{
m_input.SetFocus();
m_input.SetWindowText( "" );
}

View File

@@ -0,0 +1,63 @@
// ConsoleSCB.h: interface for the CConsoleSCB class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CONSOLESCB_H__F8855885_1C08_4504_BDA3_7BFB98D381EA__INCLUDED_)
#define AFX_CONSOLESCB_H__F8855885_1C08_4504_BDA3_7BFB98D381EA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "sizecbar.h"
#include "scbarg.h"
#include "ConsoleDialog.h"
/** Edit box used for input in Console.
*/
class CConsoleEdit : public CEdit
{
public:
DECLARE_MESSAGE_MAP()
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg UINT OnGetDlgCode();
private:
std::vector<CString> m_history;
};
/** Console class.
*/
class CConsoleSCB : public CWnd
{
public:
CConsoleSCB();
virtual ~CConsoleSCB();
void SetInputFocus();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyBar)
//}}AFX_VIRTUAL
protected:
CListBox m_cListBox;
CEdit m_edit;
CConsoleEdit m_input;
CConsoleDialog m_dialog;
//{{AFX_MSG(CMyBar)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void CConsoleSCB::OnDestroy();
afx_msg void OnSetFocus( CWnd* pOldWnd );
afx_msg void OnEditSetFocus();
afx_msg void OnEditKillFocus();
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // !defined(AFX_CONSOLESCB_H__F8855885_1C08_4504_BDA3_7BFB98D381EA__INCLUDED_)

View File

@@ -0,0 +1,98 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: customcomboboxex.h
// Version: v1.00
// Created: 4/9/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __customcomboboxex_h__
#define __customcomboboxex_h__
#pragma once
/////////////////////////////////////////////////////////////////////////////
// CCustomComboBoxEx template control
template<class BASE_TYPE>
class CCustomComboBoxEx : public BASE_TYPE
{
protected:
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg UINT OnGetDlgCode();
DECLARE_TEMPLATE_MESSAGE_MAP()
};
BEGIN_TEMPLATE_MESSAGE_MAP(class BASE_TYPE, CCustomComboBoxEx<BASE_TYPE>, BASE_TYPE)
//{{AFX_MSG_MAP(CColorPushButton)
ON_WM_GETDLGCODE()
//}}AFX_MSG_MAP
END_TEMPLATE_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
template<class BASE_TYPE>
UINT CCustomComboBoxEx<BASE_TYPE>::OnGetDlgCode()
{
return DLGC_WANTMESSAGE;
}
//////////////////////////////////////////////////////////////////////////
template<class BASE_TYPE>
BOOL CCustomComboBoxEx<BASE_TYPE>::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_RETURN)
{
NMCBEENDEDIT endEdit;
endEdit.hdr.code = CBEN_ENDEDIT;
endEdit.hdr.hwndFrom = m_hWnd;
endEdit.hdr.idFrom = GetDlgCtrlID();
endEdit.fChanged = true;
endEdit.iNewSelection = CB_ERR;
endEdit.iWhy = CBENF_RETURN;
CString text;
GetWindowText( text );
strcpy( endEdit.szText,text );
GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&endEdit) );
return TRUE;
}
if (pMsg->wParam == VK_ESCAPE)
{
SetWindowText( "" );
return TRUE;
}
}
if (pMsg->message == WM_KILLFOCUS)
{
NMCBEENDEDIT endEdit;
endEdit.hdr.code = CBEN_ENDEDIT;
endEdit.hdr.hwndFrom = m_hWnd;
endEdit.hdr.idFrom = GetDlgCtrlID();
endEdit.fChanged = true;
endEdit.iNewSelection = CB_ERR;
endEdit.iWhy = CBENF_KILLFOCUS;
CString text;
GetWindowText( text );
strcpy( endEdit.szText,text );
GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&endEdit) );
return TRUE;
}
return BASE_TYPE::PreTranslateMessage(pMsg);
}
#endif // __customcomboboxex_h__

170
Editor/Controls/DLGBARS.CPP Normal file
View File

@@ -0,0 +1,170 @@
/*****************************************************************************
DLGBARS.CPP
Purpose:
Interface for CDlgToolBar, a special type of CToolBar which does not
expect a parent frame window to be available, and CDlgStatusBar, which
does the same for CStatusBars. This allows the control bars
to be used in applications where the main window is a dialog bar.
Functions:
CDlgToolBar::CDlgToolBar() -- constructor
CDlgToolBar::~CDlgToolBar() -- destructor
CDlgToolBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
CDlgStatusBar::CDlgStatusBar() -- constructor
CDlgStatusBar::~CDlgStatusBar() -- destructor
CDlgStatusBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
Development Team:
Mary Kirtland
Ported to 32-bit by:
Mike Hedley
Written by Microsoft Product Support Services, Premier ISV Support
Copyright (c) 1996 Microsoft Corporation. All rights reserved.
\****************************************************************************/
#include "stdafx.h"
#include <afxpriv.h>
#include "dlgbars.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgToolBar
BEGIN_MESSAGE_MAP(CDlgToolBar, CToolBar)
//{{AFX_MSG_MAP(CDlgToolBar)
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgToolBar Construction/Destruction
CDlgToolBar::CDlgToolBar()
{
}
CDlgToolBar::~CDlgToolBar()
{
}
/////////////////////////////////////////////////////////////////////////////
// CDlgToolBar::OnIdleUpdateCmdUI
// OnIdleUpdateCmdUI handles the WM_IDLEUPDATECMDUI message, which is
// used to update the status of user-interface elements within the MFC
// framework.
//
// We have to get a little tricky here: CToolBar::OnUpdateCmdUI
// expects a CFrameWnd pointer as its first parameter. However, it
// doesn't do anything but pass the parameter on to another function
// which only requires a CCmdTarget pointer. We can get a CWnd pointer
// to the parent window, which is a CCmdTarget, but may not be a
// CFrameWnd. So, to make CToolBar::OnUpdateCmdUI happy, we will call
// our CWnd pointer a CFrameWnd pointer temporarily.
LRESULT CDlgToolBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
{
if (IsWindowVisible())
{
CFrameWnd *pParent = (CFrameWnd *)GetParent();
if (pParent)
OnUpdateCmdUI(pParent, (BOOL)wParam);
}
return 0L;
}
//////////////////////////////////////////////////////////////////////////
BOOL CDlgToolBar::LoadToolBar24( UINT nIDResource,int nBtnWidth )
{
CBitmap toolbarBitmap;
CImageList toolbarImageList;
BOOL bRes = LoadToolBar(nIDResource);
VERIFY(bRes);
/*
//////////////////////////////////////////////////////////////////////////
// Use 24Bit toolbars.
//////////////////////////////////////////////////////////////////////////
toolbarBitmap.LoadBitmap(IDR_MAINFRAME);
toolbarImageList.Create(16, 15, ILC_COLORDDB|ILC_MASK, 1, 1);
toolbarImageList.Add(&toolbarBitmap,TOOLBAR_TRANSPARENT_COLOR);
SendMessage(TB_SETIMAGELIST, 0, (LPARAM)toolbarImageList.m_hImageList);
*/
CImageList imageList;
CBitmap bitmap;
BITMAP bmBitmap;
if (!bitmap.Attach(LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(nIDResource),IMAGE_BITMAP, 0, 0,LR_DEFAULTSIZE|LR_CREATEDIBSECTION)))
return FALSE;
if (!bitmap.GetBitmap(&bmBitmap))
return FALSE;
CSize cSize(bmBitmap.bmWidth, bmBitmap.bmHeight);
RGBTRIPLE* rgb = (RGBTRIPLE*)(bmBitmap.bmBits);
int nCount = cSize.cx/nBtnWidth;
if (!imageList.Create(nBtnWidth, cSize.cy, ILC_COLOR24|ILC_MASK, nCount, 0))
return FALSE;
if (imageList.Add(&bitmap,TOOLBAR_TRANSPARENT_COLOR) == -1)
return FALSE;
SendMessage(TB_SETIMAGELIST, 0, (LPARAM)imageList.m_hImageList);
imageList.Detach();
bitmap.Detach();
return bRes;
}
/////////////////////////////////////////////////////////////////////////////
// CDlgStatusBar
BEGIN_MESSAGE_MAP(CDlgStatusBar, CStatusBar)
//{{AFX_MSG_MAP(CDlgStatusBar)
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgStatusBar Construction/Destruction
CDlgStatusBar::CDlgStatusBar()
{
}
CDlgStatusBar::~CDlgStatusBar()
{
}
/////////////////////////////////////////////////////////////////////////////
// CDlgStatusBar::OnIdleUpdateCmdUI
// OnIdleUpdateCmdUI handles the WM_IDLEUPDATECMDUI message, which is
// used to update the status of user-interface elements within the MFC
// framework.
//
// We have to get a little tricky here: CStatusBar::OnUpdateCmdUI
// expects a CFrameWnd pointer as its first parameter. However, it
// doesn't do anything but pass the parameter on to another function
// which only requires a CCmdTarget pointer. We can get a CWnd pointer
// to the parent window, which is a CCmdTarget, but may not be a
// CFrameWnd. So, to make CStatusBar::OnUpdateCmdUI happy, we will call
// our CWnd pointer a CFrameWnd pointer temporarily.
LRESULT CDlgStatusBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
{
if (IsWindowVisible())
{
CFrameWnd *pParent = (CFrameWnd *)GetParent();
if (pParent)
OnUpdateCmdUI(pParent, (BOOL)wParam);
}
return 0L;
}

73
Editor/Controls/DLGBARS.H Normal file
View File

@@ -0,0 +1,73 @@
/*****************************************************************************
DLGBARS.H
Purpose:
Interface for CDlgToolBar, a special type of CToolBar which does not
expect a parent frame window to be available, and CDlgStatusBar, which
does the same for CStatusBars. This allows the control bars
to be used in applications where the main window is a dialog bar.
Functions:
CDlgToolBar::CDlgToolBar() -- constructor
CDlgToolBar::~CDlgToolBar() -- destructor
CDlgToolBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
CDlgStatusBar::CDlgStatusBar() -- constructor
CDlgStatusBar::~CDlgStatusBar() -- destructor
CDlgStatusBar::OnIdleUpdateCmdUI() -- WM_IDLEUPDATECMDUI handler
Development Team:
Mary Kirtland
Ported to 32-bit by:
Mike Hedley
Written by Microsoft Product Support Services, Premier ISV Support
Copyright (c) 1996 Microsoft Corporation. All rights reserved.
\****************************************************************************/
#ifndef __DLGBARS_H__
#define __DLGBARS_H__
class CDlgToolBar : public CToolBar
{
// Construction
public:
CDlgToolBar();
// Implementation
public:
virtual ~CDlgToolBar();
BOOL LoadToolBar24( UINT nIDResource,int nBtnWidth=16 );
protected:
// Generated message map functions
//{{AFX_MSG(CDlgToolBar)
afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
class CDlgStatusBar : public CStatusBar
{
// Construction
public:
CDlgStatusBar();
// Implementation
public:
virtual ~CDlgStatusBar();
protected:
// Generated message map functions
//{{AFX_MSG(CDlgStatusBar)
afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif //__DLGBARS_H__

View File

@@ -0,0 +1,244 @@
/////////////////////////////////////////////////////////////////////////////
// DropListBox.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DropListBox.h"
#include "Resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDropListBox
CDropListBox::CDropListBox()
{
m_nLastTopIdx = 0;
}
CDropListBox::~CDropListBox()
{
}
BEGIN_MESSAGE_MAP(CDropListBox, CListBox)
//{{AFX_MSG_MAP(CDropListBox)
ON_WM_CREATE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDropListBox message handlers
int CDropListBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListBox::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//
// Because this window doesn't have an owner, there will appear
// a 'blank' button on the taskbar. The following are to hide
// that 'blank' button on the taskbar
ShowWindow( SW_HIDE );
ModifyStyleEx( 0, WS_EX_TOOLWINDOW );// |WS_VSCROLL );//| WS_EX_NOACTIVATE ); // WS_EX_CONTROLPARENT
ShowWindow( SW_SHOW );
SetWindowPos( &wndTopMost, lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, SWP_SHOWWINDOW );
SetFont( GetOwner()->GetFont() );
return 0;
}
LRESULT CDropListBox::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
SetCapture();
return FALSE;
}
LRESULT CDropListBox::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
ReleaseCapture();
return FALSE;
}
void CDropListBox::OnMouseMove(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
//
// Set selection item under mouse
int nPos = point.y / GetItemHeight(0) + GetTopIndex();
if (GetCurSel() != nPos)
{
SetCurSel( nPos );
}
//
// Check if we have autoscrolled
if( m_nLastTopIdx != GetTopIndex() )
{
int nDiff = m_nLastTopIdx - GetTopIndex();
m_nLastTopIdx = GetTopIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScroll->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = m_nLastTopIdx;
m_pScroll->SetScrollInfo( &info );
}
}
// OutputDebugString( "DropListBox MouseMove\n" );
CListBox::OnMouseMove(nFlags, point);
}
void CDropListBox::OnLButtonUp(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
int nPos = GetCurSel();
//
// Send current selection to comboedit
if( nPos != -1 )
GetOwner()->PostMessage( WM_SELECTED_ITEM, (WPARAM)nPos, 0 );
// CString str;
// str.Format( "DropListWnd: Selected item: %d\n", nPos );
// OutputDebugString( str );
//
// Destroy dropdown
ReleaseCapture();
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
void CDropListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
//
// Send input to parent
/* CRect rc;
GetClientRect( &rc );
CPoint pt = point;
ClientToScreen( &pt );
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = pt.x;
input.mi.dy = pt.y;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.time = 0;
SendInput( 1, &input, sizeof(INPUT) );
*/
//
// Return so that the listbox can be destroyed
// CListBox::OnLButtonDown(nFlags, point);
}
int CDropListBox::GetBottomIndex()
{
int nTop = GetTopIndex();
CRect rc;
GetClientRect( &rc );
int nVisCount = rc.Height() / GetItemHeight(0);
return nTop + nVisCount;
}
void CDropListBox::SetTopIdx(int nPos, BOOL bUpdateScrollbar)
{
m_nLastTopIdx = nPos;
SetTopIndex( nPos );
if( bUpdateScrollbar )
{
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScroll->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = m_nLastTopIdx;
m_pScroll->SetScrollInfo( &info );
}
}
}
void CDropListBox::GetTextSize(LPCTSTR lpszText, int nCount, CSize &size)
{
CClientDC dc(this);
int nSave = dc.SaveDC();
dc.SelectObject( GetOwner()->GetFont() );
size = dc.GetTextExtent( lpszText, nCount );
dc.RestoreDC(nSave);
}
int CDropListBox::SetCurSel(int nSelect)
{
int nr = CListBox::SetCurSel( nSelect );
if( nr != -1 )
{
//
// Set scrollbar
int nTopIdx = GetTopIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScroll->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = nTopIdx;
m_pScroll->SetScrollInfo( &info );
}
}
return nr;
}

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////
// DropListBox.h : header file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DROPLISTBOX_H__E49DED7C_CBC2_4458_A72C_F4C428927132__INCLUDED_)
#define AFX_DROPLISTBOX_H__E49DED7C_CBC2_4458_A72C_F4C428927132__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DropListBox.h : header file
//
#include "DropScrollBar.h"
#define WM_SELECTED_ITEM (WM_USER+1)
#define WM_DESTROY_DROPLIST (WM_USER+2)
#define WM_VRC_SETCAPTURE (WM_USER+3)
#define WM_VRC_RELEASECAPTURE (WM_USER+4)
class CDropScrollBar;
/////////////////////////////////////////////////////////////////////////////
// CDropListBox window
class CDropListBox : public CListBox
{
// Construction
public:
CDropListBox();
// Attributes
public:
// Operations
public:
void SetScrollBar( CDropScrollBar* pScroll ) { m_pScroll = pScroll; }
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDropListBox)
public:
//}}AFX_VIRTUAL
// Implementation
public:
int SetCurSel( int nSelect );
void GetTextSize( LPCTSTR lpszText, int nCount, CSize& size );
void SetTopIdx( int nPos, BOOL bUpdateScrollbar = FALSE );
int GetBottomIndex();
virtual ~CDropListBox();
// Generated message map functions
protected:
//{{AFX_MSG(CDropListBox)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg LRESULT OnSetCapture( WPARAM wParam, LPARAM lParam );
afx_msg LRESULT OnReleaseCapture( WPARAM wParam, LPARAM lParam );
DECLARE_MESSAGE_MAP()
private:
CWnd* m_pComboParent;
CDropScrollBar* m_pScroll;
int m_nLastTopIdx;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DROPLISTBOX_H__E49DED7C_CBC2_4458_A72C_F4C428927132__INCLUDED_)

View File

@@ -0,0 +1,199 @@
/////////////////////////////////////////////////////////////////////////////
// DropScrollBar.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DropScrollBar.h"
#include "DropListBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDropScrollBar
CDropScrollBar::CDropScrollBar()
:
m_pListBox( 0 )
{
}
CDropScrollBar::~CDropScrollBar()
{
}
BEGIN_MESSAGE_MAP(CDropScrollBar, CScrollBar)
//{{AFX_MSG_MAP(CDropScrollBar)
ON_WM_MOUSEMOVE()
ON_WM_VSCROLL_REFLECT()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDropScrollBar message handlers
void CDropScrollBar::OnMouseMove(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
// OutputDebugString( "DropScrollBar MouseMove\n" );
CScrollBar::OnMouseMove(nFlags, point);
}
LRESULT CDropScrollBar::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
SetCapture();
return FALSE;
}
LRESULT CDropScrollBar::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
ReleaseCapture();
return FALSE;
}
void CDropScrollBar::VScroll(UINT nSBCode, UINT nPos)
{
// TODO: Add your message handler code here
if( !m_pListBox )
return;
int nTop = m_pListBox->GetTopIndex();
int nBottom = m_pListBox->GetBottomIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( !GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
return;
switch( nSBCode )
{
case SB_BOTTOM: // Scroll to bottom.
break;
case SB_ENDSCROLL: // End scroll.
break;
case SB_LINEDOWN: // Scroll one line down.
info.nPos++;
if( info.nPos > info.nMax )
info.nPos = info.nMax;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_LINEUP: // Scroll one line up.
info.nPos--;
if( info.nPos < info.nMin )
info.nPos = info.nMin;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_PAGEDOWN: // Scroll one page down.
info.nPos += info.nPage;
if( info.nPos > info.nMax )
info.nPos = info.nMax;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_PAGEUP: // Scroll one page up.
info.nPos -= info.nPage;
if( info.nPos < info.nMin )
info.nPos = info.nMin;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_THUMBPOSITION: // Scroll to the absolute position. The current position is provided in nPos.
info.nPos = nPos;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. The current position is provided in nPos.
info.nPos = nPos;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_TOP: // Scroll to top.
break;
}
SetScrollInfo( &info );
}
void CDropScrollBar::SetListBox( CDropListBox* pListBox )
{
ASSERT( pListBox != NULL );
m_pListBox = pListBox;
int nTop = m_pListBox->GetTopIndex();
int nBottom = m_pListBox->GetBottomIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
info.nMax = m_pListBox->GetCount()-1;
info.nMin = 0;
info.nPage = nBottom - nTop;
info.nPos = 0;
info.nTrackPos = 0;
SetScrollInfo( &info );
}
void CDropScrollBar::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rc;
GetClientRect( &rc );
if( !rc.PtInRect( point ) )
{
ReleaseCapture();
GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
CScrollBar::OnLButtonDown(nFlags, point);
}

View File

@@ -0,0 +1,77 @@
/////////////////////////////////////////////////////////////////////////////
// DropScrollBar.h : header file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DROPSCROLLBAR_H__8814CD20_3D94_4B9C_8A64_DF4E9F6DD4DC__INCLUDED_)
#define AFX_DROPSCROLLBAR_H__8814CD20_3D94_4B9C_8A64_DF4E9F6DD4DC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CDropListBox;
/////////////////////////////////////////////////////////////////////////////
// CDropScrollBar window
class CDropScrollBar : public CScrollBar
{
// Construction
public:
CDropScrollBar();
// Attributes
public:
// Operations
public:
void SetListBox( CDropListBox* pListBox );
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDropScrollBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDropScrollBar();
// Generated message map functions
protected:
//{{AFX_MSG(CDropScrollBar)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void VScroll(UINT nSBCode, UINT nPos);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg LRESULT OnSetCapture( WPARAM wParam, LPARAM lParam );
afx_msg LRESULT OnReleaseCapture( WPARAM wParam, LPARAM lParam );
DECLARE_MESSAGE_MAP()
private:
CDropListBox* m_pListBox;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DROPSCROLLBAR_H__8814CD20_3D94_4B9C_8A64_DF4E9F6DD4DC__INCLUDED_)

471
Editor/Controls/DropWnd.cpp Normal file
View File

@@ -0,0 +1,471 @@
/////////////////////////////////////////////////////////////////////////////
// DropWnd.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DropWnd.h"
#include "DropListBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDropWnd
CDropWnd::CDropWnd()
{
m_bResizing = false;
}
CDropWnd::~CDropWnd()
{
}
BEGIN_MESSAGE_MAP(CDropWnd, CWnd)
//{{AFX_MSG_MAP(CDropWnd)
ON_WM_CREATE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_LBUTTONUP()
ON_WM_SHOWWINDOW()
ON_WM_ACTIVATEAPP()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_VRC_SETCAPTURE, OnSetCapture )
ON_MESSAGE( WM_VRC_RELEASECAPTURE, OnReleaseCapture )
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDropWnd message handlers
BOOL CDropWnd::PreCreateWindow(CREATESTRUCT& cs)
{
//
// Calc the size of the wnd
return CWnd::PreCreateWindow(cs);
}
//////////////////////////////////////////////////////////////////////////
int CDropWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CRect rcWnd;
GetClientRect( &rcWnd );
//
// Because this window doesn't have an owner, there will appear
// a 'blank' button on the taskbar. The following are to hide
// that 'blank' button on the taskbar
ModifyStyleEx( 0, WS_EX_TOOLWINDOW|WS_EX_TOPMOST );
MoveWindow( lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, FALSE );
//SetWindowPos( &wndTopMost, lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->cx, lpCreateStruct->cy, SWP_SHOWWINDOW );
//
// Create scrollbar
m_rcScroll = rcWnd;
m_rcScroll.left = m_rcScroll.right - ::GetSystemMetrics(SM_CXVSCROLL);
m_rcScroll.bottom -= ::GetSystemMetrics(SM_CYVSCROLL);
m_scrollbar.Create( SBS_VERT | SBS_RIGHTALIGN | WS_CHILD, m_rcScroll, this, 100);
//
// Create listbox
m_rcList.SetRect( lpCreateStruct->x, lpCreateStruct->y, lpCreateStruct->x+lpCreateStruct->cx-::GetSystemMetrics(SM_CXVSCROLL), lpCreateStruct->y+lpCreateStruct->cy );
ScreenToClient( m_rcList );
VERIFY(m_listbox.Create( WS_VISIBLE|WS_CHILD|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS, m_rcList, this, 101 ) );
m_listbox.SetScrollBar( &m_scrollbar );
//
// Resize this wnd so INTEGRAL_HEIGHT applies!?
CRect rc;
int nH = m_listbox.GetItemHeight(0);
nH = nH*m_listbox.GetCount()+2;
// Get screen size
int nScrX = GetSystemMetrics( SM_CXSCREEN );
int nScrY = GetSystemMetrics( SM_CYSCREEN );
//int nDefaultItems = static_cast<CAdvComboBox*>(GetParent())->GetDefaultVisibleItems();
int nDefaultItems = 10;
int minVisibleItems = 2;
//
// Check to see if the window should be placed over the combobox
int nY = lpCreateStruct->y;
int nItems = m_listbox.GetCount();
int nItemHeight = m_listbox.GetItemHeight(0);
int nVisHeight = nScrY - lpCreateStruct->y;
if ((nVisHeight / nItemHeight) < minVisibleItems)
{
CRect rcCombo(0,0,100,10);
int nComboTopY = lpCreateStruct->y - rcCombo.Height();
if( nDefaultItems == -1 || nDefaultItems > nItems )
{
nY = (nComboTopY - nH) < 0 ? 0 : (nComboTopY - nH);
nH = (nY + nH) > nComboTopY ? nComboTopY - nY : nH;
}
else
{
nY = nComboTopY - nItemHeight*nDefaultItems;
nY -= 2;
nY = nY < 0 ? 0 : nY;
nH = nComboTopY - nY;
}
}
else
{
//
// Place the window below the combo
// Check height
if( nDefaultItems == -1 || nDefaultItems > nItems )
{
if( lpCreateStruct->y + nH > nScrY )
{
nH = nScrY - lpCreateStruct->y;
}
else
if( nH < ::GetSystemMetrics(SM_CYVSCROLL) )
{
nH = ::GetSystemMetrics(SM_CYVSCROLL);
}
}
else
{
nH = nDefaultItems * nItemHeight;
nH = (nY+nH) > nScrY ? nScrY-nY : nH;
nH += 2;
}
}
// Calc width
int nW = 0;
CSize size(0,0);
for( int i = 0; i < m_listbox.GetCount(); i++)
{
CString strText;
m_listbox.GetText(i,strText);
m_listbox.GetTextSize( strText,strText.GetLength(), size );
nW = (size.cx > nW) ? size.cx : nW;
}
nW += m_rcScroll.Width() +8;
// Check min width
if( nW < m_rcList.Width() )
{
nW = lpCreateStruct->cx;
}
// Check max width
int nX = lpCreateStruct->x;
if( nW > nScrX - lpCreateStruct->x )
{
nX = nScrX - nW;
if( nX < 0 )
nX = 0;
}
if( nX == 0 && nW > nScrX )
nW = nScrX;
MoveWindow( nX, nY, nW, nH,FALSE );
GetClientRect( &rcWnd );
//
// Create sizehandle
m_rcSizeHandle = rcWnd;
GetClientRect( &m_rcSizeHandle );
m_rcSizeHandle.left = m_rcSizeHandle.right - ::GetSystemMetrics(SM_CXVSCROLL);
m_rcSizeHandle.top = m_rcSizeHandle.bottom - ::GetSystemMetrics(SM_CYVSCROLL);
//
// Set values in scrollbar
m_scrollbar.SetListBox( &m_listbox );
m_scrollbar.ShowScrollBar();
// SendMessage( WM_SHOWWINDOW, (WPARAM)1, 0 );
return 0;
}
LRESULT CDropWnd::OnSetCapture( WPARAM wParam, LPARAM lParam )
{
SetCapture();
return FALSE;
}
LRESULT CDropWnd::OnReleaseCapture( WPARAM wParam, LPARAM lParam )
{
ReleaseCapture();
return FALSE;
}
void CDropWnd::OnMouseMove(UINT nFlags, CPoint point)
{
//
//
if( m_bResizing )
{
CRect rcWnd;
GetWindowRect( &rcWnd );
if( point.x + m_nMouseDiffX >= ::GetSystemMetrics(SM_CXVSCROLL) )
{
rcWnd.right = rcWnd.left + point.x + m_nMouseDiffX +2;
}
else
{
rcWnd.right = rcWnd.left + ::GetSystemMetrics(SM_CXVSCROLL) +1;
}
if( point.y + m_nMouseDiffY >= ::GetSystemMetrics(SM_CYVSCROLL) )
{
rcWnd.bottom = rcWnd.top + point.y + m_nMouseDiffY +2;
}
else
{
rcWnd.bottom = rcWnd.top + ::GetSystemMetrics(SM_CXVSCROLL) +1;
}
MoveWindow( &rcWnd );
return;
}
//
// Check point
if( m_rcList.PtInRect( point ) )
{
HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
SetCursor( hCursor );
ReleaseCapture();
m_scrollbar.SendMessage( WM_VRC_RELEASECAPTURE );
m_listbox.SetFocus();
m_listbox.SendMessage( WM_VRC_SETCAPTURE );
}
else
if( m_rcScroll.PtInRect( point ) )
{
HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
SetCursor( hCursor );
m_scrollbar.SetFocus();
ReleaseCapture();
m_listbox.SendMessage( WM_VRC_RELEASECAPTURE );
m_scrollbar.SendMessage( WM_VRC_SETCAPTURE );
}
else
{
if( m_rcSizeHandle.PtInRect( point ) )
{
HCURSOR hCursor = LoadCursor( NULL, IDC_SIZENWSE );
SetCursor( hCursor );
}
else
{
HCURSOR hCursor = LoadCursor( NULL, IDC_ARROW );
SetCursor( hCursor );
}
SetCapture();
CWnd::OnMouseMove(nFlags, point);
}
}
void CDropWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
if( m_rcSizeHandle.PtInRect( point ) )
{
m_bResizing = true;
m_ptLastResize = point;
CRect rcClient;
GetClientRect( &rcClient );
m_nMouseDiffX = rcClient.Width() - point.x;
m_nMouseDiffY = rcClient.Height() - point.y;
return;
}
//
// Clean up the code below...
//
CRect rc;
CRect rcVScroll(0,0,0,0);
GetClientRect( &rc );
DWORD dwStyle = GetStyle();
// Take away vertical scroll
if( rc.PtInRect( point ) )
{
}
else
{
//
// Calc the point in the parent(PropertyListBox)
CWnd* pParent = GetOwner()->GetParent();
CRect rcParentClient;
CRect rcParentWnd;
pParent->GetClientRect( &rcParentClient );
pParent->GetWindowRect( &rcParentWnd );
CPoint pt = point;
ClientToScreen( &pt );
pt.x -= rcParentWnd.left;
pt.y -= rcParentWnd.top;
CRect rc;
GetOwner()->GetWindowRect( &rc );
if( !rc.PtInRect( pt ) )
{
ReleaseCapture();
// CString str;
// str.Format( "MousePos (NOT PtInRect): X:%d, y:%d\n", pt.x, pt.y );
// OutputDebugString( str );
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
else
{
// CString str;
// str.Format( "MousePos in combo\n " );
// OutputDebugString( str );
ReleaseCapture();
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
//
// Send input to parent
/* INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = pt.x;
input.mi.dy = pt.y;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.time = 0;
SendInput( 1, &input, sizeof(INPUT) );
*/
}
CWnd::OnLButtonDown(nFlags, point);
}
void CDropWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
if( m_bResizing )
{
m_bResizing = false;
}
CWnd::OnLButtonUp(nFlags, point);
}
void CDropWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
m_rcList.SetRect( 0, 0, cx-::GetSystemMetrics(SM_CXVSCROLL), cy );
m_listbox.MoveWindow( &m_rcList,FALSE );
m_rcScroll.SetRect( cx-::GetSystemMetrics(SM_CXVSCROLL), 0, cx, cy-::GetSystemMetrics(SM_CYVSCROLL) );
m_scrollbar.MoveWindow( &m_rcScroll,FALSE );
m_rcSizeHandle.SetRect( cx-::GetSystemMetrics(SM_CXVSCROLL), cy-::GetSystemMetrics(SM_CYVSCROLL), cx, cy );
InvalidateRect( &m_rcSizeHandle );
//
// Fix the scrollbar
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_scrollbar.GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPage = m_listbox.GetBottomIndex() - m_listbox.GetTopIndex();
m_scrollbar.SetScrollInfo( &info );
}
}
void CDropWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.DrawFrameControl(m_rcSizeHandle, DFC_SCROLL, DFCS_SCROLLSIZEGRIP );
// Do not call CWnd::OnPaint() for painting messages
}
BOOL CDropWnd::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
ReleaseCapture();
m_listbox.DestroyWindow();
return CWnd::DestroyWindow();
}
void CDropWnd::OnShowWindow(BOOL bShow, UINT nStatus)
{
CWnd::OnShowWindow(bShow, nStatus);
// TODO: Add your message handler code here
if( bShow )
{
// AnimateWindow( GetSafeHwnd(), 80, AW_VER_POSITIVE | AW_ACTIVATE | AW_SLIDE);
}
else
{
// AnimateWindow( GetSafeHwnd(), 80, AW_VER_NEGATIVE | AW_HIDE | AW_SLIDE);
}
}
#if _MFC_VER >= 0x0700 //MFC 7.0
void CDropWnd::OnActivateApp(BOOL bActive, DWORD dwThreadID )
{
CWnd::OnActivateApp(bActive, dwThreadID);
#else // MFC7.0
void CDropWnd::OnActivateApp(BOOL bActive, HTASK hTask ) // MFC6 -
{
CWnd::OnActivateApp(bActive, hTask);
#endif // MFC7.0
// TODO: Add your message handler code here
if( bActive )
{
}
else
{
GetOwner()->PostMessage( WM_DESTROY_DROPLIST );
}
}
BOOL CDropWnd::OnEraseBkgnd(CDC* pDC)
{
// Not erase background.
return TRUE;
}

104
Editor/Controls/DropWnd.h Normal file
View File

@@ -0,0 +1,104 @@
/////////////////////////////////////////////////////////////////////////////
// DropWnd.h : header file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_DROPWND_H__F873AF0A_BD7D_4B20_BDF6_1EBB973AA348__INCLUDED_)
#define AFX_DROPWND_H__F873AF0A_BD7D_4B20_BDF6_1EBB973AA348__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DropWnd.h : header file
//
#include "DropListBox.h"
#include "DropScrollBar.h"
/////////////////////////////////////////////////////////////////////////////
// CDropWnd window
class CDropWnd : public CWnd
{
// Construction
public:
CDropWnd();
// Attributes
public:
const CDropListBox& GetListBox() const { return m_listbox; }
CDropListBox& GetListBox() { return m_listbox; }
const CDropScrollBar& GetScrollBar() const { return m_scrollbar; }
CDropScrollBar& GetScrollBar() { return m_scrollbar; }
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDropWnd)
public:
virtual BOOL DestroyWindow();
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDropWnd();
// Generated message map functions
protected:
//{{AFX_MSG(CDropWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnPaint();
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
#if _MFC_VER >= 0x0700 //MFC 7.0
afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
#else
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask );
#endif
//}}AFX_MSG
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg LRESULT OnSetCapture( WPARAM wParam, LPARAM lParam );
afx_msg LRESULT OnReleaseCapture( WPARAM wParam, LPARAM lParam );
DECLARE_MESSAGE_MAP()
private:
CDropListBox m_listbox;
CDropScrollBar m_scrollbar;
CRect m_rcList;
CRect m_rcScroll;
CRect m_rcSizeHandle;
bool m_bResizing;
CPoint m_ptLastResize;
int m_nMouseDiffX;
int m_nMouseDiffY;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DROPWND_H__F873AF0A_BD7D_4B20_BDF6_1EBB973AA348__INCLUDED_)

View File

@@ -0,0 +1,528 @@
// EditModeToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "EditModeToolBar.h"
#include "Objects\ObjectManager.h"
#include "UndoDropDown.h"
#include "ViewManager.h"
#include "GridSettingsDialog.h"
#include "Settings.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEditModeToolBar
CEditModeToolBar::CEditModeToolBar()
{
//{{AFX_DATA_INIT(CEditModeToolBar)
m_szSelection = "";
//}}AFX_DATA_INIT
m_coordSys = (RefCoordSys)-1;
m_objectSelectionMask = 0;
}
CEditModeToolBar::~CEditModeToolBar()
{
}
BEGIN_MESSAGE_MAP(CEditModeToolBar, CXTToolBar)
//{{AFX_MSG_MAP(CEditModeToolBar)
ON_WM_CREATE()
ON_CBN_SELENDOK( IDC_SELECTION,OnSelectionChanged )
ON_CBN_SELCHANGE( IDC_SELECTION,OnSelectionChanged )
ON_NOTIFY( CBEN_ENDEDIT, IDC_SELECTION, OnNotifyOnSelectionChanged)
ON_NOTIFY_REFLECT( TBN_DROPDOWN, OnToolbarDropDown )
ON_UPDATE_COMMAND_UI(ID_REF_COORDS_SYS, OnUpdateCoordsRefSys)
ON_CBN_SELENDOK( ID_REF_COORDS_SYS,OnCoordsRefSys )
ON_UPDATE_COMMAND_UI(IDC_SELECTION_MASK, OnUpdateSelectionMask)
ON_CBN_SELENDOK( IDC_SELECTION_MASK,OnSelectionMask )
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CEditModeToolBar::DoDataExchange(CDataExchange* pDX)
{
CXTToolBar::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEditModeToolBar)
DDX_CBString(pDX, IDC_SELECTION, m_szSelection);
//}}AFX_DATA_MAP
}
/////////////////////////////////////////////////////////////////////////////
// CEditModeToolBar message handlers
BOOL CEditModeToolBar::Create( CWnd *pParentWnd,DWORD dwStyle,UINT nID )
{
if (!CXTToolBar::CreateEx( pParentWnd,TBSTYLE_FLAT|TBSTYLE_TRANSPARENT|TBSTYLE_LIST,dwStyle,CRect(0,0,0,0),nID ))
return FALSE;
LoadToolBar( IDR_EDIT_MODE );
/*
// Set up hot bar image lists.
CImageList toolbarImageList;
CBitmap toolbarBitmap;
toolbarBitmap.LoadBitmap(IDR_EDIT_MODE);
toolbarImageList.Create(16, 15, ILC_COLORDDB|ILC_MASK, 13, 1);
toolbarImageList.Add(&toolbarBitmap,TOOLBAR_TRANSPARENT_COLOR);
GetToolBarCtrl().SetImageList( &toolbarImageList );
toolbarImageList.Detach();
toolbarBitmap.Detach();
*/
GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS|TBSTYLE_EX_MIXEDBUTTONS);
//GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
// Replace buttons to check boxes.
for (int i = 0; i < GetCount(); i++)
{
int style = GetButtonStyle(i);
if (style & TBBS_SEPARATOR)
continue;
int id = GetItemID(i);
if (/*(id == ID_EDITMOD_LINK)||(id == ID_EDITMODE_UNLINK)||*/(id == ID_EDITMODE_SELECT)||(id == ID_EDITMODE_MOVE)||(id == ID_EDITMODE_ROTATE)||(id == ID_EDITMODE_SCALE))
{
if (style == TBBS_BUTTON)
{
style = TBBS_CHECKGROUP;
SetButtonStyle(i,style);
}
}
}
int iIndex;
// Layer select button.
SetButtonStyle( CommandToIndex(ID_LAYER_SELECT),BTNS_BUTTON|BTNS_SHOWTEXT );
//SetButtonText( CommandToIndex(ID_LAYER_SELECT)," " );
// Snap.
iIndex = CommandToIndex(ID_SNAP_TO_GRID);
SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN|BTNS_SHOWTEXT );
SetButtonText( iIndex," " );
// Terrain Axis.
//iIndex = CommandToIndex(ID_SELECT_AXIS_TERRAIN);
//SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN );
// Place drop down buttons for Undo and Redo.
iIndex = CommandToIndex(ID_UNDO);
SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN );
iIndex = CommandToIndex(ID_REDO);
SetButtonStyle( iIndex,GetButtonStyle(iIndex)|TBSTYLE_DROPDOWN );
// Create controls in the animation bar
CRect rect;
// Get the index of the keyframe slider position in the toolbar
iIndex = CommandToIndex(IDC_SELECTION);
/*
if (iIndex >= 0)
{
// Convert that button to a seperator and get its position
SetButtonInfo(iIndex, IDC_SELECTION, TBBS_SEPARATOR, 100);
GetItemRect(iIndex, &rect);
}
*/
CalcLayout(LM_HORZ);
rect.SetRect( 2,0,100,150 );
m_selections.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWN|CBS_SORT,rect,this,IDC_SELECTION);
InsertControl( &m_selections );
//SetButtonCtrl( iIndex,&m_selections,FALSE );
m_selections.SetItemHeight( -1, 16 );
//m_selections.SetFont( &g_PaintManager->m_FontNormal );
rect.SetRect( 2,0,60,150 );
m_refCoords.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,rect,this,ID_REF_COORDS_SYS);
m_refCoords.AddString("View");
m_refCoords.AddString("Local");
m_refCoords.AddString("World");
InsertControl( &m_refCoords );
//SetButtonCtrl( iIndex,&m_selections,FALSE );
//m_refCoords.SetItemHeight( -1, 16 );
//////////////////////////////////////////////////////////////////////////
// Initialize selection mask.
//////////////////////////////////////////////////////////////////////////
int id;
rect.SetRect( 2,0,80,300 );
m_selectionMask.Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,rect,this,IDC_SELECTION_MASK);
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Select All");
m_selectionMask.SetItemData( id,OBJTYPE_ANY );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("No Brushes");
m_selectionMask.SetItemData( id,(~OBJTYPE_BRUSH) );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Brushes");
m_selectionMask.SetItemData( id,OBJTYPE_BRUSH );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Entities");
m_selectionMask.SetItemData( id,OBJTYPE_ENTITY );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Prefabs");
m_selectionMask.SetItemData( id,OBJTYPE_PREFAB );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("Areas");
m_selectionMask.SetItemData( id,OBJTYPE_VOLUME );
//////////////////////////////////////////////////////////////////////////
id = m_selectionMask.AddString("AI Points");
m_selectionMask.SetItemData( id,OBJTYPE_AIPOINT );
InsertControl( &m_selectionMask );
//////////////////////////////////////////////////////////////////////////
/*
{
CMenu menu;
menu.CreatePopupMenu();
int size = 1;
for (int i = 0; i < 7; i++)
{
CString str;
str.Format( "%d",size );
menu.AppendMenu( MF_STRING,1+i,str );
size *= 2;
}
menu.AppendMenu( MF_SEPARATOR );
menu.AppendMenu( MF_STRING,100,"Setup grid" );
SetButtonMenu( CommandToIndex(ID_SNAP_TO_GRID),menu.Detach(),FALSE );
}
*/
CalcLayout(LM_HORZ);
GetToolBarCtrl().AutoSize();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::SetGridSize( float size )
{
// Snap.
int iIndex = CommandToIndex(ID_SNAP_TO_GRID);
CString str;
str.Format( "%g",size );
SetButtonText( iIndex,str );
AutoSize();
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::SetCurrentLayer( const CString &layerName )
{
int iIndex = CommandToIndex(ID_LAYER_SELECT);
if (iIndex >= 0)
{
SetButtonText( iIndex,CString(" ")+layerName );
//m_layerName.SetWindowText( layerName );
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnSelectionChanged()
{
CString selection = GetSelection();
if (!selection.IsEmpty())
GetIEditor()->GetObjectManager()->SetSelection( selection );
}
void CEditModeToolBar::OnNotifyOnSelectionChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NMCBEENDEDIT *endEdit = (NMCBEENDEDIT*)pNMHDR;
if (endEdit->iWhy == CBENF_RETURN || endEdit->iWhy == CBENF_KILLFOCUS)
{
// Add new selection.
CString selection = endEdit->szText;
if (!selection.IsEmpty())
{
AddSelection( selection );
GetIEditor()->GetObjectManager()->NameSelection( selection );
}
}
}
CString CEditModeToolBar::GetSelection()
{
UpdateData( TRUE );
if (m_selections.m_hWnd)
{
int sel = m_selections.GetCurSel();
if (sel != CB_ERR)
{
m_selections.GetLBText( sel,m_szSelection );
}
}
return m_szSelection;
}
void CEditModeToolBar::AddSelection( const CString &name )
{
if (m_selections.FindStringExact( 0,name ) == CB_ERR)
{
//char str[1024];
//strcpy( str,name );
//m_selections.AddString( name );
//COMBOBOXEXITEM item;
//memset(&item,0,sizeof(item));
//item.mask = CBEIF_TEXT;
//item.pszText = str;
//item.cchTextMax = name.GetLength();
m_selections.AddString( name );
}
}
void CEditModeToolBar::RemoveSelection( const CString &name )
{
int i = m_selections.FindStringExact( 0,name );
if (i != CB_ERR)
m_selections.DeleteString( i );
}
void CEditModeToolBar::SetSelection( const CString &name )
{
m_szSelection = name;
UpdateData( FALSE );
}
void CEditModeToolBar::OnRButtonUp(UINT nFlags, CPoint point)
{
/*
CRect rc;
for (int i = 0; i < GetCount(); i++)
{
GetItemRect(i,rc);
if (rc.PtInRect(point))
{
int id = GetButtonID(i);
if ((id == ID_EDITMODE_MOVE)||(id == ID_EDITMODE_ROTATE)||(id == ID_EDITMODE_SCALE))
{
if (GetToolBarCtrl().IsButtonChecked(id))
{
CLogFile::WriteLine( "Clicked" );
}
}
}
}
*/
CXTToolBar::OnRButtonUp(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnToolbarDropDown(NMHDR* pnhdr, LRESULT *plr)
{
CRect rc;
CPoint pos;
GetCursorPos( &pos );
NMTOOLBAR* pnmtb = (NMTOOLBAR*)pnhdr;
//GetItemRect( pnmtb->iItem,rc );
rc = pnmtb->rcButton;
ClientToScreen( rc );
pos.x = rc.left;
pos.y = rc.bottom;
// Switch on button command id's.
switch (pnmtb->iItem)
{
case ID_UNDO:
{
CUndoDropDown undoDialog( pos,true,AfxGetMainWnd() );
undoDialog.DoModal();
}
break;
case ID_REDO:
{
CUndoDropDown undoDialog( pos,false,AfxGetMainWnd() );
undoDialog.DoModal();
}
break;
case ID_SELECT_AXIS_TERRAIN:
//OnAxisTerrainMenu(pos);
break;
case ID_SNAP_TO_GRID:
{
// Display drop down menu with snap values.
OnSnapMenu(pos);
}
break;
default:
return;
}
*plr = TBDDRET_DEFAULT;
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnAxisTerrainMenu( CPoint pos )
{
/*
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu( MF_STRING,1,"Terrain And Objects" );
menu.AppendMenu( MF_STRING,2,"Only Terrain" );
int cmd = menu.TrackPopupMenu( TPM_RETURNCMD|TPM_LEFTALIGN|TPM_LEFTBUTTON,pos.x,pos.y,this );
if (cmd == 1)
{
GetIEditor()->SetTerrainAxisIgnoreObjects(false);
}
if (cmd == 1)
{
GetIEditor()->SetTerrainAxisIgnoreObjects(true);
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnSnapMenu( CPoint pos )
{
CMenu menu;
menu.CreatePopupMenu();
float startSize = 0.125;
int steps = 10;
double size = startSize;
for (int i = 0; i < steps; i++)
{
CString str;
str.Format( "%g",size );
menu.AppendMenu( MF_STRING,1+i,str );
size *= 2;
}
menu.AppendMenu( MF_SEPARATOR );
menu.AppendMenu( MF_STRING,100,"Setup grid" );
int cmd = menu.TrackPopupMenu( TPM_RETURNCMD|TPM_LEFTALIGN|TPM_LEFTBUTTON,pos.x,pos.y,this );
if (cmd >= 1 && cmd < 100)
{
size = startSize;
for (int i = 0; i < cmd-1; i++)
{
size *= 2;
}
// Set grid to size.
GetIEditor()->GetViewManager()->GetGrid()->size = size;
}
if (cmd == 100)
{
// Setup grid dialog.
CGridSettingsDialog dlg;
dlg.DoModal();
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnUpdateCoordsRefSys(CCmdUI *pCmdUI)
{
if (m_coordSys != GetIEditor()->GetReferenceCoordSys() && m_refCoords.m_hWnd)
{
int sel = LB_ERR;
m_coordSys = GetIEditor()->GetReferenceCoordSys();
switch (m_coordSys)
{
case COORDS_VIEW:
sel = 0;
break;
case COORDS_LOCAL:
sel = 1;
break;
case COORDS_WORLD:
sel = 2;
break;
};
if (sel != LB_ERR)
{
m_refCoords.SetCurSel(sel);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnCoordsRefSys()
{
int sel = m_refCoords.GetCurSel();
if (sel != LB_ERR)
{
switch (sel)
{
case 0:
GetIEditor()->SetReferenceCoordSys( COORDS_VIEW );
break;
case 1:
GetIEditor()->SetReferenceCoordSys( COORDS_LOCAL );
break;
case 2:
GetIEditor()->SetReferenceCoordSys( COORDS_WORLD );
break;
};
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnUpdateSelectionMask(CCmdUI *pCmdUI)
{
if (m_objectSelectionMask != gSettings.objectSelectMask && m_selectionMask.m_hWnd)
{
m_objectSelectionMask = gSettings.objectSelectMask;
int sel = LB_ERR;
for (int i = 0; i < m_selectionMask.GetCount(); i++)
{
if (m_selectionMask.GetItemData(i) == gSettings.objectSelectMask)
{
sel = i;
break;
}
}
if (sel != LB_ERR && sel != m_selectionMask.GetCurSel())
{
m_selectionMask.SetCurSel(sel);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::OnSelectionMask()
{
int sel = m_selectionMask.GetCurSel();
if (sel != LB_ERR)
{
gSettings.objectSelectMask = m_selectionMask.GetItemData(sel);
m_objectSelectionMask = gSettings.objectSelectMask;
}
}
//////////////////////////////////////////////////////////////////////////
void CEditModeToolBar::NextSelectMask()
{
int sel = m_selectionMask.GetCurSel();
if (sel == LB_ERR || sel == m_selectionMask.GetCount()-1)
{
sel = 0;
}
else
sel++;
m_selectionMask.SetCurSel(sel);
OnSelectionMask();
}

View File

@@ -0,0 +1,86 @@
#if !defined(AFX_EDITMODETOOLBAR_H__1A7415BB_DA82_4A27_BA14_F06B74A05080__INCLUDED_)
#define AFX_EDITMODETOOLBAR_H__1A7415BB_DA82_4A27_BA14_F06B74A05080__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditModeToolBar.h : header file
//
#include "SelectionCombo.h"
/////////////////////////////////////////////////////////////////////////////
// CEditModeToolBar window
class CEditModeToolBar : public CXTToolBar
{
// Construction
public:
CEditModeToolBar();
BOOL Create( CWnd *pParentWnd,DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP,UINT nID = AFX_IDW_TOOLBAR );
// Attributes
public:
// Operations
public:
CString GetSelection();
void SetSelection( const CString &name );
void AddSelection( const CString &name );
void RemoveSelection( const CString &name );
void SetCurrentLayer( const CString &layerName );
void SetGridSize( float size );
void NextSelectMask();
// Data
//{{AFX_DATA(CEditModeToolBar)
CString m_szSelection;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditModeToolBar)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CEditModeToolBar();
void OnSnapMenu( CPoint pos );
void OnAxisTerrainMenu( CPoint pos );
// Generated message map functions
protected:
//{{AFX_MSG(CEditModeToolBar)
afx_msg void OnSelectionChanged();
afx_msg void OnNotifyOnSelectionChanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnToolbarDropDown(NMHDR* pnhdr, LRESULT *plr);
afx_msg void OnUpdateCoordsRefSys(CCmdUI *pCmdUI);
afx_msg void OnCoordsRefSys();
afx_msg void OnUpdateSelectionMask(CCmdUI *pCmdUI);
afx_msg void OnSelectionMask();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CSelectionCombo m_selections;
CXTFlatComboBox m_refCoords;
CXTFlatComboBox m_selectionMask;
//CExtComboBox m_selections;
CMenu m_gridMenu;
RefCoordSys m_coordSys;
int m_objectSelectionMask;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EDITMODETOOLBAR_H__1A7415BB_DA82_4A27_BA14_F06B74A05080__INCLUDED_)

View File

@@ -0,0 +1,163 @@
// FileTree.cpp : implementation file
//
#include "stdafx.h"
#include "FileTree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include <io.h>
/////////////////////////////////////////////////////////////////////////////
// CFileTree
CFileTree::CFileTree()
{
CLogFile::WriteLine("File tree control created");
m_strFileSpec = "*.cgf";
m_strSearchFolder = "Objects";
}
CFileTree::~CFileTree()
{
CLogFile::WriteLine("File tree control destoried");
}
BEGIN_MESSAGE_MAP(CFileTree, CTreeCtrl)
//{{AFX_MSG_MAP(CFileTree)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFileTree message handlers
BOOL CFileTree::PreCreateWindow(CREATESTRUCT& cs)
{
////////////////////////////////////////////////////////////////////////
// Modify the window styles
////////////////////////////////////////////////////////////////////////
cs.style |= WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
return CTreeCtrl::PreCreateWindow(cs);
}
int CFileTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
// Fill the tree control with the correct data
////////////////////////////////////////////////////////////////////////
HTREEITEM hRoot;
char szSearchPath[_MAX_PATH];
char szRootName[_MAX_PATH + 512];
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
// Create the list
//m_cImageList.Create(IDB_TREE_VIEW, 16, 1, RGB (255, 0, 255));
CMFCUtils::LoadTrueColorImageList( m_cImageList,IDB_TREE_VIEW,16,RGB(255,0,255) );
// Attach it to the control
SetImageList(&m_cImageList, TVSIL_NORMAL);
// Create name of the root
sprintf(szRootName, "Master CD %s Folder", m_strSearchFolder.GetBuffer(0));
// Add the Master CD folder to the list
hRoot = InsertItem(szRootName, 2, 2, TVI_ROOT);
// Create the folder path
sprintf(szSearchPath, "%s%s", GetIEditor()->GetMasterCDFolder(), (const char*)m_strSearchFolder );
// Fill the list
RecurseDirectory(szSearchPath, hRoot, m_strFileSpec.GetBuffer(0));
Expand(hRoot, TVE_EXPAND);
return 0;
}
void CFileTree::RecurseDirectory(char szFolder[_MAX_PATH], HTREEITEM hRoot, PSTR pszFileSpec)
{
////////////////////////////////////////////////////////////////////////
// Enumerate all files in the passed directory which match to the the
// passed pattern. Also continue with adding all subdirectories
////////////////////////////////////////////////////////////////////////
CFileEnum cTempFiles;
__finddata64_t sFile;
char szFilePath[_MAX_PATH];
HTREEITEM hNewRoot, hNewItem;
ASSERT(pszFileSpec);
// Make the path ready for appening a folder or filename
PathAddBackslash(szFolder);
// Start the enumeration of the files
if (cTempFiles.StartEnumeration(szFolder, "*.*", &sFile))
{
do
{
// Construct the full filepath of the current file
strcpy(szFilePath, szFolder);
strcat(szFilePath, sFile.name);
// Have we found a directory ?
if (sFile.attrib & _A_SUBDIR)
{
// Skip the parent directory entries
if (_stricmp(sFile.name, ".") == 0 ||
_stricmp(sFile.name, "..") == 0)
{
continue;
}
// Add it to the list and start recursion
hNewRoot = InsertItem(sFile.name, 0, 0, hRoot);
RecurseDirectory(szFilePath, hNewRoot, pszFileSpec);
continue;
}
// Check if the file name maches the pattern
if (!PathMatchSpec(sFile.name, pszFileSpec))
continue;
// Remove the extension from the name
PathRenameExtension(sFile.name, "");
// Add the file to the list
hNewItem = InsertItem(sFile.name, 1, 1, hRoot);
// Associate the handle of this item with the path
// of its file
m_cFileNames[hNewItem] = CString(szFilePath);
} while (cTempFiles.GetNextFile(&sFile));
}
}
CString CFileTree::GetSelectedFile()
{
////////////////////////////////////////////////////////////////////////
// Return the path of the currently selected file. If there is no
// currently selected file, just a NULL terminated string will be
// returned
////////////////////////////////////////////////////////////////////////
Files::iterator it = m_cFileNames.find(GetSelectedItem());
if (it != m_cFileNames.end())
return it->second;
else
return CString("");
}

View File

@@ -0,0 +1,68 @@
#if !defined(AFX_FILETREE_H__9848DF42_CD7E_4ADD_96F9_E01605C420D6__INCLUDED_)
#define AFX_FILETREE_H__9848DF42_CD7E_4ADD_96F9_E01605C420D6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// FileTree.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CFileTree window
class CFileTree : public CTreeCtrl
{
// Construction
public:
CFileTree();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFileTree)
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
CString GetSelectedFile();
virtual ~CFileTree();
// Sets the search pattern that decides which files should be displayed
void SetFileSpec(CString strFileSpec) { m_strFileSpec = strFileSpec; };
// Spezifies the root folder of the search, it is constructed as follows:
// X:\%MasterCD%\%SearchFolder%
void SetSearchFolder(CString strSearchFolder) { m_strSearchFolder = strSearchFolder; };
CString GetSearchFolder() { return m_strSearchFolder; };
// Generated message map functions
protected:
//{{AFX_MSG(CFileTree)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
CImageList m_cImageList;
void RecurseDirectory(char szFolder[_MAX_PATH], HTREEITEM hRoot, PSTR pszFileSpec);
typedef std::map<HTREEITEM,CString> Files;
Files m_cFileNames;
CString m_strFileSpec;
CString m_strSearchFolder;
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_FILETREE_H__9848DF42_CD7E_4ADD_96F9_E01605C420D6__INCLUDED_)

View File

@@ -0,0 +1,286 @@
// HiColorToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "HiColorToolBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar
CHiColorToolBar::CHiColorToolBar()
{
}
CHiColorToolBar::~CHiColorToolBar()
{
}
BEGIN_MESSAGE_MAP(CHiColorToolBar, CToolBar)
//{{AFX_MSG_MAP(CHiColorToolBar)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar message handlers
void CHiColorToolBar::AttachToolbarImages(UINT inNormalImageID)
{
////////////////////////////////////////////////////////////////////////
// Load the high color toolbar images and attach them to the toolbar
////////////////////////////////////////////////////////////////////////
// Make high-color image lists for each of the bitmaps
MakeToolbarImageList(inNormalImageID, m_ToolbarImages, LTNormal);
MakeToolbarImageList(inNormalImageID, m_ToolbarImagesDisabled, LTDisabled);
MakeToolbarImageList(inNormalImageID, m_ToolbarImagesHot, LTHot);
// Get the toolbar control associated with the CToolbar object
CToolBarCtrl& barCtrl = GetToolBarCtrl();
// Attach the image lists to the toolbar control
barCtrl.SetImageList(&m_ToolbarImages);
barCtrl.SetDisabledImageList(&m_ToolbarImagesDisabled);
barCtrl.SetHotImageList(&m_ToolbarImagesHot);
}
void CHiColorToolBar::ReplaceBackgroundColor(CBitmap& ioBM)
{
////////////////////////////////////////////////////////////////////////
// Find every pixel of the default background color in the specified
// bitmap and set each one to the user's button color
////////////////////////////////////////////////////////////////////////
// Figure out how many pixels there are in the bitmap
BITMAP bmInfo;
VERIFY (ioBM.GetBitmap (&bmInfo));
// Add support for additional bit depths if you choose
VERIFY (bmInfo.bmBitsPixel == 24);
VERIFY (bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
// Get a pointer to the pixels
DIBSECTION ds;
VERIFY (ioBM.GetObject (sizeof (DIBSECTION), &ds) == sizeof (DIBSECTION));
RGBTRIPLE* pixels = reinterpret_cast<RGBTRIPLE *> (ds.dsBm.bmBits);
VERIFY (pixels != NULL);
// Get the user's preferred button color from the system
const COLORREF buttonColor (::GetSysColor (COLOR_BTNFACE));
const RGBTRIPLE userBackgroundColor = {
GetBValue (buttonColor), GetGValue (buttonColor), GetRValue (buttonColor)};
// Search through the pixels, substituting the user's button
// color for any pixel that has the magic background color
for (UINT i = 0; i < numPixels; ++i)
{
if (pixels[i].rgbtBlue == kBackgroundColor.rgbtBlue
&& pixels[i].rgbtGreen == kBackgroundColor.rgbtGreen
&& pixels[i].rgbtRed == kBackgroundColor.rgbtRed)
{
pixels [i] = userBackgroundColor;
}
}
}
void CHiColorToolBar::MakeDisabled(CBitmap &ioBM)
{
////////////////////////////////////////////////////////////////////////
// Give the bitmap a disabled look
////////////////////////////////////////////////////////////////////////
// Figure out how many pixels there are in the bitmap
BITMAP bmInfo;
VERIFY (ioBM.GetBitmap (&bmInfo));
// Add support for additional bit depths if you choose
VERIFY (bmInfo.bmBitsPixel == 24);
VERIFY (bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
// Get a pointer to the pixels
DIBSECTION ds;
VERIFY (ioBM.GetObject (sizeof (DIBSECTION), &ds) == sizeof (DIBSECTION));
RGBTRIPLE* pixels = reinterpret_cast<RGBTRIPLE *> (ds.dsBm.bmBits);
VERIFY (pixels != NULL);
// Get the user's preferred button color from the system
const COLORREF buttonColor (::GetSysColor (COLOR_BTNFACE));
const RGBTRIPLE userBackgroundColor = {
GetBValue (buttonColor), GetGValue (buttonColor), GetRValue (buttonColor)};
// Loop trough all pixels
for (UINT i = 0; i < numPixels; ++i)
{
if (pixels[i].rgbtBlue == userBackgroundColor.rgbtBlue
&& pixels[i].rgbtGreen == userBackgroundColor.rgbtGreen
&& pixels[i].rgbtRed == userBackgroundColor.rgbtRed)
{
// Skip pixels that have the background color
continue;
}
// Average out the BGR channels
pixels[i].rgbtBlue = (pixels[i].rgbtBlue + pixels[i].rgbtGreen + pixels[i].rgbtRed) / 3;
pixels[i].rgbtRed = pixels[i].rgbtGreen = pixels[i].rgbtBlue;
}
}
void CHiColorToolBar::MakeToolbarImageList(UINT inBitmapID, CImageList& outImageList, LoadType lt)
{
////////////////////////////////////////////////////////////////////////
// Create an image list for the specified BMP resource
////////////////////////////////////////////////////////////////////////
CBitmap bm;
DWORD dwStyleParam = 0;
// If we use CBitmap::LoadBitmap() to load the bitmap, the colors
// will be reduced to the bit depth of the main screen and we won't
// be able to access the pixels directly. To avoid those problems,
// we'll load the bitmap as a DIBSection instead and attach the
// DIBSection to the CBitmap.
VERIFY(bm.Attach (::LoadImage (::AfxFindResourceHandle(
MAKEINTRESOURCE (inBitmapID), RT_BITMAP),
MAKEINTRESOURCE (inBitmapID), IMAGE_BITMAP, 0, 0,
(LR_DEFAULTSIZE | LR_CREATEDIBSECTION) | dwStyleParam)));
// Replace the specified color in the bitmap with the user's
// button color
ReplaceBackgroundColor(bm);
// Disable it when requested
if (lt == LTDisabled)
MakeDisabled(bm);
// Create a 24 bit image list with the same dimensions and number
// of buttons as the toolbar
VERIFY(outImageList.Create (
kImageWidth, kImageHeight, kToolBarBitDepth, kNumImages, 0));
// Attach the bitmap to the image list
VERIFY(outImageList.Add (&bm, RGB (0, 0, 0)) != -1);
}
void CHiColorToolBar::AddTextStrings()
{
////////////////////////////////////////////////////////////////////////
// Add text descriptions to a tool bar
////////////////////////////////////////////////////////////////////////
// Set the text for each button
CToolBarCtrl& bar = GetToolBarCtrl();
// Remove the string map in case we are loading another toolbar into this control
if (m_pStringMap)
{
delete m_pStringMap;
m_pStringMap = NULL;
}
int nIndex = 0;
TBBUTTON tb;
for (nIndex = bar.GetButtonCount() - 1; nIndex >= 0; nIndex--)
{
ZeroMemory(&tb, sizeof(TBBUTTON));
bar.GetButton(nIndex, &tb);
// Do we have a separator?
if ((tb.fsStyle & TBSTYLE_SEP) == TBSTYLE_SEP)
continue;
// Have we got a valid command id?
if (tb.idCommand == 0)
continue;
// Get the resource string if there is one.
CString strText;
LPCTSTR lpszButtonText = NULL;
CString strButtonText(_T(""));
_TCHAR seps[] = _T("\n");
strText.LoadString(tb.idCommand);
if (!strText.IsEmpty())
{
lpszButtonText = _tcstok((LPTSTR) (LPCTSTR) strText, seps);
while(lpszButtonText)
{
strButtonText = lpszButtonText;
lpszButtonText = _tcstok(NULL, seps);
}
}
if (!strButtonText.IsEmpty())
SetButtonText(nIndex, strButtonText);
}
// Resize the buttons so that the text will fit.
CRect rc(0, 0, 0, 0);
CSize sizeMax(0, 0);
for (nIndex = bar.GetButtonCount() - 1; nIndex >= 0; nIndex--)
{
bar.GetItemRect(nIndex, rc);
rc.NormalizeRect();
sizeMax.cx = __max(rc.Size().cx, sizeMax.cx);
sizeMax.cy = __max(rc.Size().cy, sizeMax.cy);
}
SetSizes(sizeMax, CSize(32, 32));
// Set the minimum button size
SendMessage(TB_SETBUTTONWIDTH, 0, (LPARAM) (DWORD) MAKELONG(85, 128));
}
bool CHiColorToolBar::CreateAll(UINT nIDRessource, UINT inNormalImageID, CWnd *pwndParent)
{
////////////////////////////////////////////////////////////////////////
// Load all data required for the full toolbar functionality
////////////////////////////////////////////////////////////////////////
CLogFile::WriteLine("Creating new high color toolbar...");
// Create the toolbar itself
if (!CreateEx(pwndParent, TBSTYLE_FLAT | TBSTYLE_WRAPABLE, WS_CHILD | CBRS_TOP
| CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
{
return false;
}
// Load the buttons
if (!LoadToolBar(nIDRessource))
return false;
// Attach the 24bpp images
AttachToolbarImages(inNormalImageID);
// Read the text strings out of the ressource and set them
AddTextStrings();
// Set maximum number of rows
GetToolBarCtrl().SetRows(99, TRUE, NULL);
// Indent the first button a few pixels so that the toolbar is centered
GetToolBarCtrl().SetIndent(4);
return true;
}

View File

@@ -0,0 +1,84 @@
#if !defined(AFX_HICOLORTOOLBAR_H__401DCAAA_ED0C_4838_8A8A_5B2C55328891__INCLUDED_)
#define AFX_HICOLORTOOLBAR_H__401DCAAA_ED0C_4838_8A8A_5B2C55328891__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HiColorToolBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar window
// These constants represent the dimensions and number of buttons in
// the default MFC-generated toolbar. If you need something different,
// feel free to change them. For extra credit, you can load the
// toolbar's existing image list at runtime and copy the parameters from
// there.
static const int kImageWidth (32);
static const int kImageHeight (32);
static const int kNumImages (8);
static const UINT kToolBarBitDepth (ILC_COLOR24);
// This color will be treated as transparent in the loaded bitmaps --
// in other words, any pixel of this color will be set at runtime to
// the user's button color. The Visual Studio toolbar editor defaults
// to 255, 0, 255 (pink).
static const RGBTRIPLE kBackgroundColor = {255, 0, 255};
// Parameters for
class CHiColorToolBar : public CToolBar
{
// Construction
public:
CHiColorToolBar();
// Attributes MakeToolbarImageList()
enum LoadType
{
LTNormal,
LTDisabled,
LTHot
};
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHiColorToolBar)
//}}AFX_VIRTUAL
// Implementation
public:
bool CreateAll(UINT nIDRessource, UINT inHotImage, CWnd *pwndParent);
virtual ~CHiColorToolBar();
// Generated message map functions
protected:
//{{AFX_MSG(CHiColorToolBar)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
void ReplaceBackgroundColor(CBitmap& ioBM);
void MakeDisabled(CBitmap &ioBM);
void MakeToolbarImageList(UINT inBitmapID, CImageList& outImageList, LoadType lt);
void AddTextStrings();
void AttachToolbarImages(UINT inNormalImageID);
CImageList m_ToolbarImagesDisabled;
CImageList m_ToolbarImagesHot;
CImageList m_ToolbarImages;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HICOLORTOOLBAR_H__401DCAAA_ED0C_4838_8A8A_5B2C55328891__INCLUDED_)

View File

@@ -0,0 +1,48 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplacebutton.cpp
// Version: v1.00
// Created: 6/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Stefan Belopotocan code.
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "InPlaceButton.h"
// CInPlaceButton
IMPLEMENT_DYNAMIC(CInPlaceButton, CXTButton)
CInPlaceButton::CInPlaceButton( OnClick onClickFunctor )
{
m_onClick = onClickFunctor;
}
CInPlaceButton::~CInPlaceButton()
{
}
BEGIN_MESSAGE_MAP(CInPlaceButton, CXTButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked)
END_MESSAGE_MAP()
// CInPlaceButton message handlers
void CInPlaceButton::OnBnClicked()
{
if (m_onClick)
m_onClick();
}
void CInPlaceButton::Click()
{
OnBnClicked();
}

View File

@@ -0,0 +1,47 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplacebutton.h
// Version: v1.00
// Created: 6/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __inplacebutton_h__
#define __inplacebutton_h__
#if _MSC_VER > 1000
#pragma once
#endif
// CInPlaceButton
#include <XTToolkit.h>
class CInPlaceButton : public CXTButton
{
DECLARE_DYNAMIC(CInPlaceButton)
public:
typedef Functor0 OnClick;
CInPlaceButton( OnClick onClickFunctor );
virtual ~CInPlaceButton();
// Simuale on click.
void Click();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClicked();
OnClick m_onClick;
};
#endif // __inplacebutton_h__

View File

@@ -0,0 +1,743 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplacecombobox.cpp
// Version: v1.00
// Created: 5/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Stefan Belopotocan code.
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "InPlaceComboBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define DEFAULT_IPLISTBOX_HEIGHT 16 * 8
#define WM_USER_ON_SELECTION_CANCEL (WM_USER + 10)
#define WM_USER_ON_SELECTION_OK (WM_USER + 11)
#define WM_USER_ON_NEW_SELECTION (WM_USER + 12)
#define WM_USER_ON_EDITCHANGE (WM_USER + 13)
/////////////////////////////////////////////////////////////////////////////
// CInPlaceCBEdit
BOOL CInPlaceCBEdit::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
CWnd* pOwner = GetOwner();
WPARAM nChar = pMsg->wParam;
switch(nChar)
{
case VK_ESCAPE:
case VK_RETURN:
case VK_TAB:
::PeekMessage(pMsg, NULL, NULL, NULL, PM_REMOVE);
pOwner->SendMessage(WM_USER_ON_EDITCHANGE, nChar);
pOwner->GetParent()->SetFocus();
return TRUE;
case VK_UP:
case VK_DOWN:
pOwner->SendMessage(WM_USER_ON_NEW_SELECTION, nChar);
return TRUE;
default:
;
}
}
return CEdit::PreTranslateMessage(pMsg);
}
BEGIN_MESSAGE_MAP(CInPlaceCBEdit, CEdit)
//{{AFX_MSG_MAP(CInPlaceCBEdit)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceCBEdit message handlers
BOOL CInPlaceCBEdit::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CInPlaceCBListBox
CInPlaceCBListBox::CInPlaceCBListBox()
{
m_pScrollBar = 0;
m_nLastTopIdx = 0;
}
CInPlaceCBListBox::~CInPlaceCBListBox()
{
}
BEGIN_MESSAGE_MAP(CInPlaceCBListBox, CListBox)
//{{AFX_MSG_MAP(CInPlaceCBListBox)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceCBListBox message handlers
void CInPlaceCBListBox::ProcessSelected(bool bProcess)
{
//ReleaseCapture();
CWnd* pOwner = GetOwner();
if(bProcess)
{
int nSelectedItem = GetCurSel();
pOwner->SendMessage(WM_USER_ON_SELECTION_OK, nSelectedItem, GetItemData(nSelectedItem));
}
else
pOwner->SendMessage(WM_USER_ON_SELECTION_CANCEL);
}
void CInPlaceCBListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
CListBox::OnLButtonUp(nFlags, point);
CRect rect;
GetClientRect(rect);
if(!rect.PtInRect(point))
ProcessSelected(false);
}
void CInPlaceCBListBox::OnLButtonUp(UINT nFlags, CPoint point)
{
CListBox::OnLButtonUp(nFlags, point);
CRect rect;
GetClientRect(rect);
if(rect.PtInRect(point))
ProcessSelected();
//else
// ReleaseCapture();
}
void CInPlaceCBListBox::OnRButtonDown(UINT nFlags, CPoint point)
{
CListBox::OnRButtonDown(nFlags, point);
ProcessSelected(false);
}
BOOL CInPlaceCBListBox::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case VK_RETURN:
ProcessSelected();
return TRUE;
case VK_ESCAPE:
case VK_TAB:
ProcessSelected(false);
return TRUE;
default:
;
}
}
if(pMsg->message == WM_SYSKEYDOWN)
{
ProcessSelected(false);
return FALSE;
}
return CListBox::PreTranslateMessage(pMsg);
}
int CInPlaceCBListBox::GetBottomIndex()
{
int nTop = GetTopIndex();
CRect rc;
GetClientRect( &rc );
int nVisCount = rc.Height() / GetItemHeight(0);
return nTop + nVisCount;
}
void CInPlaceCBListBox::SetTopIdx(int nPos, BOOL bUpdateScrollbar)
{
m_nLastTopIdx = nPos;
SetTopIndex( nPos );
if( bUpdateScrollbar )
{
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( m_pScrollBar->GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
{
info.nPos = m_nLastTopIdx;
m_pScrollBar->SetScrollInfo( &info );
}
}
}
//////////////////////////////////////////////////////////////////////////
// CInPlaceCBScrollBar
/////////////////////////////////////////////////////////////////////////////
CInPlaceCBScrollBar::CInPlaceCBScrollBar()
{
m_pListBox = 0;
}
CInPlaceCBScrollBar::~CInPlaceCBScrollBar()
{
}
BEGIN_MESSAGE_MAP(CInPlaceCBScrollBar, CScrollBar)
//{{AFX_MSG_MAP(CInPlaceCBScrollBar)
ON_WM_MOUSEMOVE()
ON_WM_VSCROLL_REFLECT()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceCBScrollBar message handlers
void CInPlaceCBScrollBar::OnMouseMove(UINT nFlags, CPoint point)
{
//
// Is mouse within listbox
CRect rcClient;
GetClientRect( rcClient );
if( !rcClient.PtInRect( point ) )
{
//ReleaseCapture();
//GetParent()->SendMessage( WM_VRC_SETCAPTURE );
}
// OutputDebugString( "DropScrollBar MouseMove\n" );
CScrollBar::OnMouseMove(nFlags, point);
}
void CInPlaceCBScrollBar::VScroll(UINT nSBCode, UINT nPos)
{
// TODO: Add your message handler code here
if( !m_pListBox )
return;
int nTop = m_pListBox->GetTopIndex();
int nBottom = m_pListBox->GetBottomIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
if( !GetScrollInfo( &info, SIF_ALL|SIF_DISABLENOSCROLL ) )
return;
switch( nSBCode )
{
case SB_BOTTOM: // Scroll to bottom.
break;
case SB_ENDSCROLL: // End scroll.
break;
case SB_LINEDOWN: // Scroll one line down.
info.nPos++;
if( info.nPos > info.nMax )
info.nPos = info.nMax;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_LINEUP: // Scroll one line up.
info.nPos--;
if( info.nPos < info.nMin )
info.nPos = info.nMin;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_PAGEDOWN: // Scroll one page down.
info.nPos += info.nPage;
if( info.nPos > info.nMax )
info.nPos = info.nMax;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_PAGEUP: // Scroll one page up.
info.nPos -= info.nPage;
if( info.nPos < info.nMin )
info.nPos = info.nMin;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_THUMBPOSITION: // Scroll to the absolute position. The current position is provided in nPos.
info.nPos = nPos;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. The current position is provided in nPos.
info.nPos = nPos;
m_pListBox->SetTopIdx( info.nPos );
break;
case SB_TOP: // Scroll to top.
break;
}
SetScrollInfo( &info );
}
//////////////////////////////////////////////////////////////////////////
void CInPlaceCBScrollBar::SetListBox( CInPlaceCBListBox* pListBox )
{
ASSERT( pListBox != NULL );
m_pListBox = pListBox;
int nTop = m_pListBox->GetTopIndex();
int nBottom = m_pListBox->GetBottomIndex();
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
info.nMax = m_pListBox->GetCount()-1;
info.nMin = 0;
info.nPage = nBottom - nTop;
info.nPos = 0;
info.nTrackPos = 0;
SetScrollInfo( &info );
}
void CInPlaceCBScrollBar::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rc;
GetClientRect( &rc );
if( !rc.PtInRect( point ) )
{
GetOwner()->SendMessage(WM_USER_ON_SELECTION_CANCEL);
}
CScrollBar::OnLButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CInPlaceComboBox
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
int CInPlaceComboBox::m_nButtonDx = ::GetSystemMetrics(SM_CXHSCROLL);
IMPLEMENT_DYNAMIC(CInPlaceComboBox, CWnd)
CInPlaceComboBox::CInPlaceComboBox()
{
m_bReadOnly = false;
m_nCurrentSelection = -1;
}
BEGIN_MESSAGE_MAP(CInPlaceComboBox, CWnd)
//{{AFX_MSG_MAP(CInPlaceComboBox)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_WM_SETFOCUS()
ON_WM_LBUTTONDOWN()
ON_MESSAGE(WM_USER_ON_SELECTION_OK, OnSelectionOk)
ON_MESSAGE(WM_USER_ON_SELECTION_CANCEL, OnSelectionCancel)
ON_MESSAGE(WM_USER_ON_NEW_SELECTION, OnNewSelection)
ON_MESSAGE(WM_USER_ON_EDITCHANGE, OnEditChange)
ON_MESSAGE(WM_SELECTED_ITEM, OnSelectionOk)
ON_MESSAGE(WM_DESTROY_DROPLIST, OnSelectionCancel)
//}}AFX_MSG_MAP
ON_WM_MOVE()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceComboBox message handlers
int CInPlaceComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect;
GetClientRect(rect);
rect.right -= m_nButtonDx;
CWnd* pParent = GetParent();
ASSERT(pParent != NULL);
CFont* pFont = pParent->GetFont();
int flags = 0;
if (m_bReadOnly)
flags |= ES_READONLY;
m_wndEdit.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|flags, rect, this, 2);
m_wndEdit.SetOwner(this);
m_wndEdit.SetFont(pFont);
//m_minListWidth = 300;
rect.right += m_nButtonDx - 1;
rect.top = rect.bottom + 2;
rect.bottom += 100;
/*
CString myClassName = AfxRegisterWndClass(
CS_VREDRAW | CS_HREDRAW,::LoadCursor(NULL, IDC_ARROW),(HBRUSH)::GetStockObject(WHITE_BRUSH),NULL );
m_wndDropDown.CreateEx( 0,myClassName,0,WS_POPUP|WS_BORDER,rect,GetDesktopWindow(),0 );
m_wndDropDown.ModifyStyleEx( 0,WS_EX_TOOLWINDOW|WS_EX_TOPMOST );
rect.right -= m_nButtonDx;
//int nListStyle = WS_VISIBLE|WS_CHILD|LBS_DISABLENOSCROLL|LBS_HASSTRINGS|LBS_NOTIFY;
int nListStyle = WS_VISIBLE|WS_CHILD|LBS_HASSTRINGS|LBS_NOTIFY;
m_wndList.Create( nListStyle, rect, &m_wndDropDown, 0);
m_wndList.SetOwner(this);
m_wndList.SetFont(pFont);
rect.right += m_nButtonDx;
m_scrollBar.Create( SBS_VERT|SBS_RIGHTALIGN|WS_CHILD,rect,&m_wndDropDown,1 );
m_scrollBar.ShowWindow(SW_SHOW);
m_wndList.SetScrollBar(&m_scrollBar);
m_scrollBar.SetListBox(&m_wndList);
*/
m_wndDropDown.Create( 0,0,WS_BORDER|WS_CHILD|LBS_DISABLENOSCROLL|LBS_HASSTRINGS|LBS_NOTIFY,rect,GetDesktopWindow(),0 );
m_wndDropDown.SetFont(pFont);
m_wndDropDown.GetListBox().SetFont(pFont);
m_wndDropDown.GetListBox().SetOwner(this);
m_wndDropDown.SetOwner(this);
return 0;
}
void CInPlaceComboBox::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
m_wndEdit.SetWindowPos(NULL, 0, 0, cx - m_nButtonDx, cy, SWP_NOZORDER|SWP_NOMOVE);
}
void CInPlaceComboBox::MoveControl(CRect& rect)
{
CRect prevRect;
GetClientRect(prevRect);
CWnd* pParent = GetParent();
ClientToScreen(prevRect);
pParent->ScreenToClient(prevRect);
pParent->InvalidateRect(prevRect);
MoveWindow(rect, FALSE);
}
void CInPlaceComboBox::GetDropDownRect( CRect &rect )
{
GetWindowRect(rect);
rect.top = rect.bottom;
rect.bottom += 100;
}
void CInPlaceComboBox::ResetListBoxHeight()
{
/*
CRect rect;
GetClientRect(rect);
rect.right -= 1;
int nItems = m_wndList.GetCount();
int nListBoxHeight = nItems > 0 ? nItems * m_nButtonDx : DEFAULT_IPLISTBOX_HEIGHT;
if(nListBoxHeight > DEFAULT_IPLISTBOX_HEIGHT)
nListBoxHeight = DEFAULT_IPLISTBOX_HEIGHT;
*/
}
void CInPlaceComboBox::OnPaint()
{
CPaintDC dc(this);
// Nakresli tla<6C><61>tko
CRect rect;
GetClientRect(rect);
rect.left = rect.right - m_nButtonDx;
#if 1
dc.DrawFrameControl(rect, DFC_SCROLL, m_wndDropDown.IsWindowVisible() ?
DFCS_SCROLLDOWN|DFCS_PUSHED : DFCS_SCROLLDOWN);
#else
dc.DrawFrameControl(rect, DFC_SCROLL, m_wndDropDown.IsWindowVisible() ?
DFCS_SCROLLDOWN|DFCS_PUSHED|DFCS_FLAT : DFCS_SCROLLDOWN|DFCS_FLAT);
#endif
}
BOOL CInPlaceComboBox::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
void CInPlaceComboBox::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnLButtonDown(nFlags, point);
CRect rect;
GetClientRect(rect);
CRect rectButton(rect);
rectButton.left = rectButton.right - m_nButtonDx;
if(rectButton.PtInRect(point))
{
int nDoAction = m_wndDropDown.IsWindowVisible() ? SW_HIDE : SW_SHOW;
if (nDoAction == SW_SHOW)
{
ResetListBoxHeight();
CRect rc;
GetDropDownRect(rc);
if (rc.Width() < m_minListWidth+10)
{
//m_wndDropDown.SetWindowPos( &wndTopMost, rc.left,rc.top,rc.Width(),rc.Height(), SWP_SHOWWINDOW );
//m_wndDropDown.GetClientRect(rc);
//m_wndList.MoveWindow(rc);
}
//m_wndDropDown.SetWindowPos( &wndTopMost, rc.left,rc.top,rc.Width(),rc.Height(), SWP_SHOWWINDOW );
//m_wndDropDown.MoveWindow( rc );
//m_wndDropDown.GetClientRect(rc);
//m_wndList.MoveWindow(rc);
CRect rect;
GetDropDownRect(rect);
m_wndDropDown.SetWindowPos( &wndTopMost, rect.left,rect.top,rect.Width(),rect.Height(), SWP_SHOWWINDOW );
}
m_wndDropDown.ShowWindow(nDoAction);
InvalidateRect(rectButton, FALSE);
if(nDoAction == SW_SHOW)
{
m_wndDropDown.GetListBox().SetFocus();
m_wndDropDown.SetCapture();
}
}
}
//////////////////////////////////////////////////////////////////////////
void CInPlaceComboBox::OnSetFocus(CWnd* pOldWnd)
{
CWnd::OnSetFocus(pOldWnd);
m_wndEdit.SetFocus();
}
void CInPlaceComboBox::HideListBox()
{
if (GetCapture())
ReleaseCapture();
m_wndDropDown.ShowWindow(SW_HIDE);
CRect rectButton;
GetClientRect(rectButton);
rectButton.left = rectButton.right - m_nButtonDx;
InvalidateRect(rectButton, FALSE);
m_wndEdit.SetFocus();
}
//////////////////////////////////////////////////////////////////////////
LRESULT CInPlaceComboBox::OnSelectionOk(WPARAM wParam, LPARAM /*lParam*/)
{
HideListBox();
SetCurSelToEdit(m_nCurrentSelection = int(wParam));
if (m_updateCallback)
m_updateCallback();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
LRESULT CInPlaceComboBox::OnSelectionCancel(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
HideListBox();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
LRESULT CInPlaceComboBox::OnEditChange(WPARAM wParam, LPARAM lParam)
{
HideListBox();
if (m_updateCallback)
m_updateCallback();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
LRESULT CInPlaceComboBox::OnNewSelection(WPARAM wParam, LPARAM /*lParam*/)
{
/*
int nItems = m_wndList.GetCount();
if(nItems > 0)
{
if(wParam == VK_UP)
{
if(m_nCurrentSelection > 0)
SetCurSel(m_nCurrentSelection - 1);
}
else
{
if(m_nCurrentSelection < nItems - 1)
SetCurSel(m_nCurrentSelection + 1);
}
}
*/
return TRUE;
}
void CInPlaceComboBox::SetCurSelToEdit(int nSelect)
{
CString strText;
if(nSelect != -1)
m_wndDropDown.GetListBox().GetText(nSelect, strText);
m_wndEdit.SetWindowText(strText);
m_wndEdit.SetSel(0, -1);
}
int CInPlaceComboBox::GetCount() const
{
return m_wndDropDown.GetListBox().GetCount();
}
int CInPlaceComboBox::SetCurSel(int nSelect, bool bSendSetData)
{
if(nSelect >= m_wndDropDown.GetListBox().GetCount())
return CB_ERR;
int nRet = m_wndDropDown.GetListBox().SetCurSel(nSelect);
if(nRet != -1)
{
SetCurSelToEdit(nSelect);
m_nCurrentSelection = nSelect;
if(bSendSetData)
{
if (m_updateCallback)
m_updateCallback();
}
}
return nRet;
}
//////////////////////////////////////////////////////////////////////////
void CInPlaceComboBox::SelectString( LPCTSTR pStrText )
{
m_wndEdit.SetWindowText(pStrText);
int sel = m_wndDropDown.GetListBox().FindString( -1,pStrText );
if (sel != LB_ERR)
{
SetCurSel(sel,false);
}
}
//////////////////////////////////////////////////////////////////////////
CString CInPlaceComboBox::GetSelectedString()
{
CString str;
m_wndEdit.GetWindowText( str );
return str;
}
CString CInPlaceComboBox::GetTextData() const
{
CString strText;
if(m_nCurrentSelection != -1)
m_wndDropDown.GetListBox().GetText(m_nCurrentSelection, strText);
return strText;
}
int CInPlaceComboBox::AddString(LPCTSTR pStrText, DWORD nData)
{
int nIndex = m_wndDropDown.GetListBox().AddString(pStrText);
CDC *dc = GetDC();
CSize size = dc->GetTextExtent( pStrText );
ReleaseDC(dc);
if (size.cx > m_minListWidth)
m_minListWidth = size.cx;
return m_wndDropDown.GetListBox().SetItemData(nIndex, nData);
}
//////////////////////////////////////////////////////////////////////////
void CInPlaceComboBox::ResetContent()
{
m_wndDropDown.GetListBox().ResetContent();
m_nCurrentSelection = -1;
}
//////////////////////////////////////////////////////////////////////////
void CInPlaceComboBox::OnMove(int x, int y)
{
CWnd::OnMove(x, y);
if (m_wndDropDown.m_hWnd)
{
CRect rect;
GetDropDownRect(rect);
m_wndDropDown.MoveWindow( rect );
/*
m_wndDropDown.GetClientRect(rect);
rect.right -= m_nButtonDx;
m_wndList.MoveWindow(rect);
rect.left = rect.right+1;
rect.right += m_nButtonDx;
m_scrollBar.MoveWindow(rect);
*/
}
}

View File

@@ -0,0 +1,238 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplacecombobox.h
// Version: v1.00
// Created: 5/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __inplacecombobox_h__
#define __inplacecombobox_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "DropWnd.h"
class CInPlaceCBEdit : public CEdit
{
CInPlaceCBEdit(const CInPlaceCBEdit& d);
CInPlaceCBEdit& operator=(const CInPlaceCBEdit& d);
public:
CInPlaceCBEdit();
virtual ~CInPlaceCBEdit();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceCBEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceCBEdit)
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
inline CInPlaceCBEdit::CInPlaceCBEdit()
{
}
inline CInPlaceCBEdit::~CInPlaceCBEdit()
{
}
/////////////////////////////////////////////////////////////////////////////
// CInPlaceCBListBox
class CInPlaceCBListBox : public CListBox
{
CInPlaceCBListBox(const CInPlaceCBListBox& d);
CInPlaceCBListBox& operator=(const CInPlaceCBListBox& d);
public:
CInPlaceCBListBox();
virtual ~CInPlaceCBListBox();
void SetScrollBar( CScrollBar *sb ) { m_pScrollBar = sb; };
int GetBottomIndex();
void SetTopIdx(int nPos, BOOL bUpdateScrollbar=FALSE );
// Operations
protected:
void ProcessSelected(bool bProcess = true);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceCBListBox)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceCBListBox)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
int m_nLastTopIdx;
CScrollBar* m_pScrollBar;
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class CInPlaceCBScrollBar : public CScrollBar
{
// Construction
public:
CInPlaceCBScrollBar();
// Attributes
public:
// Operations
public:
void SetListBox( CInPlaceCBListBox* pListBox );
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceCBScrollBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CInPlaceCBScrollBar();
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceCBScrollBar)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void VScroll(UINT nSBCode, UINT nPos);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CInPlaceCBListBox* m_pListBox;
};
/////////////////////////////////////////////////////////////////////////////
// CInPlaceComboBox
class CInPlaceComboBox : public CWnd
{
CInPlaceComboBox(const CInPlaceComboBox& d);
CInPlaceComboBox operator=(const CInPlaceComboBox& d);
protected:
DECLARE_DYNAMIC(CInPlaceComboBox)
public:
typedef Functor0 UpdateCallback;
CInPlaceComboBox();
virtual ~CInPlaceComboBox();
void SetUpdateCallback( UpdateCallback cb ) { m_updateCallback = cb; };
void SetReadOnly( bool bEnable ) { m_bReadOnly = bEnable; };
// Attributes
public:
int GetCurrentSelection() const;
CString GetTextData() const;
// Operations
public:
int GetCount() const;
int GetCurSel() const { return GetCurrentSelection(); };
int SetCurSel(int nSelect, bool bSendSetData = true);
void SelectString( LPCTSTR pStrText );
CString GetSelectedString();
int AddString(LPCTSTR pStrText, DWORD nData = 0);
void ResetContent();
void ResetListBoxHeight();
void MoveControl(CRect& rect);
private:
void SetCurSelToEdit(int nSelect);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceComboBox)
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceComboBox)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg LRESULT OnSelectionOk(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSelectionCancel(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnEditChange(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnNewSelection(WPARAM wParam, LPARAM lParam);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
void HideListBox();
void GetDropDownRect( CRect &rect );
// Data
private:
static int m_nButtonDx;
int m_minListWidth;
bool m_bReadOnly;
int m_nCurrentSelection;
UpdateCallback m_updateCallback;
CInPlaceCBEdit m_wndEdit;
//CInPlaceCBListBox m_wndList;
//CInPlaceCBScrollBar m_scrollBar;
//CWnd m_wndDropDown;
CDropWnd m_wndDropDown;
public:
afx_msg void OnMove(int x, int y);
};
inline CInPlaceComboBox::~CInPlaceComboBox()
{
}
inline int CInPlaceComboBox::GetCurrentSelection() const
{
return m_nCurrentSelection;
}
#endif // __inplacecombobox_h__#pragma once

View File

@@ -0,0 +1,99 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplaceedit.cpp
// Version: v1.00
// Created: 5/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Based on Stefan Belopotocan code.
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "InPlaceEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CInPlaceEdit
CInPlaceEdit::CInPlaceEdit( const CString& srtInitText,OnChange onchange )
{
m_strInitText = srtInitText;
m_onChange = onchange;
}
CInPlaceEdit::~CInPlaceEdit()
{
}
void CInPlaceEdit::SetText(const CString& strText)
{
m_strInitText = strText;
SetWindowText(strText);
SetSel(0, -1);
}
BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case VK_ESCAPE:
case VK_RETURN:
::PeekMessage(pMsg, NULL, NULL, NULL, PM_REMOVE);
case VK_TAB:
GetParent()->SetFocus();
if (m_onChange)
m_onChange();
return TRUE;
default:
;
}
}
return CEdit::PreTranslateMessage(pMsg);
}
BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
//{{AFX_MSG_MAP(CInPlaceEdit)
ON_WM_CREATE()
ON_WM_KILLFOCUS()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInPlaceEdit message handlers
int CInPlaceEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
CFont* pFont = GetParent()->GetFont();
SetFont(pFont);
SetWindowText(m_strInitText);
return 0;
}
void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
}
BOOL CInPlaceEdit::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}

View File

@@ -0,0 +1,57 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: inplaceedit.h
// Version: v1.00
// Created: 5/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __inplaceedit_h__
#define __inplaceedit_h__
#if _MSC_VER > 1000
#pragma once
#endif
class CInPlaceEdit : public CEdit
{
public:
typedef Functor0 OnChange;
CInPlaceEdit( const CString& srtInitText,OnChange onchange );
virtual ~CInPlaceEdit();
// Attributes
void SetText(const CString& strText);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInPlaceEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CInPlaceEdit)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Data
protected:
CString m_strInitText;
OnChange m_onChange;
};
#endif // __inplaceedit_h__

View File

@@ -0,0 +1,743 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: layerslistbox.cpp
// Version: v1.00
// Created: 10/4/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LayersListBox.h"
#include "Objects\ObjectManager.h"
// CLayersListBox dialog
#define INDENT_SIZE 16
#define ITEM_EXPANDED_BITMAP 2
#define ITEM_COLLAPSED_BITMAP 3
#define ITEM_LEAF_BITMAP 4
#define BUTTON_VISIBLE 0
#define BUTTON_USABLE 1
#define BUTTON_EXPAND 2
IMPLEMENT_DYNAMIC(CLayersListBox, CListBox)
//////////////////////////////////////////////////////////////////////////
CLayersListBox::CLayersListBox()
{
m_itemHeight = 24;
m_handCursor = false;
m_mousePaintFlags = 0;
m_mousePaintValue = false;
m_noReload = false;
m_draggingItem = -1;
m_rclickedItem = -1;
}
//////////////////////////////////////////////////////////////////////////
CLayersListBox::~CLayersListBox()
{
DeleteObject( m_hHandCursor );
}
BEGIN_MESSAGE_MAP(CLayersListBox, CListBox)
ON_WM_DRAWITEM_REFLECT()
ON_WM_MEASUREITEM_REFLECT()
ON_WM_COMPAREITEM_REFLECT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_CREATE()
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
END_MESSAGE_MAP()
// CLayersListBox message handlers
void CLayersListBox::DrawItem(LPDRAWITEMSTRUCT lpdis)
{
//dis->
if (lpdis->itemAction == ODA_SELECT || lpdis->itemAction == ODA_DRAWENTIRE)
{
CRect rc = lpdis->rcItem;
CDC dc;
dc.Attach(lpdis->hDC);
SLayerInfo &layerInfo = m_layersInfo[lpdis->itemData];
CString text = layerInfo.name;
CBrush brush( GetSysColor(COLOR_BTNFACE) );
//CBrush *prevBrush = dc.SelectObject( &brush );
HPEN prevPen = (HPEN)dc.SelectObject( (HPEN)GetStockObject(WHITE_PEN) );
CRect buttonRc = GetButtonsFrame(rc);
CRect nameRc;
nameRc.SubtractRect(rc,buttonRc);
CRect btnrc = buttonRc;
btnrc.top += 1;
dc.Draw3dRect( btnrc,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
if (lpdis->itemState & ODS_SELECTED)
{
// Selected
dc.FillSolidRect( nameRc,GetSysColor(COLOR_HIGHLIGHT) ); // blue.
//dc.DrawRect(rc,GetSysColor(COLOR_3DDKSHADOW),GetSysColor(COLOR_3DHILIGHT) );
dc.SetTextColor( GetSysColor(COLOR_HIGHLIGHTTEXT) );
}
else
{
// Normal.
dc.FillSolidRect( nameRc,GetSysColor(COLOR_BTNFACE) ); // blue.
//dc.Draw3dRect(rc,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
dc.SetTextColor( GetSysColor(COLOR_BTNTEXT) );
}
// Draw separator white line.
dc.MoveTo( nameRc.left,nameRc.top );
dc.LineTo( nameRc.right,nameRc.top );
//int indent = max(0,layerInfo.indent-1);
int indent = layerInfo.indent;
// Draw text.
int textX = nameRc.left + 3 + indent*INDENT_SIZE;
int textY = nameRc.top + (nameRc.bottom-nameRc.top)/2 - 8;
/*
if (layerInfo.indent > 0)
{
CPen pen(PS_SOLID,1,RGB(128,128,128) );
CPen *oldPen = dc.SelectObject( &pen );
CPoint center = nameRc.CenterPoint();
dc.MoveTo( textX-2,center.y );
dc.LineTo( textX-10,center.y );
//dc.LineTo( textX-10,nameRc.top );
dc.MoveTo( textX-10,rc.top );
if (layerInfo.lastchild)
dc.LineTo( textX-10,center.y );
else
dc.LineTo( textX-10,rc.bottom );
dc.SelectObject( oldPen );
}
*/
if (layerInfo.childs)
{
CRect expandRect = GetExpandButtonRect( lpdis->itemData );
//expandRect.left -= 14;
// Draw Expand icon.
if (layerInfo.expanded)
m_imageList.Draw( &dc,ITEM_EXPANDED_BITMAP,CPoint(expandRect.left,expandRect.top+5),ILD_TRANSPARENT );
else
m_imageList.Draw( &dc,ITEM_COLLAPSED_BITMAP,CPoint(expandRect.left,expandRect.top+5),ILD_TRANSPARENT );
textX += 14;
}
CFont *prevFont = NULL;
if (layerInfo.pLayer->IsExternal())
{
if (!m_externalFont.GetSafeHandle())
{
VERIFY(m_externalFont.CreateFont(-::MulDiv(8, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72), 0, 0, 0,
FW_DONTCARE, FALSE, TRUE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH, "Tahoma"));
}
prevFont = dc.SelectObject( &m_externalFont );
}
m_imageList.Draw( &dc,ITEM_LEAF_BITMAP,CPoint(textX,textY),ILD_TRANSPARENT );
dc.TextOut( textX+2+16,textY+2,text );
DrawCheckButton( dc,rc,0,m_layersInfo[lpdis->itemData].visible );
DrawCheckButton( dc,rc,1,m_layersInfo[lpdis->itemData].usable );
dc.SelectObject( prevPen );
if (prevFont)
dc.SelectObject( prevFont );
if (lpdis->itemData == m_layersInfo.size()-1)
{
HPEN prevPen = (HPEN)dc.SelectObject( (HPEN)GetStockObject(BLACK_PEN) );
// For last item draw black line at bottom.
dc.MoveTo( nameRc.left,nameRc.bottom-1 );
dc.LineTo( nameRc.right,nameRc.bottom-1 );
dc.SelectObject(prevPen);
}
//dc.SelectObject(prevBrush);
dc.Detach();
}
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
// lpMeasureItemStruct->itemWidth = 0;
lpMeasureItemStruct->itemHeight = m_itemHeight;
//lpMeasureItemStruct->itemData = 0;
}
//////////////////////////////////////////////////////////////////////////
int CLayersListBox::CompareItem( LPCOMPAREITEMSTRUCT lpCompareItemStruct )
{
//lpCompareItemStruct.
return 0;
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::PreSubclassWindow()
{
CListBox::PreSubclassWindow();
Init();
}
//////////////////////////////////////////////////////////////////////////
int CLayersListBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListBox::OnCreate(lpCreateStruct) == -1)
return -1;
Init();
return 0;
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::Init()
{
// Initialization.
SetItemHeight(0,m_itemHeight);
// SetFont( CFont::FromHandle( (HFONT)::GetStockObject(SYSTEM_FONT)) );
//m_imageList.Create( IDB_LAYER_BUTTONS,16,16,RGB(255,0,255) );
CMFCUtils::LoadTrueColorImageList( m_imageList,IDB_LAYER_BUTTONS,16,RGB(255,0,255) );
m_hHandCursor = LoadCursor( NULL,MAKEINTRESOURCE(IDC_HAND) );
CRect rc;
GetClientRect(rc);
}
//////////////////////////////////////////////////////////////////////////
inline int CompareLayersInfo( const CLayersListBox::SLayerInfo &layer1,const CLayersListBox::SLayerInfo &layer2 )
{
return layer1.name < layer2.name;
}
//////////////////////////////////////////////////////////////////////////
CRect CLayersListBox::GetButtonRect( CRect &rcItem,int id )
{
int ofsx = 3;
int ofsy = 3;
int sz = m_itemHeight-ofsy;
CRect rc;
rc.left = rcItem.left + (sz+ofsx)*id + ofsx;
rc.right = rc.left + sz;
rc.top = rcItem.top + ofsy;
rc.bottom = rcItem.top + sz;
return rc;
}
CRect CLayersListBox::GetButtonsFrame( CRect &rcItem )
{
CRect buttonRc;
CRect brc = GetButtonRect(rcItem,1);
buttonRc = rcItem;
buttonRc.right = brc.right + 4;
return buttonRc;
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::DrawCheckButton( CDC &dc,CRect &rcItem,int id,bool state )
{
CRect rc = GetButtonRect( rcItem,id );
dc.Draw3dRect(rc,GetSysColor(COLOR_3DDKSHADOW),GetSysColor(COLOR_3DHILIGHT));
if (state)
{
m_imageList.Draw( &dc,id,CPoint(rc.left+2,rc.top+1),ILD_TRANSPARENT );
}
else
{
//dc.Draw3dRect(rc,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
}
}
//////////////////////////////////////////////////////////////////////////
CRect CLayersListBox::GetExpandButtonRect( int item )
{
assert( item >= 0 && item < m_layersInfo.size() );
CRect rcItem;
GetItemRect( item,rcItem );
CRect rcBtn(0,0,0,0);
SLayerInfo &layerInfo = m_layersInfo[item];
if (layerInfo.childs)
{
// See if hit expand button.
rcBtn = GetButtonsFrame(rcItem);
rcBtn.left = rcBtn.right + 3 + layerInfo.indent*INDENT_SIZE;
rcBtn.right = rcBtn.left + 14;
}
return rcBtn;
}
//////////////////////////////////////////////////////////////////////////
int CLayersListBox::GetButtonFromPoint( CPoint point )
{
BOOL bOutside;
int button = -1;
// Find item where we clicked.
int item = ItemFromPoint( point,bOutside );
if (item != LB_ERR && !bOutside)
{
CRect rcItem;
GetItemRect( item,rcItem );
for (int i = 0; i < 2; i++)
{
CRect buttonRc = GetButtonRect(rcItem,i);
buttonRc.InflateRect(0,5);
if (buttonRc.PtInRect(point))
{
button = i;
break;
}
}
if (button < 0)
{
if (GetExpandButtonRect(item).PtInRect(point))
button = BUTTON_EXPAND;
}
}
return button;
}
//////////////////////////////////////////////////////////////////////////
bool CLayersListBox::HandleMouseClick( UINT nFlags,CPoint point )
{
bool bNoSelect = false;
BOOL bOutside;
// Find item where we clicked.
int item = ItemFromPoint( point,bOutside );
if (item != LB_ERR && !bOutside)
{
CRect rcItem;
GetItemRect( item,rcItem );
/*
if (GetSel(item))
{
m_layersInfo[item].visible = true;
m_layersInfo[item].usable = true;
return true;
}
*/
CRect buttonRc = GetButtonsFrame(rcItem);
if (buttonRc.PtInRect(point))
{
// Clicked in button.
bNoSelect = true;
}
int button = GetButtonFromPoint(point);
if (button == BUTTON_VISIBLE)
{
m_mousePaintFlags = (1<<31) | button;
m_layersInfo[item].visible = !m_layersInfo[item].visible;
m_mousePaintValue = m_layersInfo[item].visible;
OnModifyLayer( item );
}
else if (button == BUTTON_USABLE)
{
m_mousePaintFlags = (1<<31) | button;
m_layersInfo[item].usable = !m_layersInfo[item].usable;
m_mousePaintValue = m_layersInfo[item].usable;
OnModifyLayer( item );
} else if (button == BUTTON_EXPAND)
{
bNoSelect = true;
m_layersInfo[item].pLayer->Expand( !m_layersInfo[item].pLayer->IsExpanded() );
ReloadLayers();
}
if (!bNoSelect && (nFlags & MK_CONTROL))
{
// Can only drag removable layers.
if (m_layersInfo[item].pLayer->IsRemovable())
{
// Start dragging.
m_draggingItem = item;
CPoint pos;
GetCursorPos(&pos);
// Initialize the drag image (usually called from WM_LBUTTONDOWN).
m_imageList.BeginDrag( ITEM_LEAF_BITMAP, CPoint(-10,-10));
m_imageList.DragEnter( this,point );
SetCapture();
Invalidate();
}
}
}
return bNoSelect;
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!HandleMouseClick(nFlags,point))
CListBox::OnLButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::OnLButtonUp(UINT nFlags, CPoint point)
{
m_mousePaintFlags = 0;
if (m_draggingItem >= 0)
{
m_imageList.DragLeave( this );
m_imageList.EndDrag();
ReleaseCapture();
Invalidate();
BOOL bOutside;
// Find item where we clicked.
int item = ItemFromPoint( point,bOutside );
if (item != LB_ERR && !bOutside)
{
if (item != m_draggingItem)
{
SLayerInfo &src = m_layersInfo[m_draggingItem];
SLayerInfo &trg = m_layersInfo[item];
if (!trg.pLayer->IsChildOf(src.pLayer))
{
trg.pLayer->AddChild(src.pLayer);
trg.pLayer->Expand(true);
ReloadLayers();
}
m_draggingItem = -1;
}
}
else
{
SLayerInfo &src = m_layersInfo[m_draggingItem];
if (src.pLayer->GetParent())
{
src.pLayer->GetParent()->RemoveChild(src.pLayer);
ReloadLayers();
}
}
m_draggingItem = -1;
}
CListBox::OnLButtonUp(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
{
BOOL bOutside;
// Find item where we clicked.
int item = ItemFromPoint( point,bOutside );
if (item != LB_ERR && !bOutside)
{
int button = GetButtonFromPoint(point);
if (button < 0 || button == BUTTON_EXPAND)
{
// Toggle expand status.
m_layersInfo[item].pLayer->Expand( !m_layersInfo[item].pLayer->IsExpanded() );
ReloadLayers();
}
else if (button == BUTTON_VISIBLE)
{
CUndo undo("Layer Modify");
bool bValue = m_layersInfo[item].visible;
// Set all layers to this value.
std::vector<CObjectLayer*> layers;
GetIEditor()->GetObjectManager()->GetLayersManager()->GetLayers( layers );
for (int i = 0; i < layers.size(); i++)
{
layers[i]->SetVisible(bValue,!layers[i]->IsExpanded() );
}
ReloadLayers();
} else if (button == BUTTON_USABLE)
{
CUndo undo("Layer Modify");
bool bUsable = m_layersInfo[item].usable;
// Set all layers to this value.
std::vector<CObjectLayer*> layers;
GetIEditor()->GetObjectManager()->GetLayersManager()->GetLayers( layers );
for (int i = 0; i < layers.size(); i++)
{
layers[i]->SetFrozen(!bUsable,!layers[i]->IsExpanded());
}
ReloadLayers();
}
}
CListBox::OnLButtonDblClk(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::SetUpdateCallback( UpdateCallback &cb )
{
m_updateCalback = cb;
}
BOOL CLayersListBox::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if (!m_handCursor)
{
return CListBox::OnSetCursor(pWnd, nHitTest, message);
}
SetCursor( m_hHandCursor );
return TRUE;
}
void CLayersListBox::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_draggingItem >= 0)
{
CPoint pos = point;
ClientToScreen(&pos);
m_imageList.DragMove( point );
return;
}
int button = GetButtonFromPoint(point);
if (button >= 0)
{
m_handCursor = true;
}
else
m_handCursor = false;
if (m_mousePaintFlags != 0)
{
BOOL bOutside;
int item = ItemFromPoint( point,bOutside );
if ((item != LB_ERR && !bOutside) && (m_mousePaintFlags & 0xF) == button)
{
if (button == 0)
{
m_mousePaintFlags = (1<<31) | button;
if (m_layersInfo[item].visible != m_mousePaintValue)
{
m_layersInfo[item].visible = m_mousePaintValue;
OnModifyLayer( item );
}
}
else if (button == 1)
{
m_mousePaintFlags = (1<<31) | button;
if (m_layersInfo[item].usable != m_mousePaintValue)
{
m_layersInfo[item].usable = m_mousePaintValue;
OnModifyLayer( item );
}
}
}
}
CListBox::OnMouseMove(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::SelectLayer( const CString &layerName )
{
for (int i = 0; i < m_layersInfo.size(); i++)
{
if (stricmp(layerName,m_layersInfo[i].name) == 0)
{
SetCurSel(i);
break;
}
}
}
inline bool CompareLayers( CObjectLayer *l1,CObjectLayer *l2 )
{
return stricmp(l1->GetName(),l2->GetName()) < 0;
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::ReloadLayers()
{
if (m_noReload)
return;
/*
m_layersInfo.clear();
for (int i = 0; i < layers.size(); i++)
{
}
*/
m_layersInfo.clear();
CObjectLayerManager *pLayerManager = GetIEditor()->GetObjectManager()->GetLayersManager();
std::vector<CObjectLayer*> layers;
pLayerManager->GetLayers( layers );
std::sort( layers.begin(),layers.end(),CompareLayers );
for (int i = 0; i < layers.size(); i++)
{
CObjectLayer *pLayer = layers[i];
if (!pLayer)
continue;
if (pLayer->GetParent())
continue;
AddLayerRecursively( pLayer,0 );
}
ReloadListItems();
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::AddLayerRecursively( CObjectLayer *pLayer,int level )
{
CLayersListBox::SLayerInfo layerInfo;
layerInfo.name = pLayer->GetName();
layerInfo.visible = pLayer->IsVisible();
layerInfo.usable = !pLayer->IsFrozen();
layerInfo.pLayer = pLayer;
layerInfo.indent = level;
layerInfo.childs = pLayer->GetChildCount() != 0;
layerInfo.expanded = pLayer->IsExpanded();
m_layersInfo.push_back(layerInfo);
if (pLayer->IsExpanded())
{
int numLayers = pLayer->GetChildCount();
for (int i = 0; i < numLayers; i++)
{
CObjectLayer *pChild = pLayer->GetChild(i);
if (pChild)
AddLayerRecursively( pChild,level+1 );
if (i == numLayers-1)
{
m_layersInfo[m_layersInfo.size()-1].lastchild = true;
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::ReloadListItems()
{
CObjectLayerManager *pLayerManager = GetIEditor()->GetObjectManager()->GetLayersManager();
CString selectedLayerName = pLayerManager->GetCurrentLayer()->GetName();
int sel = LB_ERR;
SetRedraw(FALSE);
ResetContent();
for (int i = 0; i < m_layersInfo.size(); i++)
{
int id = AddString( m_layersInfo[i].name );
if (m_layersInfo[i].name == selectedLayerName)
sel = id;
SetItemData(id,i);
}
if (sel != LB_ERR)
{
SetCurSel(sel);
}
SetRedraw(TRUE);
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::OnModifyLayer( int index )
{
assert( index >= 0 && index < m_layersInfo.size() );
CUndo undo("Layer Modify");
m_noReload = true;
SLayerInfo &li = m_layersInfo[index];
bool bRecursive = !(li.pLayer->IsExpanded());
li.pLayer->SetVisible( li.visible,bRecursive );
li.pLayer->SetFrozen( !li.usable,bRecursive );
m_noReload = false;
CRect rcItem;
GetItemRect( index,rcItem );
InvalidateRect( rcItem );
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::OnRButtonDown(UINT nFlags, CPoint point)
{
m_rclickedItem = -1;
BOOL bOutside;
int item = ItemFromPoint( point,bOutside );
if (item != LB_ERR && !bOutside)
{
m_rclickedItem = item;
SetCurSel( item );
CObjectLayer *pLayer = GetCurrentLayer();
if (pLayer)
{
GetIEditor()->GetObjectManager()->GetLayersManager()->SetCurrentLayer( pLayer );
}
}
CListBox::OnRButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CLayersListBox::OnRButtonUp(UINT nFlags, CPoint point)
{
BOOL bOutside;
int item = ItemFromPoint( point,bOutside );
if (item != LB_ERR && !bOutside)
{
if (item == m_rclickedItem)
{
// Show context menu.
NMHDR hdr;
hdr.code = LBN_LAYERS_RBUTTON_UP;
hdr.hwndFrom = m_hWnd;
hdr.idFrom = GetDlgCtrlID();
LRESULT hres;
hres = GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&hdr) );
if (hres != 0)
{
m_rclickedItem = -1;
return;
}
}
}
m_rclickedItem = -1;
CListBox::OnRButtonUp(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
CObjectLayer* CLayersListBox::GetCurrentLayer()
{
int sel = GetCurSel();
if (sel != LB_ERR)
{
return m_layersInfo[sel].pLayer;
}
return 0;
}

View File

@@ -0,0 +1,120 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: layerslistbox.h
// Version: v1.00
// Created: 10/4/2002 by Timur.
// Compilers: Visual C++ 7.0
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __layerslistbox_h__
#define __layerslistbox_h__
#if _MSC_VER > 1000
#pragma once
#endif
#include "Objects\ObjectLayer.h"
#define LBN_LAYERS_RBUTTON_DOWN 10
#define LBN_LAYERS_RBUTTON_UP 11
// CLayersListBox dialog
/*!
* CLayerListBox is a special owner draw version of list box to display layers.
*/
class CLayersListBox : public CListBox
{
DECLARE_DYNAMIC(CLayersListBox)
public:
typedef Functor0 UpdateCallback;
struct SLayerInfo
{
CString name;
bool visible;
bool usable;
bool expanded;
bool childs;
bool lastchild;
TSmartPtr<CObjectLayer> pLayer;
int indent;
SLayerInfo()
{
childs = false;
expanded = false;
visible = false;
usable = false;
lastchild = false;
indent = 0;
}
};
typedef std::vector<SLayerInfo> Layers;
CLayersListBox(); // standard constructor
virtual ~CLayersListBox();
void ReloadLayers();
void SelectLayer( const CString &layerName );
CObjectLayer* GetCurrentLayer();
void SetUpdateCallback( UpdateCallback &cb );
DECLARE_MESSAGE_MAP()
afx_msg void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
afx_msg void MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/);
afx_msg int CompareItem( LPCOMPAREITEMSTRUCT lpCompareItemStruct );
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
protected:
virtual void PreSubclassWindow();
void Init();
//void UpdateLayers();
void AddLayerRecursively( CObjectLayer *pLayer,int level );
void ReloadListItems();
void OnModifyLayer( int index );
void PopupMenu( int item );
CRect GetButtonRect( CRect &rcItem,int id );
CRect GetButtonsFrame( CRect &rcItem );
CRect GetExpandButtonRect( int item );
void DrawCheckButton( CDC &dc,CRect &rcItem,int id,bool state );
int GetButtonFromPoint( CPoint point);
bool HandleMouseClick( UINT nFlags,CPoint point );
std::vector<SLayerInfo> m_layersInfo;
CImageList m_imageList;
int m_itemHeight;
UpdateCallback m_updateCalback;
HCURSOR m_hHandCursor;
bool m_handCursor;
bool m_noReload;
int m_mousePaintFlags;
bool m_mousePaintValue;
int m_draggingItem;
int m_rclickedItem;
CFont m_externalFont;
};
#endif // __layerslistbox_h__

152
Editor/Controls/MemDC.h Normal file
View File

@@ -0,0 +1,152 @@
//MemDC.h
#if _MSC_VER > 1000
#pragma once
#pragma pack(push)
#pragma pack(1)
#endif // _MSC_VER > 1000
#ifndef MemDCh
#define MemDCh
/*
This is a slightly optimised version of the popular CMemDC class.
For the fastest redraw put a bitmap in your Dialog, Control or View header:
CBitmap Bitmap;
In the .cpp file:
#include "MemDC.h"
and then call the following just once:
Bitmap.CreateCompatibleBitmap(pDC, Rect.Width(), Rect.Height());
For a Modal dialog call the above in OnInitDlg otherwise in your classe's contstructor.
If you don't have pDC use GetDC() which returns the DC of the screen.
If you're using OnPaint() use the following two lines:
CPaintDC PaintDC(this); // device context for painting
CMemDC dc(PaintDC, &Bitmap);
Then draw everything to dc - and thats it!
You don't need the Bitmap: you can just create the CMemDC with:
void CMyDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) {
CPaintDC PaintDC(this); // device context for painting
CMemDC dc(PaintDC);
it'll be slower for complex animations, but fine for most Controls.
The same applies to OwnerDraw Buttons, create the MemDC object as follows:
void CMemDCTesterDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) {
CMemDC dc(lpDrawItemStruct, &Bitmap);
Theres also a constructor for Views:
void CMyView::OnDraw(CDC* pDC) {
CMemDC dc(pDC, &Bitmap);
Remember the following tips:
if you're filling the background yourself:
Remember to either do it in OnEraseBkgnd or to not do it at all use:
BOOL CMyDlgOrControl::OnEraseBkgnd(CDC* pDC) {return TRUE;}
If you're filling it black or white use:
PatBlt(Rect.left, Rect.top, Rect.Width(), Rect.Height(), BLACKNESS);
or:
PatBlt(Rect.left, Rect.top, Rect.Width(), Rect.Height(), WHITENESS);
to fill with the current dialog background colour use:
dc.FillSolidRect(&Rect, GetSysColor(COLOR_3DFACE)); //Draw in dialogs background colour
To draw text using the same font as the dialog box use:
CGdiObject* OldFont=dc.SelectObject(GetParent()->GetFont());
then use dc.DrawText(...);
and finish with
dc.SelectObject(OldFont);
To draw using the system dialog font use:
CGdiObject* OldFont=dc.SelectStockObject(ANSI_VAR_FONT);
then use dc.DrawText(...);
and finish with
dc.SelectObject(&OldFont);
It is best to use a class to encapsulate the clean-up:
class CUseDialogFont {
CGdiObject* OldFont;
CDC* pDC;
public:
CUseDialogFont(CDC* _pDC) {pDC=_pDC; OldFont=pDC->SelectStockObject(ANSI_VAR_FONT);}
~CUseDialogFont() {pDC->SelectObject(&OldFont);}
};
Then in your code just use:
CUseDialogFont Font(&dc);
That way you can 'return' at any time safe in the knowledge that the original font will be selected.
*/
class CMemDC : public CDC {
public:
CMemDC(CPaintDC& dc, CBitmap* pBmp=NULL) : isMemDC(!dc.IsPrinting()) {
//if(dc.GetWindow()) (dc.GetWindow())->GetClientRect(&Rect);
//else
Rect = dc.m_ps.rcPaint;
Set(&dc, Paint, pBmp);
}
CMemDC(CDC* pDC, CBitmap* pBmp=NULL) {
isMemDC=!pDC->IsPrinting();
if(isMemDC) {
pDC->GetClipBox(&Rect); //For Views
pDC->LPtoDP(&Rect);
}
Set(pDC, Draw, pBmp);
}
CMemDC(LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap* pBmp=NULL) : isMemDC(true) {
Rect=lpDrawItemStruct->rcItem;
Set(CDC::FromHandle(lpDrawItemStruct->hDC), DrawItem, pBmp);
}
~CMemDC() { // Destructor copies the contents of the mem DC to the original DC
if(isMemDC) {
pDC->BitBlt(Rect.left, Rect.top, Rect.Width(), Rect.Height(), this, Rect.left, Rect.top, SRCCOPY);
SelectObject(OldBitmap);
}
}
CMemDC* operator->() {return this;} // Allow usage as a pointer
operator CMemDC*() {return this;} // Allow usage as a pointer
private:
enum dcType {Paint,Draw,DrawItem};
void Set(CDC* _pDC, dcType Type, CBitmap* pBmp=NULL) {
ASSERT_VALID(_pDC);
pDC=_pDC;
OldBitmap=NULL;
if(isMemDC) {
CreateCompatibleDC(pDC);
if(pBmp!=NULL) OldBitmap=SelectObject(pBmp); //User passed bitmap, use it
else { //Create our own bitmap
CRect rc;
pDC->GetWindow()->GetClientRect(rc);
Bitmap.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
OldBitmap=SelectObject(&Bitmap);
}
if(Type==Draw) {
SetMapMode(pDC->GetMapMode());
pDC->DPtoLP(&Rect);
SetWindowOrg(Rect.left, Rect.top);
}
}else{ // Make a copy of the relevent parts of the current DC for printing
m_bPrinting=pDC->m_bPrinting;
m_hDC=pDC->m_hDC;
m_hAttribDC=pDC->m_hAttribDC;
}
}
CBitmap Bitmap; // Offscreen bitmap
CBitmap* OldBitmap; // bitmap originally found in CMemDC
CDC* pDC; // Saves CDC passed in constructor
CRect Rect; // Rectangle of drawing area.
bool isMemDC; // TRUE if CDC really is a Memory DC.
};
#if _MSC_VER >= 1000
#pragma pack(pop)
#endif // _MSC_VER >= 1000
#endif //ndef MemDCh

View File

@@ -0,0 +1,888 @@
// MltiTree.cpp : implementation file
// Copyright (c) 1999 Richard Hazlewood
// This code is provided as-is. Use at your own peril.
//
// Multi-selection tree. Based, for the most part, on the
// selection behaviour of the listview control.
// TVN_SELCHANGING/TVN_SELCHANGED notifications are used
// throughout: itemOld For de-selection, itemNew for selection.
// Note: TVN_SELCHANGING/TVN_SELCHANGED are still sent by default
// tree processing for focus changes, i.e. a SetItemState passed
// TVIS_FOCUSED without TVIS_SELECTED will still cause notification
// (if not already focused)
//Decoding in TVN_SELCHANGED:
//B = IsEmulatedNotify
//O = itemOld.hItem != 0
//N = itemNew.hItem != 0
//
//B O N
//~~~~~~~
//0 1 0 A focus loss on itemOld
//0 0 1 A focus/selection gain on itemNew
//0 1 1 A focus loss on itemOld, a focus/selection gain on itemNew
//1 1 0 A selection loss on itemOld
//1 0 1 A selection gain on itemNew
//else undefined
#include "stdafx.h"
#include <windowsx.h>
#include "MltiTree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
#ifndef MST_TIMER_PERIOD
#define MST_TIMER_PERIOD 75 //ms
#endif
/////////////////////////////////////////////////////////////////////////////
// CMultiTree
IMPLEMENT_DYNAMIC(CMultiTree, CMultiTree_BASE)
CMultiTree::CMultiTree()
{
m_bMulti = TRUE;
m_hSelect = NULL;
m_bBandLabel = FALSE;
m_bEmulated = FALSE;
}
CMultiTree::~CMultiTree()
{
}
#define CTreeCtrl CMultiTree_BASE
BEGIN_MESSAGE_MAP(CMultiTree, CTreeCtrl)
#undef CTreeCtrl
//{{AFX_MSG_MAP(CMultiTree)
ON_WM_LBUTTONDOWN()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_RBUTTONDOWN()
ON_NOTIFY_REFLECT_EX(TVN_ITEMEXPANDING, OnItemExpanding)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMultiTree message handlers
/////////////////////////////////////////////////////////////////////////////
// GetSelectedCount
// - returns number of selection tree items
UINT CMultiTree::GetSelectedCount() const
{
UINT nCount = 0;
HTREEITEM hItem = GetFirstSelectedItem();
while (hItem) {
nCount++;
hItem = GetNextSelectedItem(hItem);
}
return nCount;
}
/////////////////////////////////////////////////////////////////////////////
// SetMultiSelect
// - allow mode to be turned off
BOOL CMultiTree::SetMultiSelect(BOOL bMulti)
{
BOOL b = m_bMulti;
m_bMulti = bMulti;
if (!m_bMulti) {
HTREEITEM hItem = GetSelectedItem();
if (hItem && !IsSelected(hItem))
hItem = NULL;
SelectAllIgnore(FALSE, hItem);
if (hItem)
SelectItem(hItem);
}
return b;
}
/////////////////////////////////////////////////////////////////////////////
// SetItemState
// - replacement to handle TVIS_FOCUSED
BOOL CMultiTree::SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask)
{
ASSERT(hItem);
if (!m_bMulti)
return CMultiTree_BASE::SetItemState(hItem, nState, nStateMask);
HTREEITEM hFocus = GetSelectedItem(); //current focus
BOOL bWasFocus = (hFocus == hItem);
BOOL bFocusWasSel = hFocus && IsSelected(hFocus); //selection state of current focus
BOOL bWasSel = IsSelected(hItem); //select state of acting item
UINT nS = nState & ~TVIS_FOCUSED;
UINT nSM = nStateMask & ~TVIS_FOCUSED;
if (nStateMask & TVIS_FOCUSED) {
//wanted to affect focus
if (nState & TVIS_FOCUSED) {
//wanted to set focus
if (!bWasFocus && bFocusWasSel) {
//because SelectItem would de-select the current 'real' selection
// (the one with focus), need to make the tree ctrl think there is
// no 'real' selection but still keep the the old item selected
//it has to be done before the SelectItem call because
// otherwise the TVN_SELCHANGING/ED notification handlers
// wouldn't be able to get the proper list of selected items
CMultiTree_BASE::SelectItem(NULL); //will cause notify, but can be taken as focus change
CMultiTree_BASE::SetItemState(hFocus, TVIS_SELECTED, TVIS_SELECTED);
UpdateWindow();
}
if (!CMultiTree_BASE::SelectItem(hItem)) //set focus (will consequently select, if not already focused)
return FALSE;
if (nStateMask & TVIS_SELECTED) {
//wanted to affect select state
if (nState & TVIS_SELECTED) {
//wanted to select, already done if wasn't focused
if (!bWasFocus || bFocusWasSel) {
nS &= ~TVIS_SELECTED;
nSM &= ~TVIS_SELECTED;
}
}
//else wanted to clear, base call will do that
}
else {
//didn't want to affect select state
if (!bWasSel) {
//it wasn't previously selected, let base clear (correct)
nS &= ~TVIS_SELECTED;
nSM |= TVIS_SELECTED;
}
//else was already selected, no harm done
}
}
else {
//wanted to clear focus
if (bWasFocus) {
//it had the focus
CMultiTree_BASE::SelectItem(NULL); //clear focus
if (!(nStateMask & TVIS_SELECTED)) {
//didn't want to affect select state
if (bWasSel) {
//it was selected, so restore
ASSERT( !(nS & TVIS_SELECTED) );
ASSERT( !(nSM & TVIS_SELECTED) );
//set state here, to avoid double-notify
CMultiTree_BASE::SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
//let base do other states
}
}
else if (nState & TVIS_SELECTED) {
//wanted to select (but clear focus)
if (bWasSel) {
//if was selected, restore
CMultiTree_BASE::SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
}
//don't want to notify, default did it
nS &= ~TVIS_SELECTED;
nSM &= ~TVIS_SELECTED;
}
}
}
}
if (!nSM)
return TRUE; //no other states to alter
if (nSM & TVIS_SELECTED) {
//still need to alter selection state
NMTREEVIEW nmtv;
nmtv.hdr.hwndFrom = m_hWnd;
nmtv.hdr.idFrom = ::GetDlgCtrlID(m_hWnd);
nmtv.hdr.code = TVN_SELCHANGING;
nmtv.itemOld.mask = nmtv.itemNew.mask = 0;
nmtv.itemOld.hItem = nmtv.itemNew.hItem = NULL;
TVITEM& item = (nS & TVIS_SELECTED) ? nmtv.itemNew : nmtv.itemOld;
item.mask = TVIF_HANDLE|TVIF_PARAM;
item.hItem = hItem;
item.lParam = GetItemData(hItem);
if (_SendNotify(&nmtv.hdr))
return FALSE; //sel-changing stopped
VERIFY( CMultiTree_BASE::SetItemState(hItem, nS, nSM) );
nmtv.hdr.code = TVN_SELCHANGED;
_SendNotify(&nmtv.hdr);
nS &= ~TVIS_SELECTED;
nSM &= ~TVIS_SELECTED;
}
if (!nSM)
return TRUE;
return CMultiTree_BASE::SetItemState(hItem, nS, nSM);
}
UINT CMultiTree::GetItemState(HTREEITEM hItem, UINT nStateMask) const
{
UINT n = CMultiTree_BASE::GetItemState(hItem, nStateMask & ~TVIS_FOCUSED);
if (nStateMask & TVIS_FOCUSED)
if (GetSelectedItem() == hItem)
n |= TVIS_FOCUSED;
return n;
}
BOOL CMultiTree::SelectItem(HTREEITEM hItem)
{
if (m_bMulti) {
//TRACE(_T("Use SetItemState or FocusItem when in multi-select mode\n"));
ASSERT(FALSE);
}
return CMultiTree_BASE::SelectItem(hItem);
}
BOOL CMultiTree::FocusItem(HTREEITEM hItem)
{
ASSERT(m_bMulti);
BOOL bRet = FALSE;
if (hItem)
bRet = SetItemState(hItem, TVIS_FOCUSED, TVIS_FOCUSED);
else {
hItem = CMultiTree_BASE::GetSelectedItem();
if (hItem)
bRet = SetItemState(hItem, 0, TVIS_FOCUSED);
}
return bRet;
}
/////////////////////////////////////////////////////////////////////////////
// _SendNotify
// - helper to distinguish between default control generated notifications
// and this classes emulated ones (so can tell if focus or select notify)
BOOL CMultiTree::_SendNotify(LPNMHDR pNMHDR)
{
ASSERT(::GetParent(m_hWnd)); //never expected this
BOOL b = m_bEmulated;
m_bEmulated = TRUE;
BOOL bRes = ::SendMessage(::GetParent(m_hWnd), WM_NOTIFY, (WPARAM)pNMHDR->idFrom, (LPARAM)pNMHDR);
m_bEmulated = b;
return bRes;
}
/////////////////////////////////////////////////////////////////////////////
// Selection Parsing
HTREEITEM CMultiTree::GetFirstSelectedItem() const
{
HTREEITEM hItem = GetRootItem();
while (hItem) {
if (IsSelected(hItem))
break;
hItem = GetNextVisibleItem(hItem);
}
return hItem;
}
HTREEITEM CMultiTree::GetNextSelectedItem(HTREEITEM hItem) const
{
hItem = GetNextVisibleItem(hItem);
while (hItem) {
if (IsSelected(hItem))
break;
hItem = GetNextVisibleItem(hItem);
}
return hItem;
}
void CMultiTree::SelectAll(BOOL bSelect /*= TRUE*/)
{
bSelect = !!bSelect; //ensure 0 or 1
UINT nState = bSelect ? TVIS_SELECTED : 0;
HTREEITEM hItem = GetRootItem();
while (hItem) {
if (IsSelected(hItem) != bSelect)
SetItemState(hItem, nState, TVIS_SELECTED);
hItem = GetNextVisibleItem(hItem);
}
}
void CMultiTree::SelectAllIgnore(BOOL bSelect, HTREEITEM hIgnore)
{
//special case to avoid multiple notifications for
// the same item
bSelect = !!bSelect; //ensure 0 or 1
UINT nState = bSelect ? TVIS_SELECTED : 0;
HTREEITEM hItem = GetRootItem();
while (hItem) {
if (hItem != hIgnore)
if (IsSelected(hItem) != bSelect)
SetItemState(hItem, nState, TVIS_SELECTED);
hItem = GetNextVisibleItem(hItem);
}
}
void CMultiTree::SelectRange(HTREEITEM hFirst, HTREEITEM hLast, BOOL bOnly /*= TRUE*/)
{
//locate (and select) either first or last
// (so order is arbitrary)
HTREEITEM hItem = GetRootItem();
while (hItem) {
if ((hItem == hFirst) || (hItem == hLast)) {
if (hFirst != hLast) {
if (!IsSelected(hItem))
SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
hItem = GetNextVisibleItem(hItem);
}
break;
}
if (bOnly && IsSelected(hItem))
SetItemState(hItem, 0, TVIS_SELECTED);
hItem = GetNextVisibleItem(hItem);
}
//select rest of range
while (hItem) {
if (!IsSelected(hItem))
SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
if ((hItem == hFirst) || (hItem == hLast)) {
hItem = GetNextVisibleItem(hItem);
break;
}
hItem = GetNextVisibleItem(hItem);
}
if (!bOnly)
return;
while (hItem) {
if (IsSelected(hItem))
SetItemState(hItem, 0, TVIS_SELECTED);
hItem = GetNextVisibleItem(hItem);
}
}
/////////////////////////////////////////////////////////////////////////////
// OnButtonDown
#define _bShift (nFlags & MK_SHIFT)
#define _bCtrl (nFlags & MK_CONTROL)
void CMultiTree::OnLButtonDown(UINT nFlags, CPoint point)
{
OnButtonDown(TRUE, nFlags, point);
}
void CMultiTree::OnRButtonDown(UINT nFlags, CPoint point)
{
OnButtonDown(FALSE, nFlags, point);
}
void CMultiTree::OnButtonDown(BOOL bLeft, UINT nFlags, CPoint point)
{
UINT nHF;
HTREEITEM hItem;
//if (::GetFocus() != m_hWnd)
//::SetFocus(m_hWnd);
BOOL bBase = !m_bMulti;
if (!bBase) {
hItem = HitTest(point, &nHF);
if (hItem) {
//base always handles expanding items
//(doesn't really mean much to right button, but pass anyway)
bBase = (nHF & (TVHT_ONITEMBUTTON/*|TVHT_ONITEMINDENT*/));
if (!bBase && bLeft && (GetStyle() & TVS_CHECKBOXES)) {
//when the tree has check-boxes, the default handler makes
// a quick selection of the clicked item, then re-selects
// the previously selected item - to cause a sel-changed
// notification. Fortunately it doesn't affect the multi-
// selection, so can pass on.
bBase = (nHF & TVHT_ONITEMSTATEICON);
#ifdef _MST_MULTI_CHECK
//Use the above define if you want all selected items to
// be checked the same when any one of them is checked
// - Interestingly this doesn't happen in the listview control
// (LVS_EX_CHECKBOXES)
if (bBase) {
//the default selection notification would mess
// the multi-selection up, so generate the notification
// manually
// (anyway, this is smoother than the selection flicker
// the default gives)
NMTREEVIEW nmtv;
#ifdef TVN_CHKCHANGE
nmtv.hdr.code = TVN_CHKCHANGE;
#else
nmtv.hdr.code = TVN_SELCHANGED;
#endif
nmtv.hdr.hwndFrom = m_hWnd;
nmtv.hdr.idFrom = ::GetDlgCtrlID(m_hWnd);
nmtv.itemOld.hItem = NULL;
nmtv.itemNew.mask = TVIF_HANDLE|TVIF_PARAM;
BOOL bChk = !GetCheck(hItem);
if (IsSelected(hItem)) {
HTREEITEM h = GetFirstSelectedItem();
while (h) {
if (!GetCheck(h) == bChk) { //! to ensure 0 or 1
SetCheck(h, bChk);
#ifdef TVN_CHKCHANGE
//only send multiple check-change
// notifications (not sel-changed)
if (h != hItem) { //clicked item will be done last
nmtv.itemNew.hItem = h;
nmtv.itemNew.lParam = GetItemData(h);
_SendNotify(&nmtv.hdr);
}
#endif
}
h = GetNextSelectedItem(h);
}
}
else
SetCheck(hItem, bChk);
//notify clicked item
nmtv.itemNew.hItem = hItem;
nmtv.itemNew.lParam = GetItemData(hItem);
_SendNotify(&nmtv.hdr);
return;
}
#endif
}
}
}
if (bBase) {
if (bLeft)
CMultiTree_BASE::OnLButtonDown(nFlags, point);
else
CMultiTree_BASE::OnRButtonDown(nFlags, point);
return;
}
if (!hItem || (nHF & (TVHT_ONITEMRIGHT|TVHT_NOWHERE|TVHT_ONITEMINDENT))) {
//clicked in space, do rubber-banding
DoBanding(bLeft, nFlags, point);
return;
}
ASSERT(nHF & (TVHT_ONITEM|TVHT_ONITEMSTATEICON) ); //nothing else left
DoPreSelection(hItem, bLeft, nFlags);
DoAction(hItem, bLeft, nFlags, point);
}
void CMultiTree::DoPreSelection(HTREEITEM hItem, BOOL bLeft, UINT nFlags)
{
if (bLeft) {
//if shift key down, select immediately
if (_bShift) {
if (!m_hSelect)
m_hSelect = GetSelectedItem(); //focus
SelectRange(m_hSelect, hItem, !_bCtrl);
SetItemState(hItem, TVIS_FOCUSED, TVIS_FOCUSED); //focus changes to last clicked
}
else {
if (!_bCtrl) {
//if ctrl was down, then the selection is delayed until
// mouse up, otherwise select the one item
if (!IsSelected(hItem))
SelectAllIgnore(FALSE, hItem);
SetItemState(hItem, TVIS_SELECTED|TVIS_FOCUSED, TVIS_SELECTED|TVIS_FOCUSED);
}
m_hSelect = NULL; //reset when a non-shift operation occurs
}
return;
}
//right mouse
if (nFlags & (MK_CONTROL|MK_SHIFT)) {
if (!_bShift)
m_hSelect = hItem;
return; //do nothing if shift or ctrl
}
if (!IsSelected(hItem))
SelectAllIgnore(FALSE, hItem);
SetItemState(hItem, TVIS_SELECTED|TVIS_FOCUSED, TVIS_SELECTED|TVIS_FOCUSED);
}
void CMultiTree::DoAction(HTREEITEM hItem, BOOL bLeft, UINT nFlags, CPoint point)
{
::SetCapture(m_hWnd);
ASSERT(::GetCapture() == m_hWnd);
MSG msg;
UINT nDone = 0;
CPoint pt;
CSize sizeDrag(::GetSystemMetrics(SM_CXDRAG), ::GetSystemMetrics(SM_CYDRAG));
while (!nDone && ::GetMessage(&msg, NULL, 0, 0)) {
if (::GetCapture() != m_hWnd)
break;
switch (msg.message) {
case WM_MOUSEMOVE:
pt.x = GET_X_LPARAM(msg.lParam);
pt.y = GET_Y_LPARAM(msg.lParam);
if ((abs(pt.x - point.x) > sizeDrag.cx)
|| ((abs(pt.y - point.y) > sizeDrag.cy)) )
nDone = 2;
//because we exit loop, button up will still be dispatched
// which means WM_CONTEXTMENU will be sent after TVN_BEGINRDRAG
// - this is the same behaviour as original tree
break;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
nDone = 1;
break;
default:
::DispatchMessage(&msg);
break;
}
}
::ReleaseCapture();
ASSERT(::GetCapture() != m_hWnd);
//construct tree notification info
NMTREEVIEW nmtv;
nmtv.hdr.hwndFrom = m_hWnd;
nmtv.hdr.idFrom = ::GetDlgCtrlID(m_hWnd);
nmtv.itemNew.mask = TVIF_HANDLE|TVIF_PARAM;
nmtv.itemNew.hItem = hItem;
nmtv.itemNew.lParam = GetItemData(hItem);
DWORD dwStyle = GetStyle();
if (nDone == 1) {
//click
if (!_bShift && bLeft) {
UINT nState = TVIS_SELECTED;
if (_bCtrl)
nState ^= (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED);
else
SelectAllIgnore(FALSE, hItem);
SetItemState(hItem, TVIS_FOCUSED|nState, TVIS_FOCUSED|TVIS_SELECTED);
}
if (::GetFocus() != m_hWnd)
::SetFocus(m_hWnd);
nmtv.hdr.code = bLeft ? NM_CLICK : NM_RCLICK;
_SendNotify(&nmtv.hdr);
}
else if (nDone == 2) {
//drag
SetItemState(hItem, TVIS_FOCUSED|TVIS_SELECTED, TVIS_FOCUSED|TVIS_SELECTED);
if (!(dwStyle & TVS_DISABLEDRAGDROP)) {
nmtv.hdr.code = bLeft ? TVN_BEGINDRAG : TVN_BEGINRDRAG;
nmtv.ptDrag = point;
_SendNotify(&nmtv.hdr);
}
}
}
void CMultiTree::DoBanding(BOOL bLeft, UINT nFlags, CPoint point)
{
if (::GetFocus() != m_hWnd)
::SetFocus(m_hWnd);
::SetCapture(m_hWnd);
CTreeItemList list;
if (nFlags & (MK_SHIFT|MK_CONTROL))
GetSelectedList(list);
CClientDC dc(this);
CRect rectCli;
GetClientRect(&rectCli);
MSG msg;
BOOL bDone = FALSE;
CPoint pt;
CSize sizeDrag(::GetSystemMetrics(SM_CXDRAG), ::GetSystemMetrics(SM_CYDRAG));
BOOL bDrag = FALSE;
CSize sizeEdge(1, 1);
UINT nTimer = SetTimer(1, MST_TIMER_PERIOD, NULL); //for scroll
CPoint ptScr(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
CRect rect(0, 0, 0, 0);
UINT h = 0;
HTREEITEM hItem = GetRootItem();
if (hItem) {
GetItemRect(hItem, &rect, FALSE);
ptScr.y *= (h = rect.Height()); //this assumes equal height items
}
point += ptScr;
while (!bDone && ::GetMessage(&msg, NULL, 0, 0)) {
if (::GetCapture() != m_hWnd)
break;
switch (msg.message) {
case WM_TIMER:
pt = msg.pt;
ScreenToClient(&pt);
if (rectCli.PtInRect(pt)) {
::DispatchMessage(&msg);
break;
}
msg.lParam = MAKELPARAM(pt.x, pt.y);
//fall through to mousemove
case WM_MOUSEMOVE:
pt.x = GET_X_LPARAM(msg.lParam);
pt.y = GET_Y_LPARAM(msg.lParam);
if (!bDrag) {
if ((abs(pt.x - point.x) <= sizeDrag.cx)
&& ((abs(pt.y - point.y) <= sizeDrag.cy)) )
break;
bDrag = TRUE;
if (!(nFlags & (MK_CONTROL|MK_SHIFT)))
SelectAll(FALSE);
UpdateWindow();
rect.SetRect(point, point);
dc.DrawDragRect(rect, sizeEdge, NULL, sizeEdge);
}
dc.DrawDragRect(rect, sizeEdge, NULL, sizeEdge); //delete
if (pt.y < rectCli.top)
::SendMessage(m_hWnd, WM_VSCROLL, SB_LINEUP, 0);
else if (pt.y >= rectCli.bottom)
::SendMessage(m_hWnd, WM_VSCROLL, SB_LINEDOWN, 0);
if (pt.x < rectCli.left)
::SendMessage(m_hWnd, WM_HSCROLL, SB_LINELEFT, 0);
else if (pt.x >= rectCli.right)
::SendMessage(m_hWnd, WM_HSCROLL, SB_LINERIGHT, 0);
ptScr = point;
ptScr.x -= GetScrollPos(SB_HORZ);
ptScr.y -= GetScrollPos(SB_VERT) * h;
rect.SetRect(ptScr, pt);
rect.NormalizeRect();
UpdateSelectionForRect(rect, nFlags, list);
dc.DrawDragRect(rect, sizeEdge, NULL, sizeEdge); //draw
break;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
bDone = TRUE;
break;
case WM_KEYDOWN:
if (LOWORD(msg.wParam) == VK_ESCAPE) {
SelectAll(FALSE);
bDone = TRUE;
break;
}
//dispatch
default:
::DispatchMessage(&msg);
break;
}
}
KillTimer(nTimer);
::ReleaseCapture();
if (bDrag)
dc.DrawDragRect(rect, sizeEdge, NULL, sizeEdge);
else
if (!(nFlags & (MK_CONTROL|MK_SHIFT)))
SelectAll(FALSE);
//construct notification info
NMHDR hdr;
hdr.hwndFrom = m_hWnd;
hdr.idFrom = ::GetDlgCtrlID(m_hWnd);
hdr.code = bLeft ? NM_CLICK : NM_RCLICK;
_SendNotify(&hdr);
//when banding, make sure we receive WM_CONTEXTMENU
// every time - which is what the listview ctrl does
::DispatchMessage(&msg);
}
void CMultiTree::UpdateSelectionForRect(LPCRECT pRect, UINT nFlags, CTreeItemList& list)
{
CRect rect;
BOOL bSel;
POSITION pos;
HTREEITEM hItem = GetRootItem();
while (hItem) {
bSel = IsSelected(hItem);
GetItemRect(hItem, &rect, m_bBandLabel);
if (rect.IntersectRect(rect, pRect)) {
//item in rect
pos = list.Find(hItem);
if (!bSel && !pos)
SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
else if (_bCtrl && pos)
SetItemState(hItem, 0, TVIS_SELECTED);
else if (_bShift && pos)
list.RemoveAt(pos); //if shift and in rect, don't lock anymore
}
else {
//item not in rect
pos = list.Find(hItem);
if (bSel && !pos)
SetItemState(hItem, 0, TVIS_SELECTED);
else if (pos)
SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
}
hItem = GetNextVisibleItem(hItem);
}
UpdateWindow();
}
void CMultiTree::OnSetFocus(CWnd* pOldWnd)
{
CMultiTree_BASE::OnSetFocus(pOldWnd);
if (m_bMulti) {
//'emulated' selected items will remain greyed
// if application gets covered
HTREEITEM hItem = GetFirstSelectedItem();
RECT rect;
while (hItem) {
GetItemRect(hItem, &rect, TRUE);
InvalidateRect(&rect);
hItem = GetNextSelectedItem(hItem);
}
}
}
void CMultiTree::OnKillFocus(CWnd* pNewWnd)
{
CMultiTree_BASE::OnKillFocus(pNewWnd);
if (m_bMulti) {
//'emulated' selected items may not get
// refreshed to grey
HTREEITEM hItem = GetFirstSelectedItem();
RECT rect;
while (hItem) {
GetItemRect(hItem, &rect, TRUE);
InvalidateRect(&rect);
hItem = GetNextSelectedItem(hItem);
}
}
}
BOOL CMultiTree::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
if (!m_bMulti)
return FALSE;
LPNMTREEVIEW pNMTreeView = (LPNMTREEVIEW)pNMHDR;
*pResult = 0;
if ((pNMTreeView->action == TVE_COLLAPSE) || (pNMTreeView->action == TVE_COLLAPSERESET)) {
//clear selection of children, it would be confusing otherwise
// - the notifications can be over-ridden to stop the de-selection
// if required
//unfortunately, the parent window can't over-ride this functionality
// because MFC gives this class first crack. So if changes are required
// a derived class will have to be used..
ASSERT(pNMTreeView->itemNew.hItem);
//if a descendent item has focus the parent will get selected as a
// consequence of collapsing the tree, so preserve
// (if the parent was already selected it will gain focus, but
// that's acceptable)
BOOL bWasSel = IsSelected(pNMTreeView->itemNew.hItem);
BOOL bWasFocus = SelectChildren(pNMTreeView->itemNew.hItem, FALSE, TRUE);
if (bWasFocus && !bWasSel)
CMultiTree_BASE::SelectItem(NULL); //stop parent from gaining selection
}
return FALSE; //pass to parent
}
BOOL CMultiTree::SelectChildren(HTREEITEM hParent, BOOL bSelect /*= TRUE*/, BOOL bRecurse /*= TRUE*/)
{
UINT nS = bSelect ? TVIS_SELECTED : 0;
BOOL bFocusWasInHere = FALSE;
HTREEITEM hItem = GetNextItem(hParent, TVGN_CHILD);
while (hItem) {
UINT nState = GetItemState(hItem, TVIS_SELECTED|TVIS_EXPANDED|TVIS_FOCUSED);
if ((nState & TVIS_SELECTED) != nS)
SetItemState(hItem, nS, TVIS_SELECTED);
bFocusWasInHere |= (nState & TVIS_FOCUSED);
if (bRecurse && (nState & TVIS_EXPANDED))
bFocusWasInHere |= SelectChildren(hItem, bSelect, bRecurse);
hItem = GetNextSiblingItem(hItem);
}
return bFocusWasInHere;
}
void CMultiTree::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (!m_bMulti) {
CMultiTree_BASE::OnKeyDown(nChar, nRepCnt, nFlags);
return;
}
BOOL bCtrl = (GetKeyState(VK_CONTROL) & 0x8000);
BOOL bShift = (GetKeyState(VK_SHIFT) & 0x8000);
BOOL bDir = FALSE;
HTREEITEM hSel = NULL;
switch (nChar) {
case VK_UP:
bDir = TRUE;
case VK_DOWN:
//common
hSel = GetSelectedItem();
if (!m_hSelect)
m_hSelect = hSel;
if (!bCtrl && !bShift) {
m_hSelect = NULL; //reset
SelectAll(FALSE);
}
break;
// case VK_SPACE:
// hSel = GetSelectedItem();
// if (hSel) {
// BOOL b = IsSelected(hSel);
// if (bCtrl)
// SetItemState(hSel, b ? 0 : TVIS_SELECTED, TVIS_SELECTED);
// else if (!b)
// SetItemState(hSel, TVIS_SELECTED, TVIS_SELECTED);
// }
// return; //don't call base class (it would start a search on the char)
//TODO: the text search isn't stopped by this ^. It may be done in the TranslateMessage,
// so would have to trap PreTranslateMessage to avoid it. If 'space' selection is
// required then need to implement - I'm not bothered.
}
CMultiTree_BASE::OnKeyDown(nChar, nRepCnt, nFlags);
if (!hSel || (!bCtrl && !bShift) )
return;
HTREEITEM hNext = bDir ? GetPrevVisibleItem(hSel) : GetNextVisibleItem(hSel);
if (!hNext)
hNext = hSel;
if (bShift)
SelectRange(m_hSelect, hNext, TRUE);
else if (bCtrl)
SetItemState(hNext, TVIS_FOCUSED, TVIS_FOCUSED);
}
void CMultiTree::GetSelectedList(CTreeItemList& list) const
{
list.RemoveAll();
HTREEITEM hItem = GetFirstSelectedItem();
while (hItem) {
list.AddTail(hItem);
hItem = GetNextSelectedItem(hItem);
}
}

148
Editor/Controls/MltiTree.h Normal file
View File

@@ -0,0 +1,148 @@
#if !defined(AFX_MLTITREE_H__9F4750E5_C512_11D2_880A_02608C7CB3EE__INCLUDED_)
#define AFX_MLTITREE_H__9F4750E5_C512_11D2_880A_02608C7CB3EE__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// MltiTree.h : header file
// Copyright (c) 1999 Richard Hazlewood
// This code is provided as-is. Use at your own peril.
#include <afxtempl.h>
#include "TreeCtrlEx.h"
// Editor defines
#define _MST_TVN_CHKCHANGE
#define CMultiTree_BASE CTreeCtrlEx
/////////////////////////////////////////////////////////////////////////////
//take the liberty of using 1 for focused item - it used
// to be defined anyway, before MS removed it.
#ifndef TVIS_FOCUSED
#define TVIS_FOCUSED 1
#else
#if TVIS_FOCUSED != 1
#error TVIS_FOCUSED was assumed to be 1
#endif
#endif
//define for custom notification
// sent on check-box change
// (Care: may clash in future)
#ifdef _MST_TVN_CHKCHANGE
#ifndef _MST_MULTI_CHECK
#define _MST_MULTI_CHECK //implied
#endif
#ifndef TVN_CHKCHANGE
#define TVN_CHKCHANGEA (TVN_FIRST-49)
#define TVN_CHKCHANGEW (TVN_FIRST-(49+49))
#ifdef UNICODE
#define TVN_CHKCHANGE TVN_CHKCHANGEW
#else
#define TVN_CHKCHANGE TVN_CHKCHANGEA
#endif
#endif //!TVN_CHKCHANGE
#endif //_MST_TVN_CHKCHANGE
typedef CTypedPtrList<CPtrList, HTREEITEM> CTreeItemList;
/////////////////////////////////////////////////////////////////////////////
// CMultiTree window
#ifndef MST_AFX_EXT_CLASS
#define MST_AFX_EXT_CLASS
//define this if building class for DLL export/import
// typically: #define MST_AFX_EXT_CLASS AFX_EXT_CLASS
#endif
#ifndef CMultiTree_BASE
#define CMultiTree_BASE CTreeCtrl
#endif
class MST_AFX_EXT_CLASS CMultiTree : public CMultiTree_BASE
{
DECLARE_DYNAMIC(CMultiTree)
// Construction
public:
CMultiTree();
// Attributes
public:
// Operations
public:
UINT GetSelectedCount() const;
HTREEITEM GetFirstSelectedItem() const;
HTREEITEM GetNextSelectedItem(HTREEITEM hItem) const;
void SelectAll(BOOL bSelect = TRUE); //doesn't affect focus
void SelectRange(HTREEITEM hFirst, HTREEITEM hLast, BOOL bOnly = TRUE);
BOOL IsSelected(HTREEITEM hItem) const {return !!(TVIS_SELECTED & CMultiTree_BASE::GetItemState(hItem, TVIS_SELECTED));};
//SelectChildren returns TRUE if focus was on a child item
BOOL SelectChildren(HTREEITEM hParent, BOOL bSelect = TRUE, BOOL bRecurse = TRUE);
//Note: not virtual, so must call this class (or derivative)
BOOL SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask);
UINT GetItemState(HTREEITEM hItem, UINT nStateMask) const;
BOOL SelectItem(HTREEITEM hItem);
//Note: GetSelectedItem should be taken as GetFocusedItem
// when in multi-select mode
HTREEITEM GetFocusedItem() const {ASSERT(m_bMulti);return CMultiTree_BASE::GetSelectedItem();};
BOOL FocusItem(HTREEITEM hItem);
BOOL SetMultiSelect(BOOL bMulti);
BOOL IsMultiSelect() const {return m_bMulti;};
BOOL IsEmulatedNotify() const {return m_bEmulated;};
BOOL SetBandingHit(BOOL bLabel) {BOOL b=m_bBandLabel;m_bBandLabel=bLabel;return b;};
void GetSelectedList(CTreeItemList& list) const;
protected:
BOOL m_bMulti;
HTREEITEM m_hSelect; //for shift selection
BOOL m_bEmulated;
BOOL m_bBandLabel;
protected:
void OnButtonDown(BOOL bLeft, UINT nFlags, CPoint point);
void DoPreSelection(HTREEITEM hItem, BOOL bLeft, UINT nFlags);
void DoAction(HTREEITEM hItem, BOOL bLeft, UINT nFlags, CPoint point);
void DoBanding(BOOL bLeft, UINT nFlags, CPoint point);
void UpdateSelectionForRect(LPCRECT pRect, UINT nFlags, CTreeItemList& list);
void SelectAllIgnore(BOOL bSelect, HTREEITEM hIgnore);
BOOL _SendNotify(LPNMHDR pNMHDR);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMultiTree)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMultiTree();
// Generated message map functions
protected:
//{{AFX_MSG(CMultiTree)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MLTITREE_H__9F4750E5_C512_11D2_880A_02608C7CB3EE__INCLUDED_)

6185
Editor/Controls/NewMenu.cpp Normal file

File diff suppressed because it is too large Load Diff

892
Editor/Controls/NewMenu.h Normal file
View File

@@ -0,0 +1,892 @@
// File : NewMenu.cpp
// Version : 1.10
// Date : 30. July 2002
// Author : Bruno Podetti
// Email : Podetti@gmx.net
// Systems : VC6.0 and VC7.0 (Run under (Window 98/ME), Windows Nt 2000/XP)
//
// Special
// Compiled version with visual studio V7.0 doesn't run correctly on WinNt 4.0
// nor Windows 95. For those platforms, you have to compile it with
// visual studio V6.0
//
// ToDo's
// checking GDI-Leaks, are there some more?
// Shade-Drawing, when underground is changing
// XP-changing settings Border Style => to fix border painting without restarting
// Border repainting after menu closing!!!
//
// (30. July 2002) Bug Fixes or nice hints from 1.03
// Color of checked icons / selection marks more XP-look
// Updating images 16 color by changing systems colors
// Icon drawing with more highlighting and half transparency
// Scroller for large menu correcting (but the overlapping border is not corrected)
// Resource-problem on windows 95/98/ME?, when using too much bitmaps in menus
// changing the kind of storing bitmaps (images list)
// Calculating the size for a menuitem (specially submenuitem) corrected.
// Recentfilelist corrected (Seperator gots a wrong ID number)
//
// (25. June 2002) Bug Fixes or nice hints from 1.02
// Adding removing menu corrected for drawing the shade in menubar
// Draw the menuborder corrected under win 98 at the bottom side
// Highlighting under 98 for menu corrected (Assert), Neville Franks
// Works also on Windows 95
// Changing styles on XP menucolor of the bar now corrected.
//
// (18. June 2002) Bug Fixes or nice hints from 1.01
// Popup menu which has more items than will fit, better
// LoadMenu changed for better languagessuport, SnowCat
// Bordercolor & Drawing of XP-Style-Menu changed to more XP-Look
// Added some functions for setting/reading MenuItemData
// Menubar highlighting now supported under 98/ME (NT 4.0 and 95?)
// Font for menutitle can be changed
// Bugs for popupmenu by adding submenu corrected, no autodestroy
//
// (6. June 2002) Bug Fixes or nice hints from 1.00
// Loading Icons from a resource dll expanded (LoadToolBar) Jonathan de Halleux, Belgium.
// Minimized resource leak of User and Gdi objects
// Problem of disabled windows button on 98/Me solved
// Gradient-drawing without Msimg32.dll now supported especially for win 95
// Using solid colors for drawing menu items
// GetSubMenu changed to const
// Added helper function for setting popup-flag for popup menu (centered text)
// Redraw menu bar corrected after canceling popup menu in old style menu
//
// (23. Mai 2002) Bug Fixes and portions of code from previous version supplied by:
// Brent Corkum, Ben Ashley, Girish Bharadwaj, Jean-Edouard Lachand-Robert,
// Robert Edward Caldecott, Kenny Goers, Leonardo Zide, Stefan Kuhr,
// Reiner Jung, Martin Vladic, Kim Yoo Chul, Oz Solomonovich, Tongzhe Cui,
// Stephane Clog, Warren Stevens, Damir Valiulin
//
// You are free to use/modify this code but leave this header intact.
// This class is public domain so you are free to use it any of your
// applications (Freeware, Shareware, Commercial).
// All I ask is that you let me know so that if you have a real winner I can
// brag to my buddies that some of my code is in your app. I also wouldn't
// mind if you sent me a copy of your application since I like to play with
// new stuff.
//------------------------------------------------------------------------------
#ifndef __CNewMenu_H_
#define __CNewMenu_H_
#pragma warning(push)
#pragma warning(disable : 4211)
#include <afxtempl.h>
#include <afxpriv.h>
// Flagdefinitions
#define MFT_TITLE 0x0001
#define MFT_TOP_TITLE 0x0000
#define MFT_SIDE_TITLE 0x0002
#define MFT_GRADIENT 0x0004
#define MFT_SUNKEN 0x0008
#define MFT_LINE 0x0010
#define MFT_ROUND 0x0020
#define MFT_CENTER 0x0040
// Typedefinition for compatibility to MFC 7.0
#ifndef DWORD_PTR
typedef DWORD DWORD_PTR, *PDWORD_PTR;
#endif
#ifndef ULONG_PTR
typedef unsigned long ULONG_PTR, *PULONG_PTR;
#endif
#ifndef LONG_PTR
typedef long LONG_PTR, *PLONG_PTR;
#endif
// Additional flagdefinition for highlighting
#ifndef ODS_HOTLIGHT
#define ODS_HOTLIGHT 0x0040
#endif
#ifndef ODS_INACTIVE
#define ODS_INACTIVE 0x0080
#endif
/////////////////////////////////////////////////////////////////////////////
// Constans for detecting OS-Type
enum Win32Type
{
Win32s,
WinNT3,
Win95,
Win98,
WinME,
WinNT4,
Win2000,
WinXP
};
extern const Win32Type g_Shell;
extern BOOL bRemoteSession;
/////////////////////////////////////////////////////////////////////////////
// Global helperfunctions
UINT GetSafeTimerID(HWND hWnd, const UINT uiElapse);
BOOL DrawMenubarItem(CWnd* pWnd,CMenu* pMenu, UINT nItemIndex,UINT nState);
WORD NumBitmapColors(LPBITMAPINFOHEADER lpBitmap);
HBITMAP LoadColorBitmap(LPCTSTR lpszResourceName, HMODULE hInst, int* pNumcol=NULL);
/////////////////////////////////////////////////////////////////////////////
// Forwarddeclaration for drawing purpose
class CMenuTheme;
/////////////////////////////////////////////////////////////////////////////
// CNewMenuIcons menu icons for drawing
class CNewMenuIcons : public CObject
{
DECLARE_DYNCREATE(CNewMenuIcons)
public:
CNewMenuIcons();
virtual ~CNewMenuIcons();
public:
BOOL GetIconSize(int* cx, int* cy);
CSize GetIconSize();
virtual int FindIndex(UINT nID);
virtual void OnSysColorChange();
virtual BOOL LoadToolBar(LPCTSTR lpszResourceName, HMODULE hInst);
virtual BOOL LoadToolBar(WORD* pToolInfo, COLORREF crTransparent=CLR_NONE);
virtual BOOL DoMatch(LPCTSTR lpszResourceName, HMODULE hInst);
virtual BOOL DoMatch(WORD* pToolInfo, COLORREF crTransparent=CLR_NONE);
virtual BOOL LoadBitmap(int nWidth, int nHeight, LPCTSTR lpszResourceName, HMODULE hInst=NULL);
// virtual BOOL SetBlendImage();
virtual int AddGloomIcon(HICON hIcon, int nIndex=-1);
virtual int AddGrayIcon(HICON hIcon, int nIndex=-1);
virtual BOOL MakeImages();
void SetResourceName(LPCTSTR lpszResourceName);
int AddRef();
int Release();
#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
public:
LPCTSTR m_lpszResourceName;
HMODULE m_hInst;
int m_nColors;
COLORREF m_crTransparent;
CImageList m_IconsList;
CArray<UINT,UINT&> m_IDs;
DWORD m_dwRefCount;
};
/////////////////////////////////////////////////////////////////////////////
// CNewMenuBitmaps menu icons for drawing
class CNewMenuBitmaps : public CNewMenuIcons
{
DECLARE_DYNCREATE(CNewMenuBitmaps)
public:
CNewMenuBitmaps();
virtual ~CNewMenuBitmaps();
public:
int Add(UINT nID, COLORREF crTransparent=CLR_NONE);
int Add(HICON hIcon, UINT nID=0);
int Add(CBitmap* pBitmap, COLORREF crTransparent=CLR_NONE);
virtual void OnSysColorChange();
CArray<COLORREF,COLORREF&> m_TranspColors;
};
/////////////////////////////////////////////////////////////////////////////
// CNewMenuItemData menu item data for drawing
class CNewMenuItemData : public CObject
{
DECLARE_DYNCREATE(CNewMenuItemData)
public:
CNewMenuItemData();
virtual ~CNewMenuItemData();
public:
LPCTSTR GetString();
void SetString(LPCTSTR szMenuText);
#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
public:
CString m_szMenuText;
UINT m_nTitleFlags;
UINT m_nFlags;
UINT m_nID;
UINT m_nSyncFlag;
CNewMenuIcons* m_pMenuIcon;
int m_nMenuIconOffset;
void* m_pData;
};
/////////////////////////////////////////////////////////////////////////////
// CNewMenu the new menu class
class CNewMenu : public CMenu
{
friend class CNewMenuHook;
friend class CNewMenuIcons;
DECLARE_DYNCREATE(CNewMenu)
public:
// how the menu's are drawn, either original or XP style
typedef enum
{
STYLE_ORIGINAL,
STYLE_ORIGINAL_NOBORDER,
STYLE_XP,
STYLE_XP_NOBORDER,
STYLE_SPECIAL,
STYLE_SPECIAL_NOBORDER
} EDrawStyle;
// how seperators are handled when removing a menu (Tongzhe Cui)
typedef enum {NONE, HEAD, TAIL, BOTH} ESeperator;
public:
CNewMenu(HMENU hParent=0);
virtual ~CNewMenu();
// Functions for loading and applying bitmaps to menus (see example application)
virtual BOOL LoadMenu(HMENU hMenu);
virtual BOOL LoadMenu(LPCTSTR lpszResourceName);
virtual BOOL LoadMenu(int nResource);
BOOL LoadToolBar(WORD* pIconInfo, COLORREF crTransparent=CLR_NONE);
BOOL LoadToolBar(LPCTSTR lpszResourceName, HMODULE hInst = NULL);
BOOL LoadToolBar(UINT nToolBar, HMODULE hInst = NULL);
BOOL LoadToolBars(const UINT *arID,int n, HMODULE hInst = NULL);
BOOL LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset);
BOOL AddBitmapToImageList(CImageList *list,UINT nResourceID);
static HBITMAP LoadSysColorBitmap(int nResourceId);
// custom check mark bitmaps
void LoadCheckmarkBitmap(int unselect, int select);
// functions for appending a menu option, use the AppendMenu call
BOOL AppendMenu(UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL,int nIconNormal=-1);
BOOL AppendMenu(UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CImageList *il,int xoffset);
BOOL AppendMenu(UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CBitmap *bmp);
BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags = MF_OWNERDRAW, UINT nID = 0, int nIconNormal = -1);
BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, CBitmap* pbmp);
BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, CImageList *il, int xoffset);
BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, CNewMenuIcons* pIcons, int nIndex);
// for appending a popup menu (see example application)
CNewMenu* AppendODPopupMenu(LPCTSTR lpstrText);
// functions for inserting a menu option, use the InsertMenu call (see above define)
BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL,int nIconNormal=-1);
BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CImageList *il,int xoffset);
BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CBitmap *bmp);
BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags, UINT nID, CBitmap* pBmp);
BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags, UINT nID, CImageList *il,int xoffset);
BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags, UINT nID, CNewMenuIcons* pIcons, int nIndex);
// functions for modifying a menu option, use the ModifyODMenu call (see above define)
BOOL ModifyODMenu(LPCTSTR lpstrText, UINT nID=0, int nIconNormal=-1);
BOOL ModifyODMenu(LPCTSTR lpstrText, UINT nID, CImageList *il, int xoffset);
BOOL ModifyODMenu(LPCTSTR lpstrText, UINT nID, CNewMenuIcons* pIcons, int nIndex);
BOOL ModifyODMenu(LPCTSTR lpstrText,UINT nID,CBitmap *bmp);
BOOL ModifyODMenu(LPCTSTR lpstrText,LPCTSTR OptionText,int nIconNormal);
// use this method for adding a solid/hatched colored square beside a menu option
// courtesy of Warren Stevens
BOOL ModifyODMenu(LPCTSTR lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle=-1);
// for deleting and removing menu options
BOOL DeleteMenu(UINT uiId,UINT nFlags);
BOOL RemoveMenu(UINT uiId,UINT nFlags);
int RemoveMenu(LPCTSTR pText, ESeperator sPos=CNewMenu::NONE);
// function for retrieving and setting a menu options text (use this function
// because it is ownerdrawn)
BOOL GetMenuText(UINT id,CString &string,UINT nFlags = MF_BYPOSITION);
BOOL SetMenuText(UINT id,CString string, UINT nFlags = MF_BYPOSITION);
// Getting a submenu from it's name or position
CMenu* GetSubMenu (LPCTSTR lpszSubMenuName) const;
CMenu* GetSubMenu (int nPos) const;
int GetMenuPosition(LPCTSTR pText);
// Destoying
virtual BOOL DestroyMenu();
// Drawing:
// Draw an item
virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
// Measure an item
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);
// Draw title of the menu
virtual void DrawTitle(LPDRAWITEMSTRUCT lpDIS,BOOL bIsMenuBar);
// Erase the Background of the menu
virtual BOOL EraseBkgnd(HWND hWnd,HDC hDC);
static COLORREF GetMenuBarColor();
static void SetMenuTitleFont(CFont* pFont);
static void SetMenuTitleFont(LOGFONT* pLogFont);
static LOGFONT GetMenuTitleFont();
// Menutitle function
BOOL SetMenuTitle(LPCTSTR pTitle,UINT nTitleFlags=MFT_TOP_TITLE);
BOOL RemoveMenuTitle();
// Function to set how menu is drawn, either original or XP style
static int GetMenuDrawMode();
static void SetMenuDrawMode(UINT mode);
// Function to set how disabled items are drawn
//(mode=FALSE means they are not drawn selected)
static BOOL SetSelectDisableMode(BOOL mode);
static BOOL GetSelectDisableMode();
// Function to set how icons were drawn in normal mode
//(enable=TRUE means they are drawn blended)
static BOOL SetXpBlendig(BOOL bEnable=TRUE);
static BOOL GetXpBlendig();
static void OnSysColorChange();
// Static functions used for handling menu's in the mainframe
static LRESULT FindKeyboardShortcut(UINT nChar,UINT nFlags,CMenu *pMenu);
static BOOL OnMeasureItem(const MSG* pMsg);
static void OnInitMenuPopup(HWND hWnd, CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
// Helperfunction to find the menu to the item
static CMenu* FindPopupMenuFromID(CMenu* pMenu, UINT nID);
static CMenu* FindPopupMenuFromID(HMENU hMenu, UINT nID);
static CMenu* FindPopupMenuFromIDData(CMenu* pMenu, UINT nID, ULONG_PTR pData);
static CMenu* FindPopupMenuFromIDData(HMENU hMenu, UINT nID, ULONG_PTR pData);
virtual void OnInitMenuPopup();
virtual BOOL OnUnInitPopupMenu(HWND hWnd);
// Customizing:
// Set icon size
void SetIconSize(int width, int height);
// set the color in the bitmaps that is the background transparent color
COLORREF SetBitmapBackground(COLORREF newColor);
COLORREF GetBitmapBackground();
// Return the last itemrect from a menubaritem.
CRect GetLastActiveMenuRect();
HMENU GetParent();
BOOL IsPopup();
BOOL SetPopup(BOOL bIsPopup=TRUE);
BOOL SetItemData(UINT uiId, DWORD_PTR dwItemData, BOOL fByPos = FALSE);
BOOL SetItemDataPtr(UINT uiId, void* pItemData, BOOL fByPos = FALSE);
DWORD_PTR GetItemData(UINT uiId, BOOL fByPos = FALSE) const;
void* GetItemDataPtr(UINT uiId, BOOL fByPos = FALSE) const;
BOOL SetMenuData(DWORD_PTR dwMenuData);
BOOL SetMenuDataPtr(void* pMenuData);
DWORD_PTR GetMenuData() const;
void* GetMenuDataPtr() const;
// Miscellaneous Protected Member functions
protected:
CNewMenuIcons* GetMenuIcon(int &nIndex, UINT nID, CImageList *pil, int xoffset);
CNewMenuIcons* GetMenuIcon(int &nIndex, int nID);
CNewMenuIcons* GetMenuIcon(int &nIndex, CBitmap* pBmp);
CNewMenuIcons* GetToolbarIcons(UINT nToolBar, HMODULE hInst=NULL);
DWORD SetMenuIcons(CNewMenuIcons* pMenuIcons);
BOOL Replace(UINT nID, UINT nNewID);
static BOOL IsNewShell();
BOOL IsMenuBar(HMENU hMenu=NULL);
void SetLastMenuRect(HDC hDC, LPRECT pRect);
CNewMenuItemData* FindMenuItem(UINT nID);
CNewMenu* FindMenuOption(int nId, int& nLoc);
CNewMenu* FindMenuOption(LPCTSTR lpstrText, int& nLoc);
CNewMenu* FindAnotherMenuOption(int nId, int& nLoc, CArray<CNewMenu*,CNewMenu*>&newSubs, CArray<int,int&>&newLocs);
CNewMenuItemData* NewODMenu(UINT pos, UINT nFlags, UINT nID, LPCTSTR string);
void SynchronizeMenu();
void InitializeMenuList(int value);
void DeleteMenuList();
CNewMenuItemData* FindMenuList(UINT nID);
CNewMenuItemData* CheckMenuItemData(ULONG_PTR nItemData) const;
void DrawSpecial_OldStyle(CDC* pDC, LPCRECT pRect, UINT nID, DWORD dwStyle);
void DrawSpecial_WinXP(CDC* pDC, LPCRECT pRect, UINT nID, DWORD dwStyle);
void DrawSpecialCharStyle(CDC* pDC, LPCRECT pRect, TCHAR Sign, DWORD dwStyle);
void DrawSpecialChar(CDC* pDC, LPCRECT pRect, TCHAR Sign, BOOL bBold);
void DrawMenuTitle(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar);
// Measure an item
void MeasureItem_OldStyle( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar);
void DrawItem_OldStyle (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);
BOOL Draw3DCheckmark(CDC* dc, const CRect& rc, HBITMAP hbmCheck, DWORD dwStyle);
void MeasureItem_WinXP( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar);
void DrawItem_WinXP (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar);
void DrawItem_SpecialStyle (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);
// BOOL ImageListDuplicate(CImageList* il,int xoffset,CImageList* newlist);
void ColorBitmap(CDC* pDC, CBitmap& bmp, CSize size, COLORREF fill, COLORREF border, int hatchstyle=-1);
// Member Variables
public:
static DWORD m_dwLastActiveItem;
protected:
// Stores list of menu items
CTypedPtrArray<CPtrArray, CNewMenuItemData*> m_MenuItemList;
// When loading an owner-drawn menu using a Resource, CNewMenu must keep track of
// the popup menu's that it creates. Warning, this list *MUST* be destroyed
// last item first :)
// Stores list of sub-menus
CTypedPtrArray<CPtrArray, HMENU> m_SubMenus;
static BOOL m_bEnableXpBlendig;
static BOOL m_bSelectDisable;
static CMenuTheme* m_pActMenuDrawing;
static LOGFONT m_MenuTitleFont;
static CTypedPtrList<CPtrList, CNewMenuIcons*>* m_pSharedMenuIcons;
int m_iconX;
int m_iconY;
COLORREF m_bitmapBackground;
CImageList* m_checkmaps;
BOOL m_checkmapsshare;
int m_selectcheck;
int m_unselectcheck;
BOOL m_bDynIcons;
HMENU m_hParentMenu;
BOOL m_bIsPopupMenu;
CRect m_LastActiveMenuRect;
DWORD m_dwOpenMenu;
void* m_pData;
};
/////////////////////////////////////////////////////////////////////////////
// CNewFrame<> template for easy using of the new menu
template<class baseClass>
class CNewFrame : public baseClass
{
typedef CNewFrame<baseClass> MyNewFrame;
public:
CNewMenu m_DefaultNewMenu;
CNewMenu m_SystemNewMenu;
public:
CNewFrame()
{
m_bInMenuLoop = FALSE;
m_TimerID = NULL;
m_menubarItemIndex = UINT(-1);
}
// control bar docking
void EnableDocking(DWORD dwDockStyle);
private:
static const AFX_MSGMAP_ENTRY _messageEntries[];
protected:
static const AFX_MSGMAP messageMap;
BOOL m_bInMenuLoop;
UINT m_TimerID;
UINT m_menubarItemIndex;
#if _MFC_VER < 0x0700
static const AFX_MSGMAP* PASCAL _GetBaseMessageMap()
{
return &baseClass::messageMap;
};
#else
static const AFX_MSGMAP* PASCAL GetThisMessageMap()
{
return &CNewFrame<baseClass>::messageMap;
}
#endif
virtual const AFX_MSGMAP* GetMessageMap() const
{
return &CNewFrame<baseClass>::messageMap;
}
static const AFX_MSGMAP_ENTRY* GetMessageEntries()
{
static const AFX_MSGMAP_ENTRY Entries[] =
{
ON_WM_MEASUREITEM()
ON_WM_MENUCHAR()
ON_WM_INITMENUPOPUP()
ON_WM_ENTERMENULOOP()
ON_WM_EXITMENULOOP()
ON_WM_TIMER()
ON_WM_CREATE()
ON_WM_NCHITTEST()
ON_WM_DESTROY()
ON_WM_SYSCOLORCHANGE()
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
return Entries;
}
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (baseClass::OnCreate(lpCreateStruct) == -1)
return -1;
m_SystemNewMenu.Attach(::GetSystemMenu(m_hWnd,FALSE));
return 0;
}
afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
baseClass::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
CNewMenu::OnInitMenuPopup(m_hWnd,pPopupMenu, nIndex, bSysMenu);
}
afx_msg void OnSysColorChange()
{
baseClass::OnSysColorChange();
CNewMenu::OnSysColorChange();
}
afx_msg void OnEnterMenuLoop(BOOL bIsTrackPopupMenu)
{
m_bInMenuLoop = TRUE;
if(m_TimerID!=NULL)
{
KillTimer(m_TimerID);
m_TimerID = NULL;
}
if (m_menubarItemIndex!=UINT(-1))
{
DrawMenubarItem(this,GetMenu(),m_menubarItemIndex,NULL);
m_menubarItemIndex=UINT(-1);
}
baseClass::OnEnterMenuLoop(bIsTrackPopupMenu);
}
afx_msg void OnExitMenuLoop(BOOL bIsTrackPopupMenu)
{
m_bInMenuLoop = FALSE;
baseClass::OnExitMenuLoop(bIsTrackPopupMenu);
}
afx_msg void OnTimer(UINT_PTR nIDEvent)
{
baseClass::OnTimer(nIDEvent);
if(m_TimerID==nIDEvent)
{
CPoint pt;
GetCursorPos(&pt);
SendMessage(WM_NCHITTEST, 0, MAKELONG(pt.x, pt.y));
}
}
afx_msg void OnDestroy()
{
if(m_TimerID!=NULL)
{
KillTimer(m_TimerID);
m_TimerID = NULL;
}
baseClass::OnDestroy();
}
afx_msg UINT OnNcHitTest(CPoint point)
{
UINT nHitCode = baseClass::OnNcHitTest(point);
// Test Win85/98/me and Win NT 4.0
if(g_Shell<Win2000 || bRemoteSession)
{
UINT nStatus = IsChild(GetFocus()) ? 0: ODS_INACTIVE;
CNewMenu* pNewMenu = DYNAMIC_DOWNCAST(CNewMenu,GetMenu());
if (!m_bInMenuLoop && nHitCode == HTMENU)
{
// I support only CNewMenu ownerdrawings menu!!
if(pNewMenu)
{
UINT nItemIndex = MenuItemFromPoint(m_hWnd, pNewMenu->m_hMenu, point);
if ( nItemIndex!=(UINT)-1 )
{
if(m_menubarItemIndex!=nItemIndex)
{
// Clear the old Item
DrawMenubarItem(this,pNewMenu,m_menubarItemIndex,nStatus);
// Draw the hotlight item.
if(DrawMenubarItem(this,pNewMenu,nItemIndex,ODS_HOTLIGHT|nStatus))
{
// Set a new Timer
if(m_TimerID==NULL)
{
m_TimerID=GetSafeTimerID(m_hWnd,100);
}
m_menubarItemIndex = nItemIndex;
}
else
{
m_menubarItemIndex = UINT(-1);
}
}
else
{
// Draw the hotlight item again.
if(CNewMenu::m_dwLastActiveItem==NULL &&
DrawMenubarItem(this,pNewMenu,nItemIndex,ODS_HOTLIGHT|nStatus))
{
// Set a new Timer
if(m_TimerID==NULL)
{
m_TimerID=GetSafeTimerID(m_hWnd,100);
}
m_menubarItemIndex = nItemIndex;
}
}
return nHitCode;
}
}
}
if (m_menubarItemIndex!=UINT(-1))
{
DrawMenubarItem(this,pNewMenu,m_menubarItemIndex,nStatus);
m_menubarItemIndex=UINT(-1);
}
if(m_TimerID!=NULL)
{
KillTimer(m_TimerID);
m_TimerID=NULL;
}
}
return nHitCode;
}
afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMIS)
{
if(!CNewMenu::OnMeasureItem(GetCurrentMessage()))
{
baseClass::OnMeasureItem(nIDCtl, lpMIS);
}
}
afx_msg LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenu* pMenu)
{
LRESULT lresult;
if( DYNAMIC_DOWNCAST(CNewMenu,pMenu) )
lresult=CNewMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
else
lresult=baseClass::OnMenuChar(nChar, nFlags, pMenu);
return lresult;
}
};
#ifdef _AFXDLL
#if _MFC_VER < 0x0700
template<class baseClass>
const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &CNewFrame<baseClass>::_GetBaseMessageMap, GetMessageEntries()};
#else
template<class baseClass>
const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &baseClass::GetThisMessageMap, GetMessageEntries()};
#endif
#else
template<class baseClass>
const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &baseClass::messageMap, GetMessageEntries()};
#endif
/////////////////////////////////////////////////////////////////////////////
// CNewMiniDockFrameWnd for docking toolbars with new menu
class CNewMiniDockFrameWnd: public CNewFrame<CMiniDockFrameWnd>
{
DECLARE_DYNCREATE(CNewMiniDockFrameWnd)
};
// control bar docking
template<class baseClass>
void CNewFrame<baseClass>::EnableDocking(DWORD dwDockStyle)
{
baseClass::EnableDocking(dwDockStyle);
// Owerite registering for floating frame
m_pFloatingFrameClass = RUNTIME_CLASS(CNewMiniDockFrameWnd);
}
/////////////////////////////////////////////////////////////////////////////
// CNewDialog for dialog implementation
class CNewDialog : public CNewFrame<CDialog>
{
DECLARE_DYNAMIC(CNewDialog);
public:
CNewDialog();
CNewDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
CNewDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
// Overridables (special message map entries)
virtual BOOL OnInitDialog();
protected:
// Generated message map functions
//{{AFX_MSG(CNewDialog)
afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CNewMiniFrameWnd for menu to documents
class CNewMiniFrameWnd : public CNewFrame<CMiniFrameWnd>
{
DECLARE_DYNCREATE(CNewMiniFrameWnd)
};
/////////////////////////////////////////////////////////////////////////////
// CNewMDIChildWnd for menu to documents
class CNewMDIChildWnd : public CNewFrame<CMDIChildWnd>
{
DECLARE_DYNCREATE(CNewMDIChildWnd)
};
/////////////////////////////////////////////////////////////////////////////
// CNewFrameWnd for menu to documents
class CNewFrameWnd : public CNewFrame<CFrameWnd>
{
DECLARE_DYNCREATE(CNewFrameWnd)
public:
#if _MFC_VER < 0x0700
// dynamic creation - load frame and associated resources
virtual BOOL LoadFrame(UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);
#endif
// under MFC 7.0 the next function is virtual so we don't neet to owerwrite
// loadframe
BOOL Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle = WS_OVERLAPPEDWINDOW,
const RECT& rect = rectDefault,
CWnd* pParentWnd = NULL, // != NULL for popups
LPCTSTR lpszMenuName = NULL,
DWORD dwExStyle = 0,
CCreateContext* pContext = NULL);
};
/////////////////////////////////////////////////////////////////////////////
// CNewMDIFrameWnd for menu to documents
class CNewMDIFrameWnd : public CNewFrame<CMDIFrameWnd>
{
DECLARE_DYNCREATE(CNewMDIFrameWnd);
public:
#if _MFC_VER < 0x0700
// dynamic creation - load frame and associated resources
virtual BOOL LoadFrame(UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);
#endif
// under MFC 7.0 the next function is virtual so we don't neet to owerwrite
// loadframe
BOOL Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle = WS_OVERLAPPEDWINDOW,
const RECT& rect = rectDefault,
CWnd* pParentWnd = NULL, // != NULL for popups
LPCTSTR lpszMenuName = NULL,
DWORD dwExStyle = 0,
CCreateContext* pContext = NULL);
};
/////////////////////////////////////////////////////////////////////////////
// CNewMultiDocTemplate for menu to documents
class CNewMultiDocTemplate: public CMultiDocTemplate
{
DECLARE_DYNAMIC(CNewMultiDocTemplate)
public:
CNewMenu m_NewMenuShared;
// Constructors
public:
CNewMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
~CNewMultiDocTemplate();
};
#pragma warning(pop)
#endif // __CNewMenu_H_

View File

@@ -0,0 +1,661 @@
// NumberCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "NumberCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNumberCtrl
CNumberCtrl::CNumberCtrl()
{
m_btnStatus = 0;
m_btnWidth = 10;
m_draggin = false;
m_value = 0;
m_min = 0;
m_max = 10000;
m_step = 0.01f;
m_enabled = true;
m_noNotify = false;
m_integer = false;
m_iInternalPrecision=2; // default internal precision for floats
m_nFlags = 0;
m_bUndoEnabled = false;
m_bDragged = false;
m_multiplier = 1;
}
CNumberCtrl::~CNumberCtrl()
{
}
BEGIN_MESSAGE_MAP(CNumberCtrl, CWnd)
//{{AFX_MSG_MAP(CNumberCtrl)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_ENABLE()
ON_WM_SETFOCUS()
ON_EN_SETFOCUS(IDC_EDIT,OnEditSetFocus)
ON_EN_KILLFOCUS(IDC_EDIT,OnEditKillFocus)
//}}AFX_MSG_MAP
ON_WM_SIZE()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNumberCtrl message handlers
void CNumberCtrl::Create( CWnd* parentWnd,CRect &rc,UINT nID,int nFlags )
{
m_nFlags = nFlags;
HCURSOR arrowCursor = AfxGetApp()->LoadStandardCursor( IDC_ARROW );
CreateEx( 0,AfxRegisterWndClass(NULL,arrowCursor,NULL/*(HBRUSH)GetStockObject(LTGRAY_BRUSH)*/),NULL,WS_CHILD|WS_VISIBLE|WS_TABSTOP,rc,parentWnd,nID );
}
void CNumberCtrl::Create( CWnd* parentWnd,UINT ctrlID,int flags )
{
ASSERT( parentWnd );
m_nFlags = flags;
CRect rc;
CWnd *ctrl = parentWnd->GetDlgItem( ctrlID );
ctrl->SetDlgCtrlID( ctrlID + 10000 );
ctrl->ShowWindow( SW_HIDE );
ctrl->GetWindowRect( rc );
parentWnd->ScreenToClient(rc);
HCURSOR arrowCursor = AfxGetApp()->LoadStandardCursor( IDC_ARROW );
CreateEx( 0,AfxRegisterWndClass(NULL,arrowCursor,NULL/*(HBRUSH)GetStockObject(LTGRAY_BRUSH)*/),NULL,WS_CHILD|WS_VISIBLE|WS_TABSTOP,rc,parentWnd,ctrlID );
}
int CNumberCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_upDownCursor = AfxGetApp()->LoadStandardCursor( IDC_SIZENS );
m_upArrow = (HICON)LoadImage( AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_UP_ARROW),IMAGE_ICON,5,5,LR_DEFAULTCOLOR );
m_downArrow = (HICON)LoadImage( AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_DOWN_ARROW),IMAGE_ICON,5,5,LR_DEFAULTCOLOR );
CRect rc;
GetClientRect( rc );
if (m_nFlags & LEFTARROW)
{
rc.left += m_btnWidth+3;
}
else
{
rc.right -= m_btnWidth+1;
}
DWORD nFlags = WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL;
if (m_nFlags & LEFTALIGN)
nFlags |= ES_LEFT;
else
nFlags |= ES_RIGHT;
if (!(m_nFlags & NOBORDER))
nFlags |= WS_BORDER;
//m_edit.Create( WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER|ES_RIGHT|ES_AUTOHSCROLL,rc,this,IDC_EDIT );
m_edit.Create( nFlags,rc,this,IDC_EDIT );
// m_edit.Create( WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,rc,this,IDC_EDIT );
m_edit.SetFont( CFont::FromHandle( (HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );
m_edit.SetUpdateCallback( functor(*this, &CNumberCtrl::OnEditChanged) );
float val = m_value;
m_value = val+1;
SetInternalValue( val );
return 0;
}
void CNumberCtrl::SetLeftAlign( bool left )
{
if (m_edit)
{
if (left)
m_edit.ModifyStyle( ES_RIGHT,ES_LEFT );
else
m_edit.ModifyStyle( ES_LEFT,ES_RIGHT );
}
}
void CNumberCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawButtons( dc );
// Do not call CWnd::OnPaint() for painting messages
}
void CNumberCtrl::DrawButtons( CDC &dc )
{
CRect rc;
GetClientRect( rc );
if (!m_enabled)
{
//dc.FillRect( rc,CBrush::FromHandle((HBRUSH)GetStockObject(LTGRAY_BRUSH)) );
dc.FillSolidRect( rc,GetSysColor(COLOR_3DFACE) );
return;
}
int x = 0;
if (!(m_nFlags & LEFTARROW))
{
x = rc.right-m_btnWidth;
}
int y = rc.top;
int w = m_btnWidth;
int h = rc.bottom;
int h2 = h/2;
COLORREF hilight = RGB(255,255,255);
COLORREF shadow = RGB(100,100,100);
//dc.Draw3dRect( x,y,w,h/2-1,hilight,shadow );
//dc.Draw3dRect( x,y+h/2+1,w,h/2-1,hilight,shadow );
int smallOfs = 0;
if (rc.bottom <= 18)
smallOfs = 1;
//dc.FillRect()
//dc.SelectObject(b1);
//dc.Rectangle( x,y, x+w,y+h2 );
//dc.SelectObject(b2);
//dc.Rectangle( x,y+h2, x+w,y+h );
if (m_btnStatus == 1 || m_btnStatus == 3)
{
dc.Draw3dRect( x,y,w,h2,shadow,hilight );
}
else
{
dc.Draw3dRect( x,y,w,h2,hilight,shadow );
//DrawIconEx( dc,x+1,y+2,m_upArrow,5,5,0,0,DI_NORMAL );
}
if (m_btnStatus == 2 || m_btnStatus == 3)
dc.Draw3dRect( x,y+h2+1,w,h2-1+smallOfs,shadow,hilight );
else
dc.Draw3dRect( x,y+h2+1,w,h2-1+smallOfs,hilight,shadow );
DrawIconEx( dc,x+2,y+2,m_upArrow,5,5,0,0,DI_NORMAL );
DrawIconEx( dc,x+2,y+h2+3-smallOfs,m_downArrow,5,5,0,0,DI_NORMAL );
}
void CNumberCtrl::GetBtnRect( int btn,CRect &rc )
{
CRect rcw;
GetClientRect( rcw );
int x = 0;
if (!(m_nFlags & LEFTARROW))
{
x = rcw.right-m_btnWidth;
}
int y = rcw.top;
int w = m_btnWidth;
int h = rcw.bottom;
int h2 = h/2;
if (btn == 0)
{
rc.SetRect( x,y,x+w,y+h2 );
}
else if (btn == 1)
{
rc.SetRect( x,y+h2+1,x+w,y+h );
}
}
int CNumberCtrl::GetBtn( CPoint point )
{
for (int i = 0; i < 2; i++)
{
CRect rc;
GetBtnRect( i,rc );
if (rc.PtInRect(point))
{
return i;
}
}
return -1;
}
void CNumberCtrl::SetBtnStatus( int s )
{
m_btnStatus = s;
RedrawWindow();
}
void CNumberCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!m_enabled)
return;
m_btnStatus = 0;
int btn = GetBtn(point);
if (btn >= 0)
{
SetBtnStatus( btn+1 );
m_bDragged = false;
// Start undo.
if (m_bUndoEnabled)
GetIEditor()->BeginUndo();
}
m_mousePos = point;
SetCapture();
m_draggin = true;
CWnd::OnLButtonDown(nFlags, point);
}
void CNumberCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
if (!m_enabled)
return;
bool bLButonDown = false;
m_draggin = false;
if (GetCapture() == this)
{
bLButonDown = true;
ReleaseCapture();
}
SetBtnStatus( 0 );
//if (m_endUpdateCallback)
//m_endUpdateCallback(this);
if (m_bUndoEnabled && GetIEditor()->IsUndoRecording())
GetIEditor()->AcceptUndo( m_undoText );
if (bLButonDown)
{
int btn = GetBtn(point);
if (!m_bDragged && btn >= 0)
{
float prevValue = m_value;
if (btn == 0)
SetInternalValue( GetInternalValue() + m_step );
if (btn == 1)
SetInternalValue( GetInternalValue() - m_step );
if (prevValue != m_value)
NotifyUpdate(false);
}
else if (m_bDragged)
{
// Send last non tracking update after tracking.
NotifyUpdate(false);
}
}
///CWnd::OnLButtonUp(nFlags, point);
if (m_edit)
m_edit.SetFocus();
}
void CNumberCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_enabled)
return;
if (point == m_mousePos)
return;
if (m_draggin)
{
m_bDragged = true;
float prevValue = m_value;
SetCursor( m_upDownCursor );
if (m_btnStatus != 3)
SetBtnStatus(3);
if (!m_integer)
{
// Floating control.
int y = (point.y-m_mousePos.y) * abs((point.y-m_mousePos.y));
SetInternalValue( GetInternalValue() - m_step*y );
}
else
{
// Integer control.
int y = point.y-m_mousePos.y;
SetInternalValue( GetInternalValue() - m_step*y );
}
CPoint cp;
GetCursorPos( &cp );
int sX = GetSystemMetrics(SM_CXSCREEN);
int sY = GetSystemMetrics(SM_CYSCREEN);
if (cp.y < 20 || cp.y > sY-20)
{
// When near end of screen, prevent cursor from moving.
CPoint p = m_mousePos;
ClientToScreen(&p);
SetCursorPos( p.x,p.y );
}
else
{
m_mousePos = point;
}
if (prevValue != m_value)
NotifyUpdate(true);
}
CWnd::OnMouseMove(nFlags, point);
}
void CNumberCtrl::SetRange( float min,float max )
{
m_min = min;
m_max = max;
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::SetInternalValue( float val )
{
CString s;
if (val < m_min) val = m_min;
if (val > m_max) val = m_max;
if (m_integer)
{
if ((int)m_value == (int)val)
return;
s.Format( "%d",(int)val );
}
else
{
double prec = pow(10.0f,m_iInternalPrecision);
if (fabs(val-m_value) < 0.9f/prec)
return;
/*
if (val == int(val))
{
// Optimize float to string storage.
s.Format( "%i",int(val) );
}
else
{
int digits = CalculateDecimalPlaces(val,m_iInternalPrecision); // m.m. calculate the digits right from the comma
char fmt[12];
if (digits < 2)
digits = 2;
sprintf(fmt,"%%.%df",digits); // e.g. "%.2f"
s.Format( fmt,val );
}
*/
double v = val;
v = v*(prec);
int intpart = RoundFloatToInt(v);
v = (double)intpart / prec;
// Round it to precision.
s.Format( "%g",v );
}
m_value = val;
if (m_edit)
{
m_noNotify = true;
m_edit.SetText( s );
m_noNotify = false;
}
}
//////////////////////////////////////////////////////////////////////////
float CNumberCtrl::GetInternalValue() const
{
if (!m_enabled)
return m_value;
if (m_edit)
{
CString str;
m_edit.GetWindowText(str);
m_value = atof( (const char*)str );
}
return m_value;
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::SetValue( float val,float step )
{
m_step = step;
if (m_integer && m_step < 1)
m_step = 1;
SetInternalValue( val*m_multiplier );
}
//////////////////////////////////////////////////////////////////////////
float CNumberCtrl::GetValue() const
{
return GetInternalValue() / m_multiplier;
}
//////////////////////////////////////////////////////////////////////////
float CNumberCtrl::GetStep() const
{
return m_step;
}
//////////////////////////////////////////////////////////////////////////
CString CNumberCtrl::GetValueAsString() const
{
CString str;
/*
int digits = CalculateDecimalPlaces(GetValue(),m_iInternalPrecision); // m.m. calculate the digits right from the comma
char fmt[12];
sprintf(fmt,"%%.%df",digits); // e.g. "%.2f"
str.Format( fmt,m_value );
*/
str.Format( "%g",m_value/m_multiplier );
return str;
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::OnEditChanged()
{
static bool inUpdate = false;
if (!inUpdate)
{
float prevValue = m_value;
float v = GetInternalValue();
if (v < m_min) v = m_min;
if (v > m_max) v = m_max;
if (v != m_value)
{
SetInternalValue( v );
}
if (prevValue != m_value)
NotifyUpdate(false);
inUpdate = false;
}
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::OnEnable(BOOL bEnable)
{
CWnd::OnEnable(bEnable);
m_enabled = (bEnable == TRUE);
if (m_edit)
{
m_edit.EnableWindow(bEnable);
RedrawWindow();
}
}
void CNumberCtrl::NotifyUpdate( bool tracking )
{
if (m_noNotify)
return;
if (!tracking && m_bUndoEnabled)
GetIEditor()->BeginUndo();
if (m_updateCallback)
m_updateCallback(this);
CWnd *parent = GetParent();
if (parent)
{
if (!tracking)
{
::SendMessage( parent->GetSafeHwnd(),WM_COMMAND,MAKEWPARAM( GetDlgCtrlID(),EN_CHANGE ),(LPARAM)GetSafeHwnd() );
}
::SendMessage( parent->GetSafeHwnd(),WM_COMMAND,MAKEWPARAM( GetDlgCtrlID(),EN_UPDATE ),(LPARAM)GetSafeHwnd() );
}
m_lastUpdateValue = m_value;
if (!tracking && m_bUndoEnabled)
GetIEditor()->AcceptUndo( m_undoText );
}
void CNumberCtrl::OnSetFocus(CWnd* pOldWnd)
{
CWnd::OnSetFocus(pOldWnd);
if (m_edit)
{
m_edit.SetFocus();
m_edit.SetSel(0,-1);
}
}
void CNumberCtrl::SetInteger( bool enable )
{
m_integer = enable;
m_step = 1;
float f = GetInternalValue();
m_value = f+1;
SetInternalValue(f);
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::OnEditSetFocus()
{
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::OnEditKillFocus()
{
//if (m_bUpdating && m_endUpdateCallback)
//m_endUpdateCallback(this);
if (m_value != m_lastUpdateValue)
NotifyUpdate(false);
}
//////////////////////////////////////////////////////////////////////////
// calculate the digits right from the comma
int CNumberCtrl::CalculateDecimalPlaces( float infNumber, int iniMaxPlaces )
{
assert(iniMaxPlaces>=0);
char str[256],*_str=str;
sprintf(str,"%f",infNumber);
while(*_str!='.')_str++; // search the comma
int ret=0;
if(*_str!=0) // comma?
{
int cur=1;
_str++; // jump over comma
while(*_str>='0' && *_str<='9')
{
if(*_str!='0')ret=cur;
_str++;cur++;
}
if(ret>iniMaxPlaces)ret=iniMaxPlaces; // bound to maximum
}
return(ret);
}
//! m.m. (default is 2)
void CNumberCtrl::SetInternalPrecision( int iniDigits )
{
assert(iniDigits>=0);
m_iInternalPrecision=iniDigits;
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::EnableUndo( const CString& undoText )
{
m_undoText = undoText;
m_bUndoEnabled = true;
}
void CNumberCtrl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if (m_edit.m_hWnd)
{
CRect rc;
GetClientRect( rc );
if (m_nFlags & LEFTARROW)
{
rc.left += m_btnWidth+3;
}
else
{
rc.right -= m_btnWidth+1;
}
m_edit.MoveWindow(rc,FALSE);
}
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::SetFont( CFont* pFont,BOOL bRedraw )
{
CWnd::SetFont(pFont,bRedraw);
if (m_edit.m_hWnd)
m_edit.SetFont(pFont,bRedraw);
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrl::SetMultiplier( float fMultiplier )
{
if (fMultiplier != 0)
m_multiplier = fMultiplier;
}

View File

@@ -0,0 +1,148 @@
#if !defined(AFX_NUMBERCTRL_H__F928C7EC_F2C9_4272_B538_C670C0B2EF9F__INCLUDED_)
#define AFX_NUMBERCTRL_H__F928C7EC_F2C9_4272_B538_C670C0B2EF9F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// NumberCtrl.h : header file
//
#include "NumberCtrlEdit.h"
/////////////////////////////////////////////////////////////////////////////
// CNumberCtrl window
class CNumberCtrl : public CWnd
{
// Construction
public:
typedef Functor1<CNumberCtrl*> UpdateCallback;
enum Flags {
LEFTARROW = 0x01, //!< Place arrows at left side of edit control.
NOBORDER = 0x02, //!< Not draw border arroud edit control.
LEFTALIGN = 0x04, //!< Align text to left side.
};
CNumberCtrl();
// Attributes
public:
// Operations
public:
void Create( CWnd* parentWnd,UINT ctrlID,int nFlags=0 );
void Create( CWnd* parentWnd,CRect &rc,UINT nID,int nFlags=0 );
//! If called will enable undo with givven text when control is modified.
void EnableUndo( const CString& undoText );
void SetUpdateCallback( const UpdateCallback &cb ) { m_updateCallback = cb; };
//void SetBeginUpdateCallback( const UpdateCallback &cb ) { m_beginUpdateCallback = cb; };
//void SetEndUpdateCallback( const UpdateCallback &cb ) { m_endUpdateCallback = cb; };
void SetMultiplier( float fMultiplier );
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CNumberCtrl)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CNumberCtrl();
//! Set current value and change step.
void SetValue( float val,float step=0.01f );
//! Get current value.
float GetValue() const;
//! Get increment step.
float GetStep() const;
CString GetValueAsString() const;
//! Set min/max values.
void SetRange( float min,float max );
//! Value in control will be integer.
void SetInteger( bool enable );
//! If left is true align text in edit control to left, overwise to right.
void SetLeftAlign( bool left );
//! set the internal precision for floats m.m. (default is 2)
void SetInternalPrecision( int iniDigits );
//! Ovveridable from MFC.
void SetFont( CFont* pFont,BOOL bRedraw = TRUE);
// Generated message map functions
protected:
void DrawButtons( CDC &dc );
//{{AFX_MSG(CNumberCtrl)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnEnable(BOOL bEnable);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnEditSetFocus();
afx_msg void OnEditKillFocus();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
void GetBtnRect( int btn,CRect &rc );
int GetBtn( CPoint point );
void SetBtnStatus( int s );
void NotifyUpdate( bool tracking );
void OnEditChanged();
void SetInternalValue( float val );
//! Get current value.
float GetInternalValue() const;
CNumberCtrlEdit m_edit;
int m_nFlags;
int m_iInternalPrecision; //!< m.m. internal precisicion used for floats default is 2
float m_step;
float m_min,m_max;
mutable float m_value;
float m_lastUpdateValue;
float m_multiplier;
// 0 if no buttons pressed.
// 1 if up button pressed.
// 2 if down button pressed.
int m_btnStatus;
int m_btnWidth;
CPoint m_mousePos;
bool m_draggin;
HICON m_upArrow,m_downArrow;
HCURSOR m_upDownCursor;
bool m_enabled;
bool m_noNotify;
bool m_integer;
bool m_bUndoEnabled;
bool m_bDragged;
CString m_undoText;
UpdateCallback m_updateCallback;
//UpdateCallback m_beginUpdateCallback;
//UpdateCallback m_endUpdateCallback;
//! calculate the digits right from the comma
//! \param infNumber source float number
//! \param iniMaxPlaces maximum number of places (used for numeric rounding problems)
//! \return number of places 0..iniMaxPlaces
static int CalculateDecimalPlaces( float infNumber, int iniMaxPlaces );
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_NUMBERCTRL_H__F928C7EC_F2C9_4272_B538_C670C0B2EF9F__INCLUDED_)

View File

@@ -0,0 +1,109 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: numberctrledit.cpp
// Version: v1.00
// Created: 26/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "NumberCtrlEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNumberCtrlEdit
void CNumberCtrlEdit::SetText(const CString& strText)
{
m_strInitText = strText;
SetWindowText(strText);
}
BOOL CNumberCtrlEdit::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
//case VK_ESCAPE:
case VK_RETURN:
//case VK_TAB:
//::PeekMessage(pMsg, NULL, NULL, NULL, PM_REMOVE);
// Call update callback.
if (m_onUpdate)
m_onUpdate();
//return TRUE;
default:
;
}
}
return CEdit::PreTranslateMessage(pMsg);
}
BEGIN_MESSAGE_MAP(CNumberCtrlEdit, CEdit)
//{{AFX_MSG_MAP(CNumberCtrlEdit)
ON_WM_CREATE()
ON_WM_KILLFOCUS()
ON_WM_ERASEBKGND()
ON_WM_SETFOCUS()
ON_WM_CHAR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNumberCtrlEdit message handlers
int CNumberCtrlEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
CFont* pFont = GetParent()->GetFont();
SetFont(pFont);
SetWindowText(m_strInitText);
return 0;
}
void CNumberCtrlEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
// Call update callback.
if (m_onUpdate)
m_onUpdate();
}
BOOL CNumberCtrlEdit::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrlEdit::OnSetFocus(CWnd* pOldWnd)
{
CWnd::OnSetFocus(pOldWnd);
SetSel(0,-1);
}
//////////////////////////////////////////////////////////////////////////
void CNumberCtrlEdit::OnChar( UINT nChar,UINT nRepCnt,UINT nFlags )
{
if ((nChar >= '0' && nChar <= '9') || nChar == '-' || nChar == '.' || nChar == VK_BACK)
CEdit::OnChar(nChar,nRepCnt,nFlags);
}

View File

@@ -0,0 +1,64 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: numberctrledit.h
// Version: v1.00
// Created: 26/7/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __numberctrledit_h__
#define __numberctrledit_h__
#if _MSC_VER > 1000
#pragma once
#endif
class CNumberCtrlEdit : public CEdit
{
CNumberCtrlEdit(const CNumberCtrlEdit& d);
CNumberCtrlEdit& operator=(const CNumberCtrlEdit& d);
public:
typedef Functor0 UpdateCallback;
CNumberCtrlEdit() {};
// Attributes
void SetText(const CString& strText);
//! Set callback function called when number edit box is really updated.
void SetUpdateCallback( UpdateCallback func ) { m_onUpdate = func; }
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CNumberCtrlEdit)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CNumberCtrlEdit)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnChar( UINT nChar,UINT nRepCnt,UINT nFlags );
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Data
protected:
CString m_strInitText;
UpdateCallback m_onUpdate;
};
#endif // __numberctrledit_h__

View File

@@ -0,0 +1,73 @@
// ToolButton.cpp : implementation file
//
#include "stdafx.h"
#include "PickObjectButton.h"
/////////////////////////////////////////////////////////////////////////////
// CPickObjectButton
IMPLEMENT_DYNAMIC(CPickObjectButton,CColorCheckBox)
//////////////////////////////////////////////////////////////////////////
CPickObjectButton::CPickObjectButton()
{
m_targetClass = 0;
m_bMultipick = false;
}
CPickObjectButton::~CPickObjectButton()
{
}
BEGIN_MESSAGE_MAP(CPickObjectButton, CButton)
//{{AFX_MSG_MAP(CPickObjectButton)
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CPickObjectButton::OnClicked()
{
if (GetCheck() == 1)
{
SetCheck(0);
GetIEditor()->CancelPick();
return;
}
SetCheck(1);
GetIEditor()->PickObject( this,m_targetClass,m_statusText,m_bMultipick );
}
//////////////////////////////////////////////////////////////////////////
void CPickObjectButton::OnPick( CBaseObject *picked )
{
if (!m_bMultipick)
SetCheck(0);
if (m_pickCallback)
m_pickCallback->OnPick( picked );
}
//////////////////////////////////////////////////////////////////////////
void CPickObjectButton::OnCancelPick()
{
SetCheck(0);
if (m_pickCallback)
m_pickCallback->OnCancelPick();
}
//////////////////////////////////////////////////////////////////////////
void CPickObjectButton::SetPickCallback( IPickObjectCallback *callback,const CString &statusText,CRuntimeClass *targetClass,bool bMultiPick )
{
m_statusText = statusText;
m_pickCallback = callback;
m_targetClass = targetClass;
m_bMultipick = bMultiPick;
}
//////////////////////////////////////////////////////////////////////////
bool CPickObjectButton::OnPickFilter( CBaseObject *filterObject )
{
if (m_pickCallback)
return m_pickCallback->OnPickFilter( filterObject );
return true;
}

View File

@@ -0,0 +1,70 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: pickobjectbutton.h
// Version: v1.00
// Created: 28/2/2002 by Timur.
// Compilers: Visual C++.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __pickobjectbutton_h__
#define __pickobjectbutton_h__
#pragma once
#include "ColorCheckBox.h"
/////////////////////////////////////////////////////////////////////////////
// CPickObjectButton window
class CPickObjectButton : public CColorCheckBox, public IPickObjectCallback
{
DECLARE_DYNAMIC(CPickObjectButton)
// Construction
public:
CPickObjectButton();
void SetPickCallback( IPickObjectCallback *callback,const CString &statusText,CRuntimeClass *targetClass=0,bool bMultiPick=false );
afx_msg void OnClicked();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPickObjectButton)
protected:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPickObjectButton();
//! Called when object picked.
virtual void OnPick( CBaseObject *picked );
//! Called when pick mode cancelled.
virtual void OnCancelPick();
virtual bool OnPickFilter( CBaseObject *filterObject );
// Generated message map functions
protected:
//{{AFX_MSG(CPickObjectButton)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
IPickObjectCallback *m_pickCallback;
CString m_statusText;
CRuntimeClass *m_targetClass;
bool m_bMultipick;
};
#endif // __pickobjectbutton_h__

View File

@@ -0,0 +1,712 @@
// PreviewModelCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "PreviewModelCtrl.h"
#include <I3DEngine.h>
#include <IEntitySystem.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPreviewModelCtrl
CPreviewModelCtrl::CPreviewModelCtrl()
{
m_renderer = 0;
m_engine = 0;
m_object = 0;
m_character = 0;
m_entity = 0;
m_nTimer = 0;
m_size(0,0,0);
m_bRotate = false;
m_rotateAngle = 0;
m_renderer = GetIEditor()->GetRenderer();
m_engine = GetIEditor()->Get3DEngine();
m_pAnimationSystem = GetIEditor()->GetSystem()->GetIAnimationSystem();
m_fov = 60;
m_camera.SetFov( DEG2RAD(m_fov) );
m_camera.Init( 800,600,3.14f/4.0f );
m_camera.SetZMin( 0.01f );
m_camera.SetZMax( 10000 );
m_bInRotateMode = false;
m_bInMoveMode = false;
CDLight l;
l.m_Origin = Vec3(10,10,10);
float L = 0.5f;
l.m_Color.r = L; l.m_Color.g = L; l.m_Color.b = L; l.m_Color.a = 1;
l.m_SpecColor.r = L; l.m_SpecColor.g = L; l.m_SpecColor.b = L; l.m_SpecColor.a = 1;
l.m_fRadius = 1000;
l.m_fStartRadius = 0;
l.m_fEndRadius = 1000;
l.m_Flags |= DLF_POINT;
m_lights.push_back( l );
l.m_Origin = Vec3(-10,-10,-10);
l.m_Color.r = L; l.m_Color.g = L; l.m_Color.b = L; l.m_Color.a = 1;
l.m_SpecColor.r = L; l.m_SpecColor.g = L; l.m_SpecColor.b = L; l.m_SpecColor.a = 1;
l.m_fRadius = 1000;
l.m_fStartRadius = 0;
l.m_fEndRadius = 1000;
l.m_Flags |= DLF_POINT;
m_lights.push_back( l );
m_bContextCreated = false;
m_bHaveAnythingToRender = false;
m_bGrid = false;
m_bUpdate = false;
BBox box( Vec3(-2,-2,-2), Vec3(2,2,2) );
SetCameraLookAtBox( box );
}
CPreviewModelCtrl::~CPreviewModelCtrl()
{
/*
IRenderer *pr = CSystem::Instance()->SetCurrentRenderer( m_renderer );
I3DEngine *pe = CSystem::Instance()->SetCurrent3DEngine( m_3dEngine );
if (m_renderer)
m_renderer->ShutDown();
m_renderer = 0;
//delete m_renderer;
/*
if (m_3dEngine)
m_3dEngine->Release3DEngine();
*/
/*
CSystem::Instance()->SetCurrentRenderer( pr );
CSystem::Instance()->SetCurrent3DEngine( pe );
*/
}
BEGIN_MESSAGE_MAP(CPreviewModelCtrl, CWnd)
//{{AFX_MSG_MAP(CPreviewModelCtrl)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_MOUSEWHEEL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPreviewModelCtrl message handlers
//////////////////////////////////////////////////////////////////////////
BOOL CPreviewModelCtrl::Create( CWnd *pWndParent,const CRect &rc,DWORD dwStyle )
{
BOOL bReturn = CreateEx( NULL, AfxRegisterWndClass(CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW|CS_OWNDC,
AfxGetApp()->LoadStandardCursor(IDC_ARROW), NULL, NULL), NULL,dwStyle,
rc, pWndParent, NULL);
return bReturn;
}
//////////////////////////////////////////////////////////////////////////
int CPreviewModelCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
//////////////////////////////////////////////////////////////////////////
bool CPreviewModelCtrl::CreateContext()
{
// Create context.
if (m_renderer && !m_bContextCreated)
{
m_bContextCreated = true;
m_renderer->CreateContext( m_hWnd );
// Make main context current.
m_renderer->MakeCurrent();
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::PreSubclassWindow()
{
CWnd::PreSubclassWindow();
/*
// Create context.
if (m_renderer && !m_bContextCreated)
{
m_bContextCreated = true;
m_renderer->CreateContext( m_hWnd );
// Make main context current.
m_renderer->MakeCurrent();
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::ReleaseObject()
{
if (m_object)
m_engine->ReleaseObject( m_object );
if (m_character)
m_pAnimationSystem->RemoveCharacter( m_character );
m_object = 0;
m_character = 0;
m_entity = 0;
m_bHaveAnythingToRender = false;
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::LoadFile( const CString &modelFile,bool changeCamera )
{
m_bHaveAnythingToRender = false;
if (!m_hWnd)
return;
if (!m_renderer)
return;
ReleaseObject();
if (modelFile.IsEmpty())
{
if (m_nTimer != 0)
KillTimer(m_nTimer);
m_nTimer = 0;
Invalidate();
return;
}
if (stricmp( Path::GetExt(modelFile),"cga" ) == 0)
{
// Load CGA animated object.
m_character = m_pAnimationSystem->MakeCharacter( modelFile );
if(!m_character)
{
Warning( "Loading of geometry object %s failed.",(const char*)modelFile );
if (m_nTimer != 0)
KillTimer(m_nTimer);
m_nTimer = 0;
Invalidate();
return;
}
m_character->GetBBox( m_bboxMin,m_bboxMax );
}
else
{
// Load object.
m_object = m_engine->MakeObject( modelFile,NULL,evs_ShareAndSortForCache );
if(!m_object)
{
Warning( "Loading of geometry object %s failed.",(const char*)modelFile );
if (m_nTimer != 0)
KillTimer(m_nTimer);
m_nTimer = 0;
Invalidate();
return;
}
m_bboxMin = m_object->GetBoxMin();
m_bboxMax = m_object->GetBoxMax();
}
m_bHaveAnythingToRender = true;
// No timer.
/*
if (m_nTimer == 0)
m_nTimer = SetTimer(1,200,NULL);
*/
if (changeCamera)
{
BBox box;
box.min = m_bboxMin;
box.max = m_bboxMax;
SetCameraLookAtBox( box );
//SetOrbitAngles( Vec3(0,0,0) );
}
Invalidate();
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::SetEntity( IEntityRender *entity )
{
m_bHaveAnythingToRender = false;
if (m_entity != entity)
{
m_entity = entity;
if (m_entity)
{
m_bHaveAnythingToRender = true;
m_entity->GetBBox( m_bboxMin,m_bboxMax );
}
Invalidate();
}
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::SetObject( IStatObj *pObject )
{
if (m_object != pObject)
{
m_bHaveAnythingToRender = false;
m_object = pObject;
if (m_object)
{
m_bHaveAnythingToRender = true;
m_bboxMin = m_object->GetBoxMin();
m_bboxMax = m_object->GetBoxMax();
}
Invalidate();
}
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::SetCameraLookAtBox( const BBox &box )
{
Vec3d v = box.max - box.min;
float radius = v.Length()/2.0f;
m_camTarget = (box.max + box.min) * 0.5f;
m_camRadius = radius*1.8f;
m_camAngles(0,0,0);
m_camAngles.x = 30;
m_camAngles.y = 0;
m_camAngles.z = -30;
m_camera.SetPos(m_camTarget + Vec3(m_camRadius,m_camRadius,m_camRadius) );
m_camera.SetAngle(m_camAngles);
SetOrbitAngles( m_camAngles );
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
bool res = Render();
if (!res)
{
RECT rect;
// Get the rect of the client window
GetClientRect(&rect);
// Create the brush
CBrush cFillBrush;
cFillBrush.CreateSolidBrush(RGB(128,128,128));
// Fill the entire client area
dc.FillRect(&rect, &cFillBrush);
}
}
//////////////////////////////////////////////////////////////////////////
BOOL CPreviewModelCtrl::OnEraseBkgnd(CDC* pDC)
{
if (m_bHaveAnythingToRender)
return TRUE;
return CWnd::OnEraseBkgnd(pDC);
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::SetCamera( CCamera &cam )
{
m_camera.SetPos( cam.GetPos() );
m_camera.SetAngle( cam.GetAngles() );
CRect rc;
GetClientRect(rc);
//m_camera.SetFov(m_stdFOV);
int w = rc.Width();
int h = rc.Height();
float proj = (float)h/(float)w;
if (proj > 1.2f) proj = 1.2f;
m_camera.Init( w,h,DEG2RAD(m_fov),m_camera.GetZMax(),proj );
m_camera.Update();
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::SetOrbitAngles( const Vec3d &ang )
{
float dist = (m_camera.GetPos() - m_camTarget).Length();
Vec3d cangles = ang;
Vec3d v(0,0,dist);
cangles=ConvertToRad(cangles);
//Matrix tm; tm.Identity();
//tm.Rotate(cangles);
Matrix44 tm=ViewMatrix(cangles);
v = tm*v;
m_camera.SetPos( v + m_camTarget );
m_camera.SetAngle( m_camAngles );
}
//////////////////////////////////////////////////////////////////////////
bool CPreviewModelCtrl::Render()
{
if (!m_bHaveAnythingToRender)
{
return false;
}
if (!m_bContextCreated)
{
if (!CreateContext())
return false;
}
//IRenderer *pr = CSystem::Instance()->SetCurrentRenderer( m_renderer );
SetCamera( m_camera );
CRect rc;
GetClientRect(rc);
m_renderer->SetCurrentContext( m_hWnd );
m_renderer->ChangeViewport(0,0,rc.right,rc.bottom);
m_renderer->SetClearColor( Vec3(0.5f,0.5f,0.5f) );
m_renderer->BeginFrame();
m_renderer->SetCamera( m_camera );
m_renderer->SetPolygonMode( R_SOLID_MODE );
// Render object.
m_renderer->EF_ClearLightsList();
m_renderer->EF_StartEf();
m_renderer->ResetToDefault();
// Add lights.
for (int i = 0; i < m_lights.size(); i++)
{
m_renderer->EF_ADDDlight( &m_lights[i] );
}
SRendParams rp;
rp.vPos = Vec3(0,0,0);
rp.vAngles = Vec3(0,0,0);
rp.nDLightMask = 0x3;
rp.vAmbientColor = Vec3d(1,1,1);
rp.dwFObjFlags |= FOB_TRANS_MASK;
if (m_bRotate)
{
rp.vAngles.Set( 0,0,m_rotateAngle );
m_rotateAngle += 0.1f;
}
if (m_object)
m_object->Render( rp,Vec3(zero),0 );
if (m_entity)
m_entity->DrawEntity( rp );
if (m_character)
m_character->Draw( rp,Vec3(zero) );
m_renderer->EF_EndEf3D(SHDF_SORT);
m_renderer->EF_ClearLightsList();
if (m_bGrid)
DrawGrid();
m_renderer->FlushTextMessages();
m_renderer->Update();
// Restore main context.
m_renderer->MakeCurrent();
return true;
}
void CPreviewModelCtrl::DrawGrid()
{
// Draw grid.
float step = 0.1f;
float XR = 5;
float YR = 5;
m_renderer->ResetToDefault();
m_renderer->SetState(GS_DEPTHWRITE | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA);
//m_renderer->SetBlendMode();
//m_renderer->EnableBlend( true );
m_renderer->SetMaterialColor( 0.6f,0.6f,0.6f,0.3f );
// Draw grid.
for (float x = -XR; x < XR; x+=step)
{
if (fabs(x) > 0.01)
m_renderer->DrawLine( Vec3d(x,-YR,0),Vec3d(x,YR,0) );
}
for (float y = -YR; y < YR; y+=step)
{
if (fabs(y) > 0.01)
m_renderer->DrawLine( Vec3d(-XR,y,0),Vec3d(XR,y,0) );
}
// Draw axis.
m_renderer->SetMaterialColor( 1,0,0,0.3f );
m_renderer->DrawLine( Vec3d(-XR,0,0),Vec3d(XR,0,0) );
m_renderer->SetMaterialColor( 0,1,0,0.3f );
m_renderer->DrawLine( Vec3d(0,-YR,0),Vec3d(0,YR,0) );
m_renderer->SetMaterialColor( 0,0,1,0.3f );
m_renderer->DrawLine( Vec3d(0,0,-YR),Vec3d(0,0,YR) );
}
void CPreviewModelCtrl::OnTimer(UINT_PTR nIDEvent)
{
if (IsWindowVisible())
{
if (m_bHaveAnythingToRender)
Invalidate();
}
CWnd::OnTimer(nIDEvent);
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::DeleteRenderContex()
{
ReleaseObject();
// Destroy render context.
if (m_renderer && m_bContextCreated)
{
m_renderer->DeleteContext(m_hWnd);
m_bContextCreated = false;
}
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::OnDestroy()
{
DeleteRenderContex();
CWnd::OnDestroy();
if (m_nTimer)
KillTimer( m_nTimer );
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bInRotateMode = true;
m_mousePos = point;
if (!m_bInMoveMode)
SetCapture();
}
void CPreviewModelCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bInRotateMode = false;
if (!m_bInMoveMode)
ReleaseCapture();
}
void CPreviewModelCtrl::OnMButtonDown(UINT nFlags, CPoint point)
{
m_bInRotateMode = true;
m_bInMoveMode = true;
m_mousePos = point;
//if (!m_bInMoveMode)
SetCapture();
}
void CPreviewModelCtrl::OnMButtonUp(UINT nFlags, CPoint point)
{
m_bInRotateMode = false;
m_bInMoveMode = false;
ReleaseCapture();
}
void CPreviewModelCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CWnd::OnMouseMove(nFlags, point);
Invalidate();
if (point == m_mousePos)
return;
if (m_bInRotateMode && m_bInMoveMode)
{
// Zoom.
Matrix44 m = m_camera.GetVCMatrixD3D9();
//Vec3d xdir(m[0][0],m[1][0],m[2][0]);
Vec3d xdir(0,0,0);
//xdir.Normalize();
Vec3d zdir(m[0][2],m[1][2],m[2][2]);
zdir.Normalize();
float step = 0.002f;
float dx = (point.x-m_mousePos.x);
float dy = (point.y-m_mousePos.y);
// dx = pow(dx,1.05f );
//dy = pow(dy,1.05f );
//m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) );
m_camera.SetPos( m_camera.GetPos() + step*xdir*dx + step*zdir*dy );
SetCamera( m_camera );
CPoint pnt = m_mousePos;
ClientToScreen( &pnt );
SetCursorPos( pnt.x,pnt.y );
}
else if (m_bInRotateMode)
{
// Look
Vec3d angles( point.y-m_mousePos.y,0,-point.x+m_mousePos.x );
//m_camera.SetAngle( m_camera.GetAngles() + angles*0.2f );
m_camAngles += angles;
SetOrbitAngles( m_camAngles );
CPoint pnt = m_mousePos;
ClientToScreen( &pnt );
SetCursorPos( pnt.x,pnt.y );
}
else if (m_bInMoveMode)
{
// Slide.
Matrix44 m = m_camera.GetVCMatrixD3D9();
Vec3d xdir(m[0][0],m[1][0],m[2][0]);
Vec3d ydir(m[0][1],m[1][1],m[2][1]);
xdir.Normalize();
ydir.Normalize();
float dist = (m_camera.GetPos() - m_camTarget).Length();
float step = 0.001f;
float dx = (point.x-m_mousePos.x);
float dy = (point.y-m_mousePos.y);
//dx = pow( dx,1.2f );
//dy = pow( dy,1.2f );
//m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) );
m_camera.SetPos( m_camera.GetPos() - step*xdir*dx + step*ydir*dy );
SetCamera( m_camera );
// Calc camera target.
Vec3d angles = m_camAngles;
angles=ConvertToRad(angles);
//Matrix44 tm; tm.Identity();
//tm.Rotate(angles);
Matrix44 tm=ViewMatrix(angles);
Vec3d v(0,0,dist);
v = m_camera.GetPos() - tm*v;
m_camTarget = v;
m_mousePos = point;
CPoint pnt = m_mousePos;
ClientToScreen( &pnt );
SetCursorPos( pnt.x,pnt.y );
}
//Invalidate();
}
void CPreviewModelCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
m_bInMoveMode = true;
m_mousePos = point;
if (!m_bInRotateMode)
SetCapture();
}
void CPreviewModelCtrl::OnRButtonUp(UINT nFlags, CPoint point)
{
m_bInMoveMode = false;
m_mousePos = point;
if (!m_bInRotateMode)
ReleaseCapture();
}
BOOL CPreviewModelCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
{
// TODO: Add your message handler code here and/or call default
Matrix44 m = m_camera.GetVCMatrixD3D9();
Vec3d zdir(m[0][2],m[1][2],m[2][2]);
zdir.Normalize();
//m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) );
m_camera.SetPos( m_camera.GetPos() + 0.002f*zdir*(zDelta) );
SetCamera( m_camera );
Invalidate();
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize( nType,cx,cy );
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::EnableUpdate( bool bUpdate )
{
m_bUpdate = bUpdate;
// No timer.
/*
if (bUpdate)
{
if (m_nTimer == 0)
m_nTimer = SetTimer(1,50,NULL);
}
else
{
if (m_nTimer != 0)
KillTimer(m_nTimer);
}
*/
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::Update()
{
if (m_bUpdate && m_bHaveAnythingToRender)
{
if (IsWindowVisible())
Invalidate(FALSE);
}
}
//////////////////////////////////////////////////////////////////////////
void CPreviewModelCtrl::SetRotation( bool bEnable )
{
m_bRotate = bEnable;
}

View File

@@ -0,0 +1,128 @@
#if !defined(AFX_PREVIEWMODELCTRL_H__138DA368_C705_4A79_A8FA_5A5D328B8C67__INCLUDED_)
#define AFX_PREVIEWMODELCTRL_H__138DA368_C705_4A79_A8FA_5A5D328B8C67__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PreviewModelCtrl.h : header file
//
struct IEntity;
/////////////////////////////////////////////////////////////////////////////
// CPreviewModelCtrl window
class CPreviewModelCtrl : public CWnd
{
// Construction
public:
CPreviewModelCtrl();
// Attributes
public:
// Operations
public:
BOOL Create( CWnd *pWndParent,const CRect &rc,DWORD dwStyle=WS_CHILD|WS_VISIBLE );
void LoadFile( const CString &modelFile,bool changeCamera=true );
Vec3 GetSize() const { return m_size; };
void SetEntity( IEntityRender *entity );
void SetObject( IStatObj *pObject );
void SetCameraLookAtBox( const BBox &box );
void SetGrid( bool bEnable ) { m_bGrid = bEnable; }
void SetRotation( bool bEnable );
void EnableUpdate( bool bEnable );
void Update();
void DeleteRenderContex();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPreviewModelCtrl)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPreviewModelCtrl();
bool CreateContext();
void ReleaseObject();
// Generated message map functions
protected:
//{{AFX_MSG(CPreviewModelCtrl)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnDestroy();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
void SetCamera( CCamera &cam );
void SetOrbitAngles( const Vec3d &ang );
bool Render();
void DrawGrid();
IStatObj *m_object;
ICryCharInstance *m_character;
CCamera m_camera;
IRenderer* m_renderer;
I3DEngine* m_engine;
ICryCharManager* m_pAnimationSystem;
bool m_bContextCreated;
Vec3 m_size;
Vec3 m_objectAngles;
Vec3 m_pos;
int m_nTimer;
CString m_loadedFile;
std::vector<CDLight> m_lights;
Vec3d m_bboxMin;
Vec3d m_bboxMax;
// Camera control.
Vec3d m_camTarget;
float m_camRadius;
Vec3d m_camAngles;
bool m_bInRotateMode;
bool m_bInMoveMode;
CPoint m_mousePos;
IEntityRender* m_entity;
bool m_bHaveAnythingToRender;
bool m_bGrid;
bool m_bUpdate;
float m_fov;
// Rotate object in preview.
bool m_bRotate;
float m_rotateAngle;
protected:
virtual void PreSubclassWindow();
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PREVIEWMODELCTRL_H__138DA368_C705_4A79_A8FA_5A5D328B8C67__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,257 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: propertyctrl.h
// Version: v1.00
// Created: 5/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description: Defines custom control to handle Properties.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __propertyctrl_h__
#define __propertyctrl_h__
#if _MSC_VER > 1000
#pragma once
#endif
// forward declarations.
class CPropertyItem;
class CVarBlock;
/** Costom control to handle Properties hierarchies.
*/
class CPropertyCtrl : public CWnd
{
DECLARE_DYNAMIC(CPropertyCtrl)
public:
typedef std::vector<CPropertyItem*> Items;
// Flags of property control.
enum Flags
{
F_VARIABLE_HEIGHT = 0x0010,
F_VS_DOT_NET_STYLE = 0x0020, // Provides a look similar to Visual Studio.NET property grid.
};
//! When item change, this callback fired with name of item.
typedef Functor1<XmlNodeRef> UpdateCallback;
//! When selection changes, this callback is fired with name of item.
typedef Functor1<XmlNodeRef> SelChangeCallback;
//! When item change, this callback fired variable that changed.
typedef Functor1<IVariable*> UpdateVarCallback;
CPropertyCtrl();
virtual ~CPropertyCtrl();
void Create( DWORD dwStyle,const CRect &rc,CWnd *pParent=NULL,UINT nID=0 );
//! Set control flags.
//! @param flags @see Flags enum.
void SetFlags( int flags ) { m_nFlags = flags; };
//! get control flags.
int GetFlags() const { return m_nFlags; };
/** Create Property items from root Xml node
*/
void CreateItems( XmlNodeRef &node );
/** Delete all items from this control.
*/
void DeleteAllItems();
/** Delete item and all its subitems.
*/
void DeleteItem( CPropertyItem *pItem );
/** Add more variables.
@param szCategory Name of category to place var block, if NULL do not create new category.
@return Root item where this var block was added.
*/
CPropertyItem* AddVarBlock( CVarBlock *varBlock,const char *szCategory=NULL );
/** Set update callback to be used for this property window.
*/
void SetUpdateCallback( UpdateCallback &callback ) { m_updateFunc = callback; }
/** Set update callback to be used for this property window.
*/
void SetUpdateCallback( UpdateVarCallback &callback ) { m_updateVarFunc = callback; }
/** Enable of disable calling update callback when some values change.
*/
bool EnableUpdateCallback( bool bEnable );
/** Set selchange callback to be used for this property window.
*/
void SetSelChangeCallback( SelChangeCallback &callback ) { m_selChangeFunc = callback; }
/** Enable of disable calling selchange callback when the selection changes.
*/
bool EnableSelChangeCallback( bool bEnable );
/** Expand all categories.
*/
void ExpandAll();
/** Expand all childs of specified item.
*/
void ExpandAllChilds( CPropertyItem *item,bool bRecursive );
//! Expend this item
void Expand( CPropertyItem *item,bool bExpand );
/** Get pointer to root item
*/
CPropertyItem* GetRootItem() const { return m_root; };
/** Reload values back from xml nodes.
*/
void ReloadValues();
/** Change splitter value.
*/
void SetSplitter( int splitter ) { m_splitter = splitter; };
/** Get current value of splitter.
*/
int GetSplitter() const { return m_splitter; };
/** Get total height of all visible items.
*/
int GetVisibleHeight();
static void RegisterWindowClass();
void OnItemChange( CPropertyItem *item );
// Ovveride method defined in CWnd.
BOOL EnableWindow( BOOL bEnable = TRUE );
//! When set to true will only display values of modified parameters.
void SetDisplayOnlyModified( bool bEnable ) { m_bDisplayOnlyModified = bEnable; };
CRect GetItemValueRect( const CRect &rect );
void GetItemRect( CPropertyItem *item,CRect &rect );
//! Set height of item, (When F_VARIABLE_HEIGHT flag is set, this value is ignored)
void SetItemHeight( int nItemHeight );
//! Get height of item.
int GetItemHeight( CPropertyItem *item ) const;
void ClearSelection();
CPropertyItem* GetSelectedItem() { return m_selected; }
void SetRootName( const CString &rootName );
//! Find item that reference specified property.
CPropertyItem* FindItemByVar( IVariable *pVar );
void GetVisibleItems( CPropertyItem *root,Items &items );
bool IsCategory( CPropertyItem *item );
CPropertyItem* GetItemFromPoint( CPoint point );
void SelectItem( CPropertyItem *item );
void MultiSelectItem( CPropertyItem *pItem );
void MultiUnselectItem( CPropertyItem *pItem );
void MultiSelectRange( CPropertyItem *pAnchorItem );
protected:
friend CPropertyItem;
void DrawItem( CPropertyItem *item,CDC &dc,CRect &itemRect );
int CalcOffset( CPropertyItem *item );
void DrawSign( CDC &dc,CPoint point,bool plus );
void CreateInPlaceControl();
bool IsOverSplitter( CPoint point );
void ProcessTooltip( CPropertyItem *item );
void CalcLayout();
void Init();
void CopyItem( XmlNodeRef rootNode,CPropertyItem *pItem,bool bRecursively );
void OnCopy( bool bRecursively );
void OnCopyAll();
void OnPaste();
DECLARE_MESSAGE_MAP()
afx_msg UINT OnGetDlgCode();
afx_msg void OnDestroy();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg LRESULT OnGetFont(WPARAM wParam, LPARAM);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT_PTR nIDEvent);
//////////////////////////////////////////////////////////////////////////
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void PreSubclassWindow();
//////////////////////////////////////////////////////////////////////////
TSmartPtr<CPropertyItem> m_root;
XmlNodeRef m_xmlRoot;
bool m_bEnableCallback;
UpdateCallback m_updateFunc;
bool m_bEnableSelChangeCallback;
SelChangeCallback m_selChangeFunc;
UpdateVarCallback m_updateVarFunc;
CImageList m_icons;
CPropertyItem *m_selected;
CBitmap m_offscreenBitmap;
CPropertyItem *m_prevTooltipItem;
std::vector<CPropertyItem*> m_multiSelectedItems;
HCURSOR m_leftRightCursor;
CBrush m_bgBrush;
int m_splitter;
CPoint m_mouseDownPos;
bool m_bSplitterDrag;
CPoint m_scrollOffset;
CToolTipCtrl m_tooltip;
CFont *m_pBoldFont;
//! When set to true will only display values of modified items.
bool m_bDisplayOnlyModified;
//! Timer to track loose of focus.
int m_nTimer;
//! Item height.
int m_nItemHeight;
//! Control custom flags.
int m_nFlags;
};
#endif // __propertyctrl_h__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,317 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: propertyitem.h
// Version: v1.00
// Created: 5/6/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __propertyitem_h__
#define __propertyitem_h__
#if _MSC_VER > 1000
#pragma once
#endif
//! All possible property types.
enum PropertyType
{
ePropertyInvalid = 0,
ePropertyTable = 1,
ePropertyBool = 2,
ePropertyInt,
ePropertyFloat,
ePropertyVector,
ePropertyString,
ePropertyColor,
ePropertyAngle,
ePropertyFile,
ePropertyTexture,
ePropertySound,
ePropertyModel,
ePropertySelection,
ePropertyList,
ePropertyShader,
ePropertyMaterial,
ePropertyAiBehavior,
ePropertyAiAnchor,
ePropertyAiCharacter,
ePropertyEquip,
ePropertySoundPreset,
ePropertyEAXPreset,
ePropertyLocalString,
};
// forward declarations.
class CNumberCtrl;
class CPropertyCtrl;
class CInPlaceEdit;
class CInPlaceComboBox;
class CInPlaceButton;
struct IVariable;
/** Item of CPropertyCtrl.
Every property item reflects value of single XmlNode.
*/
class CPropertyItem : public CRefCountBase
{
public:
// Variables.
// Constructors.
CPropertyItem( CPropertyCtrl* pCtrl );
virtual ~CPropertyItem();
//! Set xml node to this property item.
virtual void SetXmlNode( XmlNodeRef &node );
//! Set variable.
virtual void SetVariable( IVariable *var );
//! Get Variable.
IVariable* GetVariable() const { return m_pVariable; }
/** Get type of property item.
*/
virtual int GetType() { return m_type; }
/** Get name of property item.
*/
virtual CString GetName() const { return m_name; };
/** Set name of property item.
*/
virtual void SetName( const char *sName ) { m_name = sName; };
/** Called when item becomes selected.
*/
virtual void SetSelected( bool selected );
/** Get if item is selected.
*/
bool IsSelected() const { return m_bSelected; };
/** Get if item is currently expanded.
*/
bool IsExpanded() const { return m_bExpanded; };
/** Get if item can be expanded (Have children).
*/
bool IsExpandable() const { return m_bExpandable; };
/** Check if item cannot be category.
*/
bool IsNotCategory() const { return m_bNoCategory; };
/** Check if item must be bold.
*/
bool IsBold() const;
/** Check if item must be disabled.
*/
bool IsDisabled() const;
/** Get height of this item.
*/
virtual int GetHeight() { return 14; }
/** Called by PropertyCtrl to draw value of this item.
*/
virtual void DrawValue( CDC *dc,CRect rect );
/** Called by PropertyCtrl when item selected to creare in place editing control.
*/
virtual void CreateInPlaceControl( CWnd* pWndParent,CRect& rect );
/** Called by PropertyCtrl when item deselected to destroy in place editing control.
*/
virtual void DestroyInPlaceControl();
/** Move in place control to new position.
*/
virtual void MoveInPlaceControl( const CRect& rect );
/** Set Focus to inplace control.
*/
virtual void SetFocus();
/** Set data from InPlace control to Item value.
*/
virtual void SetData( CWnd* pWndInPlaceControl ){};
//////////////////////////////////////////////////////////////////////////
// Mouse notifications.
//////////////////////////////////////////////////////////////////////////
virtual void OnLButtonDown( UINT nFlags,CPoint point );
virtual void OnRButtonDown( UINT nFlags,CPoint point ) {};
virtual void OnLButtonDblClk( UINT nFlags,CPoint point );
virtual void OnMouseWheel( UINT nFlags,short zDelta,CPoint point );
/** Changes value of item.
*/
virtual void SetValue( const char* sValue,bool bRecordUndo=true );
/** Returns current value of property item.
*/
virtual const char* GetValue() const;
/** Get Item's XML node.
*/
XmlNodeRef& GetXmlNode() { return m_node; };
//////////////////////////////////////////////////////////////////////////
//! Get description of this item.
CString GetTip() const;
//! Return image index of this property.
int GetImage() const { return m_image; };
//! Return true if this property item is modified.
bool IsModified() const { return m_modified; }
//////////////////////////////////////////////////////////////////////////
// Childs.
//////////////////////////////////////////////////////////////////////////
//! Expand child nodes.
virtual void SetExpanded( bool expanded );
//! Reload Value from Xml Node (hierarchicaly reload children also).
virtual void ReloadValues();
//! Get number of child nodes.
int GetChildCount() const { return m_childs.size(); };
//! Get Child by id.
CPropertyItem* GetChild( int index ) const { return m_childs[index]; };
//! Parent of this item.
CPropertyItem* GetParent() const { return m_parent; };
//! Add Child item.
void AddChild( CPropertyItem *item );
//! Delete child item.
void RemoveChild( CPropertyItem *item );
//! Find item that reference specified property.
CPropertyItem* FindItemByVar( IVariable *pVar );
//! Get full name, including names of all parents.
virtual CString GetFullName() const;
//! Find item by full specified item.
CPropertyItem* FindItemByFullName( const CString &name );
protected:
//////////////////////////////////////////////////////////////////////////
// Private methods.
//////////////////////////////////////////////////////////////////////////
void ReceiveFromControl();
void SendToControl();
void OnChildChanged( CPropertyItem *child );
void OnEditChanged();
void OnNumberCtrlUpdate( CNumberCtrl *ctrl );
void OnNumberCtrlBeginUpdate( CNumberCtrl *ctrl ) {};
void OnNumberCtrlEndUpdate( CNumberCtrl *ctrl ) {};
void OnComboSelection();
void OnColorBrowseButton();
void OnFileBrowseButton();
void OnShaderBrowseButton();
void OnAIBehaviorBrowseButton();
void OnAIAnchorBrowseButton();
void OnAICharacterBrowseButton();
void OnEquipBrowseButton();
void OnSoundPresetBrowseButton();
void OnEAXPresetBrowseButton();
void OnMaterialBrowseButton();
void ParseXmlNode( bool bRecursive=true );
//! String to color.
COLORREF StringToColor( const CString &value );
//! String to boolean.
bool GetBoolValue();
//! Convert variable value to value string.
CString VarToValue( IVariable *var );
//! Convert from value to variable.
void ValueToVar( const CString &value,IVariable *var );
//! Release used variable.
void ReleaseVariable();
//! Callback called when variable change.
void OnVariableChange( IVariable *var );
private:
CString m_name;
PropertyType m_type;
CString m_value;
CString m_prevValue;
//////////////////////////////////////////////////////////////////////////
// Flags for this property item.
//////////////////////////////////////////////////////////////////////////
//! True if item selected.
unsigned int m_bSelected : 1;
//! True if item currently expanded
unsigned int m_bExpanded : 1;
//! True if item can be expanded
unsigned int m_bExpandable : 1;
//! True if item can not be category.
unsigned int m_bNoCategory : 1;
//! If tru ignore update that comes from childs.
unsigned int m_bIgnoreChildsUpdate : 1;
//! True if item modified.
unsigned int m_modified : 1;
// Used for number controls.
float m_rangeMin;
float m_rangeMax;
int m_iInternalPrecision; //!< m.m. internal precision (digits behind the comma, only used for floats)
// Xml node.
XmlNodeRef m_node;
//! Pointer to the variable for this item.
TSmartPtr<IVariable> m_pVariable;
//////////////////////////////////////////////////////////////////////////
// InPlace controls.
CNumberCtrl* m_cNumber;
CInPlaceEdit* m_cEdit;
CInPlaceComboBox* m_cCombo;
CInPlaceButton* m_cButton;
//////////////////////////////////////////////////////////////////////////
//! Owner property control.
CPropertyCtrl* m_propertyCtrl;
//! Parent item.
CPropertyItem* m_parent;
// Enum.
IVarEnumListPtr m_enumList;
CString m_tip;
int m_image;
//! Last modified time in seconds.
float m_lastModified;
float m_valueMultiplier;
// Childs.
typedef std::vector<TSmartPtr<CPropertyItem> > Childs;
Childs m_childs;
};
#endif // __propertyitem_h__

View File

@@ -0,0 +1,147 @@
// RollupBar.cpp: implementation of the CRollupBar class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RollupBar.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRollupBar::CRollupBar()
{
CLogFile::WriteLine("RollUp bar created");
}
CRollupBar::~CRollupBar()
{
CLogFile::WriteLine("RollUp bar destroied");
}
BEGIN_MESSAGE_MAP(CRollupBar, CWnd)
//{{AFX_MSG_MAP(CWnd)
ON_WM_CREATE()
ON_NOTIFY( TCN_SELCHANGE, IDC_ROLLUPTAB, OnTabSelect )
ON_WM_SIZE()
ON_WM_CTLCOLOR()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
int CRollupBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//m_cImageList.Create(IDB_TREE_VIEW, 16, 1, RGB (255, 0, 255));
//m_tabImageList.Create(IDB_TABPANEL, 22, 1, RGB (0,255,255));
CMFCUtils::LoadTrueColorImageList( m_tabImageList,IDB_TABPANEL,22,TOOLBAR_TRANSPARENT_COLOR );
CRect rc;
m_tab.Create( TCS_HOTTRACK|TCS_TABS|TCS_FOCUSNEVER|TCS_SINGLELINE| WS_CHILD|WS_VISIBLE,rc,this,IDC_ROLLUPTAB );
m_tab.ModifyStyle( WS_BORDER,0,0 );
m_tab.ModifyStyleEx( WS_EX_CLIENTEDGE|WS_EX_STATICEDGE|WS_EX_WINDOWEDGE,0,0 );
m_tab.SetImageList( &m_tabImageList );
m_tab.InsertItem( 0,NULL,0 );
m_tab.InsertItem( 1,NULL,1 );
m_tab.InsertItem( 2,NULL,2 );
m_tab.InsertItem( 3,NULL,3 );
m_tab.SetFont( CFont::FromHandle( (HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );
m_selectedCtrl = 0;
return 0;
}
void CRollupBar::OnSize(UINT nType, int cx, int cy)
{
////////////////////////////////////////////////////////////////////////
// Resize
////////////////////////////////////////////////////////////////////////
RECT rcRollUp;
CWnd::OnSize(nType, cx, cy);
// Get the size of the client window
GetClientRect(&rcRollUp);
m_tab.MoveWindow( rcRollUp.left, rcRollUp.top,
rcRollUp.right,rcRollUp.bottom );
CRect rc;
for (int i = 0; i < m_controls.size(); i++)
{
CRect irc;
m_tab.GetItemRect( 0,irc );
m_tab.GetClientRect( rc );
if (m_controls[i])
{
rc.left += 1;
rc.right -= 2;
rc.top += irc.bottom-irc.top+8;
rc.bottom -= 2;
m_controls[i]->MoveWindow( rc );
}
}
/*
// Set the position of the listbox
m_pwndRollUpCtrl->SetWindowPos(NULL, rcRollUp.left + 3, rcRollUp.top + 3 + h, rcRollUp.right - 6,
rcRollUp.bottom - 6 - m_infoSize.cy - infoOfs - h, SWP_NOZORDER);
*/
}
void CRollupBar::OnTabSelect(NMHDR* pNMHDR, LRESULT* pResult)
{
int sel = m_tab.GetCurSel();
Select( sel );
}
void CRollupBar::Select( int num )
{
m_selectedCtrl = num;
for (int i = 0; i < m_controls.size(); i++)
{
if (i == num)
{
m_controls[i]->ShowWindow( SW_SHOW );
}
else
{
m_controls[i]->ShowWindow( SW_HIDE );
}
}
}
void CRollupBar::SetRollUpCtrl( int i,CRollupCtrl *pCtrl )
{
if (i >= m_controls.size())
{
m_controls.resize( i+1 );
}
pCtrl->SetParent( &m_tab );
m_controls[i] = pCtrl;
if (i != m_tab.GetCurSel())
{
m_controls[i]->ShowWindow( SW_HIDE );
}
}
CRollupCtrl* CRollupBar::GetCurrentCtrl()
{
ASSERT( m_selectedCtrl < m_controls.size() );
return m_controls[m_selectedCtrl];
}

View File

@@ -0,0 +1,45 @@
// RollupBar.h: interface for the CRollupBar class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_ROLLUPBAR_H__4FB67648_FCE7_4827_A538_FE0D05FDE4C6__INCLUDED_)
#define AFX_ROLLUPBAR_H__4FB67648_FCE7_4827_A538_FE0D05FDE4C6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "sizecbar.h"
#include "scbarg.h"
#include "RollupCtrl.h"
#define OBJECTS_BAR 0
#define TERRAIN_BAR 1
class CRollupBar : public CWnd
{
public:
CRollupBar();
virtual ~CRollupBar();
void SetRollUpCtrl( int i,CRollupCtrl *pCtrl );
//! Select Object/Terrain
void Select( int num );
int GetSelection() { return m_selectedCtrl; };
CRollupCtrl* GetCurrentCtrl();
protected:
//{{AFX_MSG(CMyBar)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnTabSelect(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CTabCtrl m_tab;
CImageList m_tabImageList;
std::vector<CRollupCtrl*> m_controls;
int m_selectedCtrl;
};
#endif // !defined(AFX_ROLLUPBAR_H__4FB67648_FCE7_4827_A538_FE0D05FDE4C6__INCLUDED_)

View File

@@ -0,0 +1,905 @@
//////////////////////////////////////////////////////////////////////////////
//
// RollupCtrl.cpp
//
// Code Johann Nadalutti
// Mail: jnadalutti@worldonline.fr
//
//////////////////////////////////////////////////////////////////////////////
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
//////////////////////////////////////////////////////////////////////////////
//
// History
// --------
// #v1.0
// 31/03/01: Created
//
// #v1.01
// 13/04/01: Added ScrollToPage() method
// Added automatic page visibility to ExpandPage() method
// Added Mousewheel support
// 15/04/01: Added mouse capture checking on WM_MOUSEMOVE dialog msg
// Added SetCursor() on Dialog WM_SETCURSOR
// Added MovePageAt() method
// 17/04/01: Fixed Group Boxes displayed over Buttons
// 20/04/01: Added IsPageExpanded() and IsPageExpanded() methods
// Added PopupMenu
// Added Button subclassing (now button's focus not drawn)
//
// Note
// -----
// Dialog box width is
// RollupCtrlClientRect.Width() - RC_SCROLLBARWIDTH - (RC_GRPBOXINDENT*2)
//
//
// Thanks to
// ----------
// PJ Arends, Ramon Smits, Uwe Keim, Daniel Madden, Do Quyet Tien,
// Ravi Bhavnani, Masaaki Onishi, ...
// and all others users for their comments.
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl Includes
#include "stdafx.h"
#include "RollupCtrl.h"
#include "XTToolkit.h"
/////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl Message Map
BEGIN_MESSAGE_MAP(CRollupCtrl, CWnd)
//{{AFX_MSG_MAP(CRollupCtrl)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_MOUSEACTIVATE()
ON_WM_CONTEXTMENU()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl Implementation
IMPLEMENT_DYNCREATE(CRollupCtrl, CWnd)
//---------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------
CRollupCtrl::CRollupCtrl()
{
static CBrush brush;
if (!brush.GetSafeHandle())
brush.CreateSolidBrush(CXTColorRef::GetColor(COLOR_BTNFACE));
m_strMyClass = AfxRegisterWndClass(
CS_VREDRAW | CS_HREDRAW,
(HCURSOR)::LoadCursor(NULL, IDC_ARROW),
(HBRUSH)brush.GetSafeHandle(),
//
//COLORREF clr = CXTColorRef::GetColor(COLOR_BACKGROUND);
//(HBRUSH) COLOR_BACKGROUND,
NULL);
m_nStartYPos = m_nPageHeight = 0;
m_lastId = 0;
}
//---------------------------------------------------------------------------
// Destructor
//---------------------------------------------------------------------------
CRollupCtrl::~CRollupCtrl()
{
//Remove all pages allocations
for (int i=0; i<m_PageList.size(); i++) {
if (m_PageList[i]->pwndButton) delete m_PageList[i]->pwndButton;
if (m_PageList[i]->pwndGroupBox) delete m_PageList[i]->pwndGroupBox;
if (m_PageList[i]->pwndTemplate && m_PageList[i]->bAutoDestroyTpl) {
m_PageList[i]->pwndTemplate->DestroyWindow();
delete m_PageList[i]->pwndTemplate;
}
delete m_PageList[i];
}
CLogFile::WriteLine("RollUp control destroyed");
}
//---------------------------------------------------------------------------
// Create
//---------------------------------------------------------------------------
BOOL CRollupCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
return CWnd::Create(m_strMyClass, "RollupCtrl", dwStyle, rect, pParentWnd, nID);
}
//---------------------------------------------------------------------------
// Function name : InsertPage
// Description : Return -1 if an error occurs
// Make sure template had WS_CHILD style
//---------------------------------------------------------------------------
int CRollupCtrl::InsertPage(LPCTSTR caption, UINT nIDTemplate, CRuntimeClass* rtc, int idx)
{
if (idx>0 && idx>=m_PageList.size()) idx=-1;
//Create Template
ASSERT(rtc!=NULL);
CDialog* pwndTemplate = (CDialog*)rtc->CreateObject();
BOOL b = pwndTemplate->Create(nIDTemplate, this);
if (!b) { delete pwndTemplate; return -1; }
//Insert Page
return _InsertPage(caption, pwndTemplate, idx, TRUE);
}
//---------------------------------------------------------------------------
// Function name : InsertPage
// Description : return -1 if an error occurs
// Make sure template had WS_CHILD style
//---------------------------------------------------------------------------
int CRollupCtrl::InsertPage(LPCTSTR caption, CDialog* pwndTemplate, BOOL bAutoDestroyTpl, int idx)
{
if (!pwndTemplate) return -1;
if (idx>0 && idx>=m_PageList.size()) idx=-1;
pwndTemplate->SetParent( this );
//Insert Page
return _InsertPage(caption, pwndTemplate, idx, bAutoDestroyTpl);
}
//---------------------------------------------------------------------------
// Function name : InsertPage
// Description : Called by InsertPage(...) methods
// Return -1 if an error occurs
// Make sure template had WS_CHILD style
//---------------------------------------------------------------------------
int CRollupCtrl::_InsertPage(LPCTSTR caption, CDialog* pwndTemplate, int idx, BOOL bAutoDestroyTpl)
{
ASSERT(pwndTemplate!=NULL);
ASSERT(pwndTemplate->m_hWnd!=NULL);
//Get client rect
CRect r; GetClientRect(r);
//Create GroupBox
CButton* groupbox = new CButton;
groupbox->Create("", WS_CHILD|BS_GROUPBOX, r, this, 0 );
//Create Button
CButton* but = new CButton;
but->Create(caption, WS_CHILD|BS_AUTOCHECKBOX|BS_PUSHLIKE|BS_FLAT, r, this, 0 );
//Change Button's font
HFONT hfont= (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
CFont* font = CFont::FromHandle(hfont);
but->SetFont(font);
//Add page at pagelist
RC_PAGEINFO* pi = new RC_PAGEINFO;
pi->id = m_lastId++;
pi->bExpanded = FALSE;
pi->bEnable = TRUE;
pi->pwndTemplate = pwndTemplate;
pi->pwndButton = but;
pi->pwndGroupBox = groupbox;
pi->pOldDlgProc = (WNDPROC)::GetWindowLongPtr(pwndTemplate->m_hWnd, DWLP_DLGPROC);
pi->pOldButProc = (WNDPROC)::GetWindowLongPtr(but->m_hWnd, GWLP_WNDPROC);
pi->bAutoDestroyTpl = bAutoDestroyTpl;
int newidx;
if (idx<0) {
m_PageList.push_back(pi);
newidx = m_PageList.size()-1;
}
else { m_PageList.insert(m_PageList.begin()+idx,pi); newidx=idx; }
//Set Dlg Window datas
::SetWindowLongPtr(pwndTemplate->m_hWnd, GWLP_USERDATA, (LONG_PTR)m_PageList[newidx]);
::SetWindowLongPtr(pwndTemplate->m_hWnd, DWLP_USER, (LONG_PTR)this);
//Set But Window data
::SetWindowLongPtr(but->m_hWnd, GWLP_USERDATA, (LONG_PTR)m_PageList[newidx]);
//SubClass Template window proc
::SetWindowLongPtr(pwndTemplate->m_hWnd, DWLP_DLGPROC, (LONG_PTR)CRollupCtrl::DlgWindowProc);
//SubClass Button window proc
::SetWindowLongPtr(but->m_hWnd, GWLP_WNDPROC, (LONG_PTR)CRollupCtrl::ButWindowProc);
//Update
m_nPageHeight+=RC_PGBUTTONHEIGHT+(RC_GRPBOXINDENT/2);
RecalLayout();
// Override expended flag based on settings in map.
bool bExpanded = stl::find_in_map( m_expandedMap,caption,true );
if (bExpanded)
ExpandPage( pi->id,bExpanded,FALSE );
//pi->bExpanded = bExpanded;
return pi->id;
}
//---------------------------------------------------------------------------
// Function name : RemovePage
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::RemovePage(int idx)
{
if (!FindPage(idx))
return;
//Remove
_RemovePage(idx);
//Update
RecalLayout();
}
//---------------------------------------------------------------------------
// Function name : RemoveAllPages
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::RemoveAllPages()
{
//Remove all
for (; m_PageList.size();)
_RemovePage( m_PageList[0]->id );
//Update
RecalLayout();
}
//---------------------------------------------------------------------------
// Function name : _RemovePage
// Description : Called by RemovePage or RemoveAllPages methods
//---------------------------------------------------------------------------
void CRollupCtrl::_RemovePage(int idx)
{
// Find page
RC_PAGEINFO* pi = FindPage(idx);
//Remove page from array
m_PageList.erase( m_PageList.begin() + FindPageIndex(idx) );
//Get Page Rect
CRect tr; pi->pwndTemplate->GetWindowRect(&tr);
//Update PageHeight
m_nPageHeight-=RC_PGBUTTONHEIGHT+(RC_GRPBOXINDENT/2);
if (pi->bExpanded) m_nPageHeight-=tr.Height();
//Remove wnds
if (pi->pwndButton) delete pi->pwndButton;
if (pi->pwndGroupBox) delete pi->pwndGroupBox;
// fix
::SetWindowLongPtr(pi->pwndTemplate->m_hWnd, DWLP_DLGPROC, (LONG_PTR)pi->pOldDlgProc);
if (pi->pwndTemplate && pi->bAutoDestroyTpl)
{
pi->pwndTemplate->DestroyWindow();
delete pi->pwndTemplate;
} else {
pi->pwndTemplate->ShowWindow(SW_HIDE);
}
//Delete pageinfo
delete pi;
}
//---------------------------------------------------------------------------
// Function name : ExpandPage
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::ExpandPage(int idx, BOOL bExpand,BOOL bScroll)
{
if (!FindPage(idx))
return;
//Expand-collapse
_ExpandPage( FindPage(idx), bExpand);
//Update
RecalLayout();
//Scroll to this page (Automatic page visibility)
if (bExpand && bScroll)
ScrollToPage(idx, FALSE);
}
//---------------------------------------------------------------------------
// Function name : ExpandAllPages
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::ExpandAllPages(BOOL bExpand)
{
//Expand-collapse All
for (int i=0; i<m_PageList.size(); i++)
_ExpandPage(m_PageList[i], bExpand);
//Update
RecalLayout();
}
//---------------------------------------------------------------------------
// Function name : _ExpandPage
// Description : Called by ExpandPage or ExpandAllPages methods
//---------------------------------------------------------------------------
void CRollupCtrl::_ExpandPage(RC_PAGEINFO* pi, BOOL bExpand)
{
//Check if we need to change state
if (pi->bExpanded==bExpand) return;
if (!pi->bEnable) return;
//Get Page Rect
CRect tr; pi->pwndTemplate->GetWindowRect(&tr);
//Expand-collapse
pi->bExpanded = bExpand;
CString caption;
pi->pwndButton->GetWindowText( caption );
m_expandedMap[caption] = pi->bExpanded == TRUE;
if (bExpand) m_nPageHeight+=tr.Height();
else m_nPageHeight-=tr.Height();
}
//---------------------------------------------------------------------------
// Function name : EnablePage
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::EnablePage(int idx, BOOL bEnable)
{
if (!FindPage(idx))
return;
//Enable-Disable
_EnablePage(FindPage(idx), bEnable);
//Update
RecalLayout();
}
//---------------------------------------------------------------------------
// Function name : EnableAllPages
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::EnableAllPages(BOOL bEnable)
{
//Enable-disable All
for (int i=0; i<m_PageList.size(); i++)
_EnablePage(m_PageList[i], bEnable);
//Update
RecalLayout();
}
//---------------------------------------------------------------------------
// Function name : _EnablePage
// Description : Called by EnablePage or EnableAllPages methods
//---------------------------------------------------------------------------
void CRollupCtrl::_EnablePage(RC_PAGEINFO* pi, BOOL bEnable)
{
//Check if we need to change state
if (pi->bEnable==bEnable) return;
//Get Page Rect
CRect tr; pi->pwndTemplate->GetWindowRect(&tr);
//Change state
pi->bEnable = bEnable;
if (pi->bExpanded) { m_nPageHeight-=tr.Height(); pi->bExpanded=FALSE; }
}
//---------------------------------------------------------------------------
// Function name : ScrollToPage
// Description : Scroll a page at the top of the RollupCtrl if bAtTheTop=TRUE
// or just ensure page visibility into view if bAtTheTop=FALSE
//---------------------------------------------------------------------------
void CRollupCtrl::ScrollToPage(int idx, BOOL bAtTheTop)
{
if (!FindPage(idx))
return;
//Get page infos
RC_PAGEINFO* pi = FindPage(idx);
//Get windows rect
CRect r; GetWindowRect(&r);
CRect tr; pi->pwndTemplate->GetWindowRect(&tr);
//Check page visibility
if (bAtTheTop || ((tr.bottom>r.bottom) || (tr.top<r.top)))
{
//Compute new m_nStartYPos
pi->pwndButton->GetWindowRect(&tr);
m_nStartYPos-= (tr.top-r.top);
//Update
RecalLayout();
}
}
//---------------------------------------------------------------------------
// Function name : MovePageAt
// Description : newidx can be equal to -1 (move at end)
// Return -1 if an error occurs
//---------------------------------------------------------------------------
int CRollupCtrl::MovePageAt(int id, int newidx)
{
if (!FindPage(id)) return -1;
int idx = FindPageIndex(id);
if (idx==newidx) return -1;
if (newidx>0 && newidx>=m_PageList.size()) newidx=-1;
//Remove page from its old position
RC_PAGEINFO* pi = FindPage(id);
m_PageList.erase( m_PageList.begin() + FindPageIndex(id) );
//Insert at its new position
int retidx;
if (newidx<0)
{
m_PageList.push_back(pi);
retidx = m_PageList.size()-1;
}
else { m_PageList.insert( m_PageList.begin()+newidx, pi); retidx=newidx; }
//Update
RecalLayout();
return retidx;
}
//---------------------------------------------------------------------------
// Function name : IsPageExpanded
// Description :
//---------------------------------------------------------------------------
BOOL CRollupCtrl::IsPageExpanded(int idx)
{
if (!FindPage(idx))
return FALSE;
return FindPage(idx)->bExpanded;
}
//---------------------------------------------------------------------------
// Function name : IsPageEnabled
// Description :
//---------------------------------------------------------------------------
BOOL CRollupCtrl::IsPageEnabled(int idx)
{
if (!FindPage(idx))
return FALSE;
return FindPage(idx)->bEnable;
}
//---------------------------------------------------------------------------
// Function name : RecalLayout
// Description :
//---------------------------------------------------------------------------
void CRollupCtrl::RecalLayout()
{
//Check StartPosY
CRect r; GetClientRect(&r);
int BottomPagePos = m_nStartYPos+m_nPageHeight;
if (BottomPagePos<r.Height()) m_nStartYPos = r.Height()-m_nPageHeight;
if (m_nStartYPos>0) m_nStartYPos = 0;
//Update layout
HDWP hdwp = BeginDeferWindowPos(m_PageList.size()*3); //*3 for pwndButton+pwndTemplate+pwndGroupBox
int posy=m_nStartYPos;
for (int i=0; i<m_PageList.size(); i++){
RC_PAGEINFO* pi = m_PageList[i];
//Enable-Disable Button
pi->pwndButton->SetCheck(pi->bEnable&pi->bExpanded);
pi->pwndButton->EnableWindow(pi->bEnable);
//Expanded
if (pi->bExpanded && pi->bEnable) {
CRect tr; pi->pwndTemplate->GetWindowRect(&tr);
//Update GroupBox position and size
DeferWindowPos(hdwp, pi->pwndGroupBox->m_hWnd, 0, 2, posy, r.Width()-3-RC_SCROLLBARWIDTH, tr.Height()+RC_PGBUTTONHEIGHT+RC_GRPBOXINDENT-4, SWP_NOZORDER|SWP_SHOWWINDOW);
//Update Template position and size
DeferWindowPos(hdwp, pi->pwndTemplate->m_hWnd, 0, RC_GRPBOXINDENT, posy+RC_PGBUTTONHEIGHT, r.Width()-RC_SCROLLBARWIDTH-(RC_GRPBOXINDENT*2), tr.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
//Update Button's position and size
DeferWindowPos(hdwp, pi->pwndButton->m_hWnd, 0, RC_GRPBOXINDENT, posy, r.Width()-RC_SCROLLBARWIDTH-(RC_GRPBOXINDENT*2), RC_PGBUTTONHEIGHT, SWP_NOZORDER|SWP_SHOWWINDOW);
posy+=tr.Height()+RC_PGBUTTONHEIGHT+4;
//Collapsed
} else {
//Update GroupBox position and size
DeferWindowPos(hdwp, pi->pwndGroupBox->m_hWnd, 0, 2, posy, r.Width()-3-RC_SCROLLBARWIDTH, 16,SWP_NOZORDER|SWP_SHOWWINDOW);
//Update Template position and size
DeferWindowPos(hdwp, pi->pwndTemplate->m_hWnd, 0, RC_GRPBOXINDENT, 0, 0, 0,SWP_NOZORDER|SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE);
//Update Button's position and size
DeferWindowPos(hdwp, pi->pwndButton->m_hWnd, 0, RC_GRPBOXINDENT, posy, r.Width()-RC_SCROLLBARWIDTH-(RC_GRPBOXINDENT*2), RC_PGBUTTONHEIGHT, SWP_NOZORDER|SWP_SHOWWINDOW);
posy+=RC_PGBUTTONHEIGHT;
}
posy+=(RC_GRPBOXINDENT/2);
}
EndDeferWindowPos(hdwp);
//Update Scroll Bar
CRect br = CRect(r.right-RC_SCROLLBARWIDTH,r.top, r.right, r.bottom);
InvalidateRect(&br, FALSE);
UpdateWindow();
}
//---------------------------------------------------------------------------
// Function name : GetPageIdxFromButtonHWND
// Description : Return -1 if matching hwnd not found
//---------------------------------------------------------------------------
int CRollupCtrl::GetPageIdxFromButtonHWND(HWND hwnd)
{
//Search matching button's hwnd
for (int i=0; i<m_PageList.size(); i++)
if (hwnd==m_PageList[i]->pwndButton->m_hWnd) return i;
return -1;
}
//---------------------------------------------------------------------------
// Function name : GetPageInfo
// Description : Return -1 if an error occurs
//---------------------------------------------------------------------------
RC_PAGEINFO* CRollupCtrl::GetPageInfo(int idx)
{
if (!FindPage(idx))
return (RC_PAGEINFO*)-1;
return FindPage(idx);
}
//---------------------------------------------------------------------------
// Dialog SubClasser
//---------------------------------------------------------------------------
LRESULT CALLBACK CRollupCtrl::DlgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RC_PAGEINFO* pi = (RC_PAGEINFO*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
CRollupCtrl* _this = (CRollupCtrl*)GetWindowLongPtr(hWnd, DWLP_USER);
CRect r; _this->GetClientRect(&r);
if (_this->m_nPageHeight>r.Height()) //Can Scroll ?
{
switch (uMsg) {
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
{
CPoint pos; GetCursorPos(&pos);
_this->m_nOldMouseYPos = pos.y;
::SetCapture(hWnd);
return 0;
}
case WM_LBUTTONUP:
case WM_MBUTTONUP:
{
if (::GetCapture() == hWnd) { ::ReleaseCapture(); return 0; }
break;
}
case WM_MOUSEMOVE:
{
if ((::GetCapture() == hWnd) && (wParam==MK_LBUTTON || wParam==MK_MBUTTON)) {
CPoint pos; GetCursorPos(&pos);
_this->m_nStartYPos+=(pos.y-_this->m_nOldMouseYPos);
_this->RecalLayout();
_this->m_nOldMouseYPos = pos.y;
return 0;
}
break;
}
case WM_SETCURSOR:
if ((HWND)wParam==hWnd) { ::SetCursor(::LoadCursor(NULL, RC_ROLLCURSOR)); return TRUE; }
break;
}//switch(uMsg)
}
return ::CallWindowProc(pi->pOldDlgProc, hWnd, uMsg, wParam, lParam);
}
//---------------------------------------------------------------------------
// Button SubClasser
//---------------------------------------------------------------------------
LRESULT CALLBACK CRollupCtrl::ButWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg==WM_SETFOCUS) return FALSE;
RC_PAGEINFO* pi = (RC_PAGEINFO*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
return ::CallWindowProc(pi->pOldButProc, hWnd, uMsg, wParam, lParam);
}
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl message handlers
//---------------------------------------------------------------------------
// OnCommand
//---------------------------------------------------------------------------
BOOL CRollupCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
{
//PopupMenu command ExpandAllPages
if (LOWORD(wParam)==RC_IDM_EXPANDALL) ExpandAllPages(TRUE);
else if (LOWORD(wParam)==RC_IDM_COLLAPSEALL) ExpandAllPages(FALSE);
//PopupMenu command ExpandPage
else if (LOWORD(wParam)>=RC_IDM_STARTPAGES
&& LOWORD(wParam)<RC_IDM_STARTPAGES+GetPagesCount())
{
int idx = LOWORD(wParam)-RC_IDM_STARTPAGES;
int id = m_PageList[idx]->id;
ExpandPage(id, !IsPageExpanded(id) );
}
//Button command
else if (HIWORD(wParam)==BN_CLICKED)
{
int idx = GetPageIdxFromButtonHWND((HWND)lParam);
if (idx!=-1) {
RC_PAGEINFO* pi = m_PageList[idx];
ExpandPage(pi->id, !pi->bExpanded);
return 0;
}
}
return CWnd::OnCommand(wParam, lParam);
}
//---------------------------------------------------------------------------
// OnPaint
//---------------------------------------------------------------------------
void CRollupCtrl::OnPaint()
{
CPaintDC dc(this);
//Draw ScrollBar
CRect r; GetClientRect(&r);
CRect br = CRect(r.right-RC_SCROLLBARWIDTH,r.top, r.right, r.bottom);
dc.DrawEdge(&br, EDGE_RAISED, BF_RECT );
int SB_Pos = 0;
int SB_Size = 0;
int ClientHeight = r.Height()-4;
if (m_nPageHeight>r.Height()) {
SB_Size = ClientHeight-(((m_nPageHeight-r.Height())*ClientHeight)/m_nPageHeight);
SB_Pos = -(m_nStartYPos*ClientHeight)/m_nPageHeight;
} else {
SB_Size = ClientHeight;
}
br.left +=2;
br.right -=1;
br.top = SB_Pos+2;
br.bottom = br.top+SB_Size;
dc.FillSolidRect(&br, RC_SCROLLBARCOLOR);
dc.FillSolidRect(CRect(br.left,2,br.right,br.top), RGB(0,0,0));
dc.FillSolidRect(CRect(br.left,br.bottom,br.right,2+ClientHeight), RGB(0,0,0));
// Do not call CWnd::OnPaint() for painting messages
}
//---------------------------------------------------------------------------
// OnSize
//---------------------------------------------------------------------------
void CRollupCtrl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
RecalLayout();
}
//---------------------------------------------------------------------------
// OnLButtonDown
//---------------------------------------------------------------------------
void CRollupCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect r; GetClientRect(&r);
if (m_nPageHeight<=r.Height()) return; //Can't Scroll
CRect br = CRect(r.right-RC_SCROLLBARWIDTH,r.top, r.right, r.bottom);
if ((nFlags&MK_LBUTTON) && br.PtInRect(point)) {
SetCapture();
int ClientHeight = r.Height()-4;
int SB_Size = ClientHeight-(((m_nPageHeight-r.Height())*ClientHeight)/m_nPageHeight);
int SB_Pos = -(m_nStartYPos*ClientHeight)/m_nPageHeight;
//Click inside scrollbar cursor
if ((point.y<(SB_Pos+SB_Size)) && (point.y>SB_Pos)) {
m_nSBOffset = SB_Pos-point.y+1;
//Click outside scrollbar cursor (2 cases => above or below cursor)
} else {
int distup = point.y-SB_Pos;
int distdown= (SB_Pos+SB_Size)-point.y;
if (distup<distdown) m_nSBOffset = 0; //above
else m_nSBOffset = -SB_Size; //below
}
//Calc new m_nStartYPos from mouse pos
int TargetPos = point.y + m_nSBOffset;
m_nStartYPos=-(TargetPos*m_nPageHeight)/ClientHeight;
//Update
RecalLayout();
}
CWnd::OnLButtonDown(nFlags, point);
}
//---------------------------------------------------------------------------
// OnLButtonUp
//---------------------------------------------------------------------------
void CRollupCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
if (GetCapture()==this) ReleaseCapture();
CWnd::OnLButtonUp(nFlags, point);
}
//---------------------------------------------------------------------------
// OnMouseMove
//---------------------------------------------------------------------------
void CRollupCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
CRect r; GetClientRect(&r);
if (m_nPageHeight<=r.Height()) return; //Can't Scroll
CRect br = CRect(r.right-RC_SCROLLBARWIDTH,r.top, r.right, r.bottom);
if ((nFlags&MK_LBUTTON) && (GetCapture()==this)) {
//Calc new m_nStartYPos from mouse pos
int ClientHeight = r.Height()-4;
int TargetPos = point.y + m_nSBOffset;
m_nStartYPos=-(TargetPos*m_nPageHeight)/ClientHeight;
//Update
RecalLayout();
}
CWnd::OnMouseMove(nFlags, point);
}
//---------------------------------------------------------------------------
// OnMouseWheel
//---------------------------------------------------------------------------
BOOL CRollupCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
//Calc new m_nStartYPos
m_nStartYPos+=(zDelta/4);
//Update
RecalLayout();
return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}
//---------------------------------------------------------------------------
// OnMouseActivate
//---------------------------------------------------------------------------
int CRollupCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
//Timur
//SetFocus();
//Timur
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
//---------------------------------------------------------------------------
// OnContextMenu
//---------------------------------------------------------------------------
void CRollupCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu menu;
if (menu.CreatePopupMenu())
{
menu.AppendMenu(MF_STRING, RC_IDM_EXPANDALL, "Expand all" );
menu.AppendMenu(MF_STRING, RC_IDM_COLLAPSEALL, "Collapse all" );
menu.AppendMenu(MF_SEPARATOR, 0, "" );
//Add all pages with checked style for expanded ones
for (int i=0; i<m_PageList.size(); i++) {
CString cstrPageName;
m_PageList[i]->pwndButton->GetWindowText(cstrPageName);
menu.AppendMenu(MF_STRING, RC_IDM_STARTPAGES+i, cstrPageName);
if (m_PageList[i]->bExpanded)
menu.CheckMenuItem(RC_IDM_STARTPAGES+i, MF_CHECKED);
}
menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x, point.y, this);
}
}
RC_PAGEINFO* CRollupCtrl::FindPage( int id )
{
for (int i = 0; i < m_PageList.size(); i++)
{
if (m_PageList[i]->id == id)
{
return m_PageList[i];
}
}
return 0;
}
int CRollupCtrl::FindPageIndex( int id )
{
for (int i = 0; i < m_PageList.size(); i++)
{
if (m_PageList[i]->id == id)
{
return i;
}
}
return 0;
}

View File

@@ -0,0 +1,180 @@
//////////////////////////////////////////////////////////////////////////////
//
// RollupCtrl.h
//
// Code Johann Nadalutti
// Mail: jnadalutti@worldonline.fr
//
//////////////////////////////////////////////////////////////////////////////
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
//////////////////////////////////////////////////////////////////////////////
//
// History
// --------
// #v1.0
// 31/03/01: Created
//
// #v1.01
// 13/04/01: Added ScrollToPage() method
// Added automatic page visibility to ExpandPage() method
// Added Mousewheel support
// 15/04/01: Added mouse capture checking on WM_MOUSEMOVE dialog msg
// Added SetCursor() on Dialog WM_SETCURSOR
// Added MovePageAt() method
// 17/04/01: Fixed Group Boxes displayed over Buttons
// 20/04/01: Added IsPageExpanded() and IsPageExpanded() methods
// Added PopupMenu
// Added Button subclassing (now button's focus not drawn)
//
// Note
// -----
// Dialog box width is
// RollupCtrlClientRect.Width() - RC_SCROLLBARWIDTH - (RC_GRPBOXINDENT*2)
//
//
// Thanks to
// ----------
// PJ Arends, Ramon Smits, Uwe Keim, Daniel Madden, Do Quyet Tien,
// Ravi Bhavnani, Masaaki Onishi, ...
// and all others users for their comments.
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ROLLUPCTRL_H__23BA7472_F13A_11D4_AC77_0050BADF98BC__INCLUDED_)
#define AFX_ROLLUPCTRL_H__23BA7472_F13A_11D4_AC77_0050BADF98BC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl include
#include <afxtempl.h>
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl structure and defines
struct RC_PAGEINFO {
CWnd* pwndTemplate;
CButton* pwndButton;
CButton* pwndGroupBox;
BOOL bExpanded;
BOOL bEnable;
BOOL bAutoDestroyTpl;
WNDPROC pOldDlgProc; //Old wndTemplate(Dialog) window proc
WNDPROC pOldButProc; //Old wndTemplate(Dialog) window proc
int id;
};
#define RC_PGBUTTONHEIGHT 18
#define RC_SCROLLBARWIDTH 6
#define RC_GRPBOXINDENT 6
#define RC_SCROLLBARCOLOR RGB(150,180,180)
#define RC_ROLLCURSOR MAKEINTRESOURCE(32649) // see IDC_HAND (WINVER >= 0x0500)
//Popup Menu Ids
#define RC_IDM_EXPANDALL 0x100
#define RC_IDM_COLLAPSEALL 0x101
#define RC_IDM_STARTPAGES 0x102
/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl class definition
class CRollupCtrl : public CWnd
{
DECLARE_DYNCREATE(CRollupCtrl)
public:
// Constructor-Destructor
CRollupCtrl();
virtual ~CRollupCtrl();
// Methods
BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
int InsertPage(LPCTSTR caption, CDialog* pwndTemplate, BOOL bAutoDestroyTpl=TRUE, int idx=-1); //Return page zero-based index
int InsertPage(LPCTSTR caption, UINT nIDTemplate, CRuntimeClass* rtc, int idx=-1); //Return page zero-based index
void RemovePage(int idx); //idx is a zero-based index
void RemoveAllPages();
void ExpandPage(int idx, BOOL bExpand=TRUE,BOOL bScrool=TRUE); //idx is a zero-based index
void ExpandAllPages(BOOL bExpand=TRUE);
void EnablePage(int idx, BOOL bEnable=TRUE); //idx is a zero-based index
void EnableAllPages(BOOL bEnable=TRUE);
int GetPagesCount() { return m_PageList.size(); }
RC_PAGEINFO* GetPageInfo(int idx); //idx is a zero-based index
// New v1.01 Methods
void ScrollToPage(int idx, BOOL bAtTheTop=TRUE);
int MovePageAt(int idx, int newidx); //newidx can be equal to -1 (move at end)
BOOL IsPageExpanded(int idx);
BOOL IsPageEnabled(int idx);
protected:
// Internal methods
void RecalLayout();
int GetPageIdxFromButtonHWND(HWND hwnd);
void _RemovePage(int idx);
void _ExpandPage(RC_PAGEINFO* pi, BOOL bExpand);
void _EnablePage(RC_PAGEINFO* pi, BOOL bEnable);
int _InsertPage(LPCTSTR caption, CDialog* dlg, int idx, BOOL bAutoDestroyTpl);
RC_PAGEINFO* FindPage( int id );
int FindPageIndex( int id );
// Datas
CString m_strMyClass;
std::vector<RC_PAGEINFO*> m_PageList;
int m_nStartYPos, m_nPageHeight;
int m_nOldMouseYPos, m_nSBOffset;
int m_lastId;
std::map<CString,bool> m_expandedMap;
// Window proc
static LRESULT CALLBACK DlgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ButWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRollupCtrl)
protected:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CRollupCtrl)
afx_msg void OnPaint();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
#endif // !defined(AFX_ROLLUPCTRL_H__23BA7472_F13A_11D4_AC77_0050BADF98BC__INCLUDED_)

View File

@@ -0,0 +1,91 @@
// SelectionCombo.cpp : implementation file
//
#include "stdafx.h"
#include "SelectionCombo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSelectionCombo
CSelectionCombo::CSelectionCombo()
{
}
CSelectionCombo::~CSelectionCombo()
{
}
BEGIN_MESSAGE_MAP(CSelectionCombo, CXTFlatComboBox)
//{{AFX_MSG_MAP(CSelectionCombo)
ON_WM_GETDLGCODE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSelectionCombo message handlers
BOOL CSelectionCombo::Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )
{
return CXTFlatComboBox::Create( dwStyle,rect,pParentWnd,nID );
}
UINT CSelectionCombo::OnGetDlgCode()
{
return DLGC_WANTMESSAGE;
}
BOOL CSelectionCombo::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_RETURN)
{
NMCBEENDEDIT endEdit;
endEdit.hdr.code = CBEN_ENDEDIT;
endEdit.hdr.hwndFrom = m_hWnd;
endEdit.hdr.idFrom = GetDlgCtrlID();
endEdit.fChanged = true;
endEdit.iNewSelection = CB_ERR;
endEdit.iWhy = CBENF_RETURN;
CString text;
GetWindowText( text );
strcpy( endEdit.szText,text );
GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&endEdit) );
return TRUE;
}
if (pMsg->wParam == VK_ESCAPE)
{
SetWindowText( "" );
return TRUE;
}
}
if (pMsg->message == WM_KILLFOCUS)
{
NMCBEENDEDIT endEdit;
endEdit.hdr.code = CBEN_ENDEDIT;
endEdit.hdr.hwndFrom = m_hWnd;
endEdit.hdr.idFrom = GetDlgCtrlID();
endEdit.fChanged = true;
endEdit.iNewSelection = CB_ERR;
endEdit.iWhy = CBENF_KILLFOCUS;
CString text;
GetWindowText( text );
strcpy( endEdit.szText,text );
GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&endEdit) );
return TRUE;
}
return CXTFlatComboBox::PreTranslateMessage(pMsg);
}

View File

@@ -0,0 +1,54 @@
#if !defined(AFX_SELECTIONCOMBO_H__66952646_5AAD_4182_AC95_845711841B8D__INCLUDED_)
#define AFX_SELECTIONCOMBO_H__66952646_5AAD_4182_AC95_845711841B8D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// SelectionCombo.h : header file
//
#include <XTToolkit.h>
/////////////////////////////////////////////////////////////////////////////
// CSelectionCombo window
class CSelectionCombo : public CXTFlatComboBox
{
// Construction
public:
CSelectionCombo();
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSelectionCombo)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSelectionCombo();
// Generated message map functions
protected:
//{{AFX_MSG(CSelectionCombo)
afx_msg UINT OnGetDlgCode();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SELECTIONCOMBO_H__66952646_5AAD_4182_AC95_845711841B8D__INCLUDED_)

View File

@@ -0,0 +1,81 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: splitterwndex.cpp
// Version: v1.00
// Created: 24/4/2002 by Timur.
// Compilers: Visual Studio.NET
// Description: CSplitterWndEx implementation.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SplitterWndEx.h"
// CSplitterWndEx
IMPLEMENT_DYNAMIC(CSplitterWndEx, CSplitterWnd)
CSplitterWndEx::CSplitterWndEx()
{
m_cxSplitter = m_cySplitter = 3 + 1 + 1;
m_cxBorderShare = m_cyBorderShare = 0;
m_cxSplitterGap = m_cySplitterGap = 3 + 1 + 1;
m_cxBorder = m_cyBorder = 1;
}
CSplitterWndEx::~CSplitterWndEx()
{
}
BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
END_MESSAGE_MAP()
// CSplitterWndEx message handlers
void CSplitterWndEx::SetPane( int row,int col,CWnd *pWnd,SIZE sizeInit )
{
assert( pWnd != NULL );
// set the initial size for that pane
m_pColInfo[col].nIdealSize = sizeInit.cx;
m_pRowInfo[row].nIdealSize = sizeInit.cy;
pWnd->ModifyStyle( 0,WS_BORDER,WS_CHILD|WS_VISIBLE );
pWnd->SetParent(this);
CRect rect(CPoint(0,0), sizeInit);
pWnd->MoveWindow( 0,0,sizeInit.cx,sizeInit.cy,FALSE );
pWnd->SetDlgCtrlID( IdFromRowCol(row,col) );
ASSERT((int)::GetDlgCtrlID(pWnd->m_hWnd) == IdFromRowCol(row, col));
}
void CSplitterWndEx::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
{
// Let CSplitterWnd handle everything but the border-drawing
if((nType != splitBorder) || (pDC == NULL))
{
CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg);
return;
}
ASSERT_VALID(pDC);
// Draw border
pDC->Draw3dRect(rectArg, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
}
//////////////////////////////////////////////////////////////////////////
CWnd* CSplitterWndEx::GetActivePane(int* pRow, int* pCol )
{
return GetFocus();
}

View File

@@ -0,0 +1,45 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: splitterwndex.h
// Version: v1.00
// Created: 24/4/2002 by Timur.
// Compilers: Visual Studio.NET
// Description: CSplitterWndEx class.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __splitterwndex_h__
#define __splitterwndex_h__
#if _MSC_VER > 1000
#pragma once
#endif
// CSplitterWndEx
class CSplitterWndEx : public CSplitterWnd
{
public:
DECLARE_DYNAMIC(CSplitterWndEx)
CSplitterWndEx();
~CSplitterWndEx();
virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL);
//! Assign any Window to splitter window pane.
void SetPane( int row,int col,CWnd *pWnd,SIZE sizeInit );
// Ovveride this for flat look.
void OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg);
protected:
DECLARE_MESSAGE_MAP()
};
#endif __splitterwndex_h__

View File

@@ -0,0 +1,571 @@
// SyntaxColorizer.cpp: implementation of the CSyntaxColorizer class.
//
// Version: 1.0.0
// Author: Jeff Schering jeffschering@hotmail.com
// Date: Jan 2001
// Copyright 2001 by Jeff Schering
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SyntaxColorizer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSyntaxColorizer::CSyntaxColorizer()
{
createDefaultCharFormat();
SetCommentColor(CLR_COMMENT);
SetStringColor(CLR_STRING);
createTables();
m_pskKeyword = NULL;
createDefaultKeywordList();
}
CSyntaxColorizer::~CSyntaxColorizer()
{
ClearKeywordList();
deleteTables();
}
//////////////////////////////////////////////////////////////////////
// Member Functions
//////////////////////////////////////////////////////////////////////
void CSyntaxColorizer::createDefaultCharFormat()
{
ZeroStruct( m_cfDefault );
m_cfDefault.dwMask = CFM_CHARSET | CFM_FACE | CFM_SIZE | CFM_OFFSET | CFM_COLOR;
m_cfDefault.dwMask ^= CFM_ITALIC ^ CFM_BOLD ^ CFM_STRIKEOUT ^ CFM_UNDERLINE;
m_cfDefault.dwEffects = 0;
//m_cfDefault.yHeight = 200; //10pts * 20 twips/point = 200 twips
m_cfDefault.yHeight = 180; //10pts * 20 twips/point = 200 twips
m_cfDefault.bCharSet = ANSI_CHARSET;
m_cfDefault.bPitchAndFamily = FIXED_PITCH | FF_MODERN;
m_cfDefault.yOffset = 0;
m_cfDefault.crTextColor = CLR_PLAIN;
strcpy(m_cfDefault.szFaceName,"Courier New");
m_cfDefault.cbSize = sizeof(m_cfDefault);
m_cfComment = m_cfDefault;
m_cfString = m_cfDefault;
}
void CSyntaxColorizer::createDefaultKeywordList()
{
LPTSTR sKeywords = "__asm,else,main,struct,__assume,enum,"
"__multiple_inheritance,switch,auto,__except,__single_inheritance,"
"template,__based,explicit,__virtual_inheritance,this,bool,extern,"
"mutable,thread,break,false,naked,throw,case,__fastcall,namespace,"
"true,catch,__finally,new,try,__cdecl,float,noreturn,__try,char,for,"
"operator,typedef,class,friend,private,typeid,const,goto,protected,"
"typename,const_cast,if,public,union,continue,inline,register,"
"unsigned,__declspec,__inline,reinterpret_cast,using,declaration,"
"directive,default,int,return,uuid,delete,__int8,short,"
"__uuidof,dllexport,__int16,signed,virtual,dllimport,__int32,sizeof,"
"void,do,__int64,static,volatile,double,__leave,static_cast,wmain,"
"dynamic_cast,long,__stdcall,while";
LPTSTR sDirectives = "#define,#elif,#else,#endif,#error,#ifdef,"
"#ifndef,#import,#include,#line,#pragma,#undef";
LPTSTR sPragmas = "alloc_text,comment,init_seg1,optimize,auto_inline,"
"component,inline_depth,pack,bss_seg,data_seg,"
"inline_recursion,pointers_to_members1,check_stack,"
"function,intrinsic,setlocale,code_seg,hdrstop,message,"
"vtordisp1,const_seg,include_alias,once,warning";
AddKeyword(sKeywords,CLR_KEYWORD,GRP_KEYWORD);
AddKeyword(sDirectives,CLR_KEYWORD,GRP_KEYWORD);
AddKeyword(sPragmas,CLR_KEYWORD,GRP_KEYWORD);
}
void CSyntaxColorizer::createTables()
{
m_pTableZero = new unsigned char[256]; m_pTableOne = new unsigned char[256];
m_pTableTwo = new unsigned char[256]; m_pTableThree = new unsigned char[256];
m_pTableFour = new unsigned char[256]; m_pAllowable = new unsigned char[256];
memset(m_pTableZero,SKIP,256); memset(m_pTableOne,SKIP,256);
memset(m_pTableTwo,SKIP,256); memset(m_pTableThree,SKIP,256);
memset(m_pTableFour,SKIP,256); memset(m_pAllowable,false,256);
*(m_pTableZero + '"') = DQSTART; *(m_pTableZero + '\'') = SQSTART;
*(m_pTableZero + '/') = CMSTART; *(m_pTableOne + '"') = DQEND;
*(m_pTableTwo + '\'') = SQEND; *(m_pTableThree + '\n') = SLEND; *(m_pTableThree + '\r') = SLEND;
*(m_pTableFour + '*') = MLEND;
*(m_pAllowable + '\n') = true; *(m_pAllowable + '\r') = true;
*(m_pAllowable + '\t') = true; *(m_pAllowable + '\0') = true;
*(m_pAllowable + ' ') = true; *(m_pAllowable + ';') = true;
*(m_pAllowable + '(') = true; *(m_pAllowable + ')') = true;
*(m_pAllowable + '{') = true; *(m_pAllowable + '}') = true;
*(m_pAllowable + '[') = true; *(m_pAllowable + ']') = true;
*(m_pAllowable + '*') = true;
}
void CSyntaxColorizer::deleteTables()
{
delete m_pTableZero; delete m_pTableOne; delete m_pTableTwo;
delete m_pTableThree; delete m_pTableFour; delete m_pAllowable;
}
void CSyntaxColorizer::AddKeyword(LPCTSTR Keyword, COLORREF cr, int grp)
{
LPTSTR token;
//make a copy of Keyword so that strtok will operate correctly
LPTSTR keyword = new TCHAR[strlen(Keyword) + 1];
strcpy(keyword,Keyword);
CHARFORMAT cf = m_cfDefault;
cf.crTextColor = cr;
token = strtok(keyword,",");
while(token != NULL)
{
if(_stricmp(token,"rem") == 0)
*(m_pTableTwo + '\n') = SLEND; //set single quote as comment start
addKey(token,cf,grp);
token = strtok(NULL,",");
}
delete keyword;
}
void CSyntaxColorizer::AddKeyword(LPCTSTR Keyword, CHARFORMAT cf, int grp)
{
LPTSTR token;
//make a copy of Keyword so that strtok will operate correctly
LPTSTR keyword = new TCHAR[strlen(Keyword) + 1];
strcpy(keyword,Keyword);
token = strtok(keyword,",");
while(token != NULL)
{
if(_stricmp(token,"rem") == 0)
*(m_pTableTwo + '\n') = SLEND; //set single quote as comment start
addKey(token,cf,grp);
token = strtok(NULL,",");
}
delete keyword;
}
void CSyntaxColorizer::addKey(LPCTSTR Keyword, CHARFORMAT cf, int grp) //add in ascending order
{
SKeyword* pskNewKey = new SKeyword;
SKeyword* prev,*curr;
//the string pointed to by Keyword is only temporary, so make a copy
// of it for our list
pskNewKey->keyword = new TCHAR[strlen(Keyword)+1];
strcpy(pskNewKey->keyword,Keyword);
m_keywords[pskNewKey->keyword] = pskNewKey;
pskNewKey->keylen = strlen(Keyword);
pskNewKey->cf = cf;
pskNewKey->group = grp;
pskNewKey->pNext = NULL;
*(m_pTableZero + pskNewKey->keyword[0]) = KEYWORD;
//if list is empty, add first node
if(m_pskKeyword == NULL)
m_pskKeyword = pskNewKey;
else
{
//check to see if new node goes before first node
if(strcmp(Keyword,m_pskKeyword->keyword) < 0)
{
pskNewKey->pNext = m_pskKeyword;
m_pskKeyword = pskNewKey;
}
//check to see if new keyword already exists at the first node
else if(strcmp(Keyword,m_pskKeyword->keyword) == 0)
{
//the keyword exists, so replace the existing with the new
pskNewKey->pNext = m_pskKeyword->pNext;
delete []m_pskKeyword->keyword; delete m_pskKeyword;
m_pskKeyword = pskNewKey;
}
else
{
prev = m_pskKeyword;
curr = m_pskKeyword->pNext;
while(curr != NULL && strcmp(curr->keyword,Keyword) < 0)
{
prev = curr;
curr = curr->pNext;
}
if(curr != NULL && strcmp(curr->keyword,Keyword) == 0)
{
//the keyword exists, so replace the existing with the new
prev->pNext = pskNewKey;
pskNewKey->pNext = curr->pNext;
delete []curr->keyword; delete curr;
}
else
{
pskNewKey->pNext = curr;
prev->pNext = pskNewKey;
}
}
}
}
void CSyntaxColorizer::ClearKeywordList()
{
SKeyword* pTemp = m_pskKeyword;
m_keywords.clear();
while(m_pskKeyword != NULL)
{
*(m_pTableZero + m_pskKeyword->keyword[0]) = SKIP;
if(_stricmp(m_pskKeyword->keyword,"rem") == 0)
*(m_pTableTwo + '\n') = SKIP;
pTemp = m_pskKeyword->pNext;
delete []m_pskKeyword->keyword;
delete m_pskKeyword;
m_pskKeyword = pTemp;
}
}
CString CSyntaxColorizer::GetKeywordList()
{
CString sList;
SKeyword* pTemp = m_pskKeyword;
while(pTemp != NULL)
{
sList += pTemp->keyword;
sList += ",";
pTemp = pTemp->pNext;
}
sList.TrimRight(',');
return sList;
}
CString CSyntaxColorizer::GetKeywordList(int grp)
{
CString sList;
SKeyword* pTemp = m_pskKeyword;
while(pTemp != NULL)
{
if(pTemp->group == grp)
{
sList += pTemp->keyword;
sList += ",";
}
pTemp = pTemp->pNext;
}
sList.TrimRight(',');
return sList;
}
void CSyntaxColorizer::SetCommentColor(COLORREF cr)
{
CHARFORMAT cf = m_cfComment;
cf.dwMask = CFM_COLOR;
cf.crTextColor = cr;
SetCommentStyle(cf);
}
void CSyntaxColorizer::SetStringColor(COLORREF cr)
{
CHARFORMAT cf = m_cfString;
cf.dwMask = CFM_COLOR;
cf.crTextColor = cr;
SetStringStyle(cf);
}
void CSyntaxColorizer::SetGroupStyle(int grp, CHARFORMAT cf)
{
SKeyword* pTemp = m_pskKeyword;
while(pTemp != NULL)
{
if(pTemp->group == grp)
{
pTemp->cf = cf;
}
pTemp = pTemp->pNext;
}
}
void CSyntaxColorizer::GetGroupStyle(int grp, CHARFORMAT &cf)
{
SKeyword* pTemp = m_pskKeyword;
while(pTemp != NULL)
{
if(pTemp->group == grp)
{
cf = pTemp->cf;
pTemp = NULL;
}
else
{
pTemp = pTemp->pNext;
//if grp is not found, return default style
if(pTemp == NULL) cf = m_cfDefault;
}
}
}
void CSyntaxColorizer::SetGroupColor(int grp, COLORREF cr)
{
CHARFORMAT cf;
GetGroupStyle(grp,cf);
cf.dwMask = CFM_COLOR;
cf.crTextColor = cr;
SetGroupStyle(grp,cf);
}
void CSyntaxColorizer::Colorize(CHARRANGE cr, CRichEditCtrl *pCtrl)
{
pCtrl->LockWindowUpdate();
long nTextLength = 0;
if(cr.cpMin == 0 && cr.cpMax == -1) //send entire text of rich edit box
{
//set up the buffer to hold the text from the rich edit box
nTextLength = pCtrl->GetTextLength();
//if there is alot of text in the Rich Edit (>64K) then GetWindowText doesn't
//work. We have to select all of the text, and then use GetSelText
pCtrl->SetSel(0,-1);
}
else
{
//set up the buffer to hold the text
nTextLength = cr.cpMax - cr.cpMin + 1;//add 1 because zero-based array
//get the text
pCtrl->SetSel(cr.cpMin,cr.cpMax);
}
LPTSTR lpszBuf = new TCHAR[nTextLength+1];
pCtrl->GetSelText(lpszBuf);
pCtrl->SetSelectionCharFormat(m_cfDefault);
colorize(lpszBuf,pCtrl,cr.cpMin);
delete lpszBuf;
pCtrl->UnlockWindowUpdate();
}
void CSyntaxColorizer::Colorize(long nStartChar, long nEndChar, CRichEditCtrl *pCtrl)
{
long nTextLength = 0;
if(nStartChar == 0 && nEndChar == -1) //send entire text of rich edit box
{
nTextLength = pCtrl->GetTextLength();
//if there is alot of text in the Rich Edit (>64K) then GetWindowText doesn't
//work. We have to select all of the text, and then use GetSelText
pCtrl->SetSel(0,-1);
}
else
{
//set up the text buffer; add 1 because zero-based array
nTextLength = nEndChar - nStartChar + 1;
pCtrl->SetSel(nStartChar,nEndChar);
}
LPTSTR lpszBuf = new TCHAR[nTextLength+1];
pCtrl->GetSelText(lpszBuf);
pCtrl->SetSelectionCharFormat(m_cfDefault);
colorize(lpszBuf,pCtrl,nStartChar);
delete lpszBuf;
}
void CSyntaxColorizer::colorize(LPTSTR lpszBuf, CRichEditCtrl *pCtrl, long iOffset /*=0*/)
{
//setup some vars
char sWord[4096];
CHARFORMAT cf;
LPTSTR lpszTemp;
long iStart;
long x = 0;
SKeyword* pskTemp = m_pskKeyword;
unsigned char* pTable = m_pTableZero;
//do the work
while(lpszBuf[x])
{
switch(pTable[lpszBuf[x]])
{
case DQSTART:
pTable = m_pTableOne;
iStart = iOffset + x;
break;
case SQSTART:
pTable = m_pTableTwo;
iStart = iOffset + x;
break;
case CMSTART:
if(lpszBuf[x+1] == '/')
{
pTable = m_pTableThree;
iStart = iOffset + x;
x++;
}
else if(lpszBuf[x+1] == '*')
{
pTable = m_pTableFour;
iStart = iOffset + x;
x++;
}
else if(lpszBuf[x] == '\'')
{
pTable = m_pTableThree;
iStart = iOffset + x;
x++;
}
break;
case MLEND:
if(lpszBuf[x+1] == '/')
{
x++;
pTable = m_pTableZero;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(m_cfComment);
}
break;
case SLEND:
if(lpszBuf[x-2] != '\\') // line continuation character
{
pTable = m_pTableZero;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(m_cfComment);
}
break;
case DQEND:
pTable = m_pTableZero;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(m_cfString);
break;
case SQEND:
if(lpszBuf[x-1] == '\\' && lpszBuf[x+1] == '\'')
break;
pTable = m_pTableZero;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(m_cfString);
break;
case KEYWORD:
// Extract whole word.
lpszTemp = lpszBuf+x;
{
if (x > 0 && !m_pAllowable[lpszBuf[x-1]])
break;
int i = 0;
while (!m_pAllowable[lpszTemp[i]])
{
sWord[i] = lpszTemp[i];
i++;
}
if (i > 0)
{
sWord[i] = 0;
// Word extracted.
// Find keyword.
Keywords::iterator it = m_keywords.find( sWord );
if (it != m_keywords.end())
{
int iStart = iOffset + x;
pskTemp = it->second;
x += pskTemp->keylen;
pCtrl->SetSel(iStart,iOffset + x);
pCtrl->SetSelectionCharFormat(pskTemp->cf);
}
}
}
/*
lpszTemp = lpszBuf+x;
while(pskTemp != NULL)
{
if(pskTemp->keyword[0] == lpszTemp[0])
{
int x1=0,y1=0;iStart = iOffset + x;
while(pskTemp->keyword[x1])
{
y1 += lpszTemp[x1] ^ pskTemp->keyword[x1];
x1++;
}
if(y1 == 0 && (*(m_pAllowable + (lpszBuf[x-1])) &&
*(m_pAllowable + (lpszBuf[x+pskTemp->keylen]))))
{
if(_stricmp(pskTemp->keyword,"rem") == 0)
{
pTable = m_pTableThree;
}
else
{
x += pskTemp->keylen;
pCtrl->SetSel(iStart,iOffset + x);
pCtrl->SetSelectionCharFormat(pskTemp->cf);
}
}
}
pskTemp = pskTemp->pNext;
}
*/
pskTemp = m_pskKeyword;
break;
case SKIP:;
}
x++;
}
//sometimes we get to the end of the file before the end of the string
//or comment, so we deal with that situation here
if(pTable == m_pTableOne)
{
cf = m_cfString;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(cf);
}
else if(pTable == m_pTableTwo)
{
cf = m_cfString;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(cf);
}
else if(pTable == m_pTableThree)
{
cf = m_cfComment;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(cf);
}
else if(pTable == m_pTableFour)
{
cf = m_cfComment;
pCtrl->SetSel(iStart,iOffset + x+1);
pCtrl->SetSelectionCharFormat(cf);
}
}

View File

@@ -0,0 +1,113 @@
// SyntaxColorizer.h: interface for the CSyntaxColorizer class.
//
// Version: 1.0.0
// Author: Jeff Schering jeffschering@hotmail.com
// Date: Jan 2001
// Copyright 2001 by Jeff Schering
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SYNTAXCOLORIZER_H__5C50E421_E4AC_11D4_A61E_60A459C10100__INCLUDED_)
#define AFX_SYNTAXCOLORIZER_H__5C50E421_E4AC_11D4_A61E_60A459C10100__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define CLR_STRING RGB(55,0,200)
#define CLR_PLAIN RGB(0,0,0)
#define CLR_COMMENT RGB(0,170,0)
#define CLR_KEYWORD RGB(0,0,255)
#define GRP_KEYWORD 0
#ifdef WIN64
#define hash_map map
#else
#if defined(LINUX)
#include <ext/hash_map>
#else
#include <hash_map>
#endif
#endif
class CSyntaxColorizer
{
public:
CSyntaxColorizer();
virtual ~CSyntaxColorizer();
//protected vars
protected:
unsigned char *m_pTableZero, *m_pTableOne;
unsigned char *m_pTableTwo, *m_pTableThree;
unsigned char *m_pTableFour, *m_pAllowable;
enum Types
{
SKIP,
DQSTART, //Double Quotes start
DQEND, //Double Quotes end
SQSTART, //Single Quotes start
SQEND, //Single Quotes end
CMSTART, //Comment start (both single and multi line)
SLEND, //Single line comment end
MLEND, //Multi line comment end
KEYWORD //Keyword start
} m_type;
struct SKeyword
{
char* keyword;
int keylen;
CHARFORMAT cf;
int group;
SKeyword* pNext;
SKeyword() { pNext = NULL; }
};
SKeyword* m_pskKeyword;
CHARFORMAT m_cfComment;
CHARFORMAT m_cfString;
CHARFORMAT m_cfDefault;
//typedef std::map<LPCSTR,SKeyword*,> Keywords;
//typedef std::hash_map<const char*,SKeyword*,stl::hash_strcmp<const char*> > Keywords;
typedef std::hash_map<const char*,SKeyword*,stl::hash_strcmp<const char*> > Keywords;
Keywords m_keywords;
//protected member functions
protected:
void addKey(LPCTSTR Keyword, CHARFORMAT cf, int grp);
void createTables();
void deleteTables();
void createDefaultKeywordList();
void createDefaultCharFormat();
void colorize(LPTSTR lpszBuf, CRichEditCtrl *pCtrl, long iOffset = 0);
//public member functions
public:
void Colorize(long StartChar, long nEndChar, CRichEditCtrl *pCtrl);
void Colorize(CHARRANGE cr, CRichEditCtrl *pCtrl);
void GetCommentStyle(CHARFORMAT &cf) { cf = m_cfComment; };
void GetStringStyle(CHARFORMAT &cf) { cf = m_cfString; };
void GetGroupStyle(int grp, CHARFORMAT &cf);
void GetDefaultStyle(CHARFORMAT &cf) { cf = m_cfDefault; };
void SetCommentStyle(CHARFORMAT cf) { m_cfComment = cf; };
void SetCommentColor(COLORREF cr);
void SetStringStyle(CHARFORMAT cf) { m_cfString = cf; };
void SetStringColor(COLORREF cr);
void SetGroupStyle(int grp, CHARFORMAT cf);
void SetGroupColor(int grp, COLORREF cr);
void SetDefaultStyle(CHARFORMAT cf) { m_cfDefault = cf; };
void AddKeyword(LPCTSTR Keyword, CHARFORMAT cf, int grp = 0);
void AddKeyword(LPCTSTR Keyword, COLORREF cr, int grp = 0);
void ClearKeywordList();
CString GetKeywordList();
CString GetKeywordList(int grp);
};
#endif // !defined(AFX_SYNTAXCOLORIZER_H__5C50E421_E4AC_11D4_A61E_60A459C10100__INCLUDED_)

105
Editor/Controls/TemplDef.h Normal file
View File

@@ -0,0 +1,105 @@
#if !defined(AFX_TEMPLDEF_H__742F3281_055B_11D4_B261_00104BB13A66__INCLUDED_)
#define AFX_TEMPLDEF_H__742F3281_055B_11D4_B261_00104BB13A66__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
///////////////////////////////////////////////////////////////////////////////
// TemplDef.h: helper macroses for using templates with MFC
//
// Author: Yury Goltsman
// email: ygprg@go.to
// page: http://go.to/ygprg
// Copyright <20> 2000, Yury Goltsman
//
// This code provided "AS IS," without any kind of warranty.
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// version : 1.0
//
///////////////////////////////////////////////////////////////////////////////
// common definitions for any map:
// use it to specify list of arguments for class and as theTemplArgs
// e.g. BEGIN_TEMPLATE_MESSAGE_MAP(ARGS2(class base_class, int max),
// CMyTClass<ARGS2(base_class, max)>,
// base_class)
#define ARGS2(arg1, arg2) arg1, arg2
#define ARGS3(arg1, arg2, arg3) arg1, arg2, arg3
#define ARGS4(arg1, arg2, arg3, arg4) arg1, arg2, arg3, arg4
#define ARGS5(arg1, arg2, arg3, arg4, arg5) arg1, arg2, arg3, arg4, arg5
///////////////////////////////////////////////////////////////////////////////
// definition for MESSAGE_MAP:
#define DECLARE_TEMPLATE_MESSAGE_MAP() DECLARE_MESSAGE_MAP()
#if defined(WIN64) && _MFC_VER < 0x700
#ifdef _AFXDLL
#define BEGIN_TEMPLATE_MESSAGE_MAP(theTemplArgs, theClass, baseClass) \
template <theTemplArgs> \
const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() \
{ return &baseClass::messageMap; } \
template <theTemplArgs> \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
template <theTemplArgs> \
/*AFX_COMDAT AFX_DATADEF*/ const AFX_MSGMAP theClass::messageMap = \
{ &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; \
template <theTemplArgs> \
/*AFX_COMDAT */const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{
#else
#define BEGIN_TEMPLATE_MESSAGE_MAP(theTemplArgs, theClass, baseClass) \
template <theTemplArgs> \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
template <theTemplArgs> \
/*AFX_COMDAT */AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \
template <theTemplArgs> \
/*AFX_COMDAT */const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{
#endif // _AFXDLL
#else
#ifdef _AFXDLL
#define BEGIN_TEMPLATE_MESSAGE_MAP(theTemplArgs, theClass, baseClass) \
template <theTemplArgs> \
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ return &theClass::messageMap; } \
template <theTemplArgs> \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
template <theTemplArgs> \
/*AFX_COMDAT AFX_DATADEF*/ const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::GetThisMessageMap, &theClass::_messageEntries[0] }; \
template <theTemplArgs> \
/*AFX_COMDAT */const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \
#else
#define BEGIN_TEMPLATE_MESSAGE_MAP(theTemplArgs, theClass, baseClass) \
template <theTemplArgs> \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
template <theTemplArgs> \
/*AFX_COMDAT */AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \
template <theTemplArgs> \
/*AFX_COMDAT */const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \
#endif // _AFXDLL
#endif //WIN64
#define END_TEMPLATE_MESSAGE_MAP() END_MESSAGE_MAP()
#endif // !defined(AFX_TEMPLDEF_H__742F3281_055B_11D4_B261_00104BB13A66__INCLUDED_)

View File

@@ -0,0 +1,222 @@
// C:\Dev\Crytek\Editor\Controls\RichEditCtrlEx.cpp : implementation file
//
#include "stdafx.h"
#include "TextEditorCtrl.h"
#define GRP_KEYWORD 0
#define GRP_CONSTANTS 1
#define GRP_DIRECTIVE 2
#define GRP_PRAGMA 3
// CTextEditorCtrl
IMPLEMENT_DYNAMIC(CTextEditorCtrl, CRichEditCtrl)
CTextEditorCtrl::CTextEditorCtrl()
{
/*
//reconfigure CSyntaxColorizer's default keyword groupings
LPTSTR sKeywords = "for,for,else,main,struct,enum,switch,auto,"
"template,explicit,this,bool,extern,thread,break,false,"
"throw,case,namespace,true,catch,new,try,float,noreturn,"
"char,operator,typedef,class,friend,private,const,goto,"
"protected,typename,if,public,union,continue,inline,"
"unsigned,using,directive,default,int,return,delete,short,"
"signed,virtual,sizeof,void,do,static,double,long,while";
LPTSTR sDirectives = "#define,#elif,#else,#endif,#error,#ifdef,"
"#ifndef,#import,#include,#line,#pragma,#undef";
LPTSTR sPragmas = "comment,optimize,auto_inline,once,warning,"
"component,pack,function,intrinsic,setlocale,hdrstop,message";
m_sc.ClearKeywordList();
m_sc.AddKeyword(sKeywords,RGB(0,0,255),GRP_KEYWORD);
m_sc.AddKeyword(sDirectives,RGB(0,0,255),GRP_DIRECTIVE);
m_sc.AddKeyword(sPragmas,RGB(0,0,255),GRP_PRAGMA);
m_sc.AddKeyword("REM,Rem,rem",RGB(255,0,255),4);
*/
LPTSTR sKeywords = "Shader,ShadeLayer,HW,LightStyle,ValueString,Orient,Origin,Params,Array,Template,Templates,"
"Version,CGVProgram,CGVPParam,Name,"
"DeclareLightMaterial,Side,Ambient,Diffuse,Specular,Emission,Shininess,"
"Layer,Map,RGBGen,RgbGen,AlphaGen,NoDepthTest,Blend,TexCoordMod,Scale,UScale,VScale,ShiftNoise,Noise,SRange,TRange,"
"Cull,Sort,State,NoCull,ShadowMapGen,Conditions,Vars,DepthWrite,NoColorMask,Portal,LMNoAlpha,"
"TexColorOp,TexStage,TexType,TexFilter,TexGen,UpdateStyle,EvalLight,Style,TexDecal,Tex1Decal,TexBump,"
"RCParam,RCombiner,RShader,TSParam,Reg,Comp,DepthMask,AlphaFunc,Light,LightType,ClipPlane,PlaneS,PlaneT,"
"PolygonOffset,NoLightmap,ShineMap,Turbulence,tcMod,Procedure,TessSize,Spark,Sequence,Maps,Time,Loop,"
"Mask,Public,float,RenderParams,User,"
"rgbGen,blend,map,"
"Translate,Identity,Rotate,RotateX,RotateY,RotateZ,Div,DeformGen,Scroll,UScroll,VScroll,Angle"
"Type,Level,Amp,Phase,Freq,DeformVertexes,FlareSize,NoLight,Const,Start,"
"Matrix,FLOAT,BYTE,Verts,Vertex,Normal,Normals,Color,Texture0,Texture1,Texture2,Texture3,Texture4,TNormals";
LPTSTR sConstants = "Decal,None,Nearest,TwoSided,RCRGBToAlpha,OcclusionTest,NoSet,Replace,FromClient,"
"Opaque,MonitorNoise,Point,Front,Back,Water,TriLinear,"
"MuzzleFlash,FromObj,Modulate,Base,SphereMap,Add,Glare,Additive,Intensity,White,Sin,Cos,Tan,"
"$Diffuse,$None,$Specular,$Whiteimage,$Environment,$Glare,$Opacity,$Flare";
LPTSTR sDirectives = "#define,#elif,#else,#endif,#error,#ifdef,"
"#ifndef,#import,#include,#line,#pragma,#undef";
m_sc.ClearKeywordList();
m_sc.AddKeyword(sKeywords,RGB(0,0,255),GRP_KEYWORD);
m_sc.AddKeyword(sConstants,RGB(180,0,110),GRP_CONSTANTS);
m_sc.AddKeyword(sDirectives,RGB(160,0,160),GRP_DIRECTIVE);
m_sc.SetCommentColor( RGB(0,128,128) );
m_sc.SetStringColor( RGB(0,128,0) );
m_bModified = true;
}
CTextEditorCtrl::~CTextEditorCtrl()
{
}
BEGIN_MESSAGE_MAP(CTextEditorCtrl, CRichEditCtrl)
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
static DWORD CALLBACK StreamReadFunction(DWORD_PTR dwCookie,
LPBYTE lpBuf, //the buffer to fill
LONG nCount, //the no. of bytes to read
LONG* nRead) // no. of bytes read
{
CCryFile* fp = (CCryFile*)dwCookie;
*nRead = fp->Read(lpBuf,nCount);
return 0;
}
static DWORD CALLBACK StreamWriteFunction(DWORD_PTR dwCookie,
LPBYTE lpBuf, //the buffer to fill
LONG nCount, //the no. of bytes to write
LONG* nWrite) // no. of bytes writed
{
CFile* pFile = (CFile*) dwCookie;
pFile->Write(lpBuf,nCount);
*nWrite = nCount;
return 0;
}
// CTextEditorCtrl message handlers
void CTextEditorCtrl::LoadFile( const CString &sFileName )
{
if (stricmp(m_filename,sFileName) == 0)
return;
m_filename = sFileName;
SetRedraw(FALSE);
CCryFile file(sFileName,"rb");
if (file.Open(sFileName,"rb"))
{
m_es.dwCookie = (DWORD_PTR)&file;
m_es.pfnCallback = StreamReadFunction;
StreamIn(SF_TEXT,m_es);
}
Parse();
m_bModified = false;
}
//////////////////////////////////////////////////////////////////////////
void CTextEditorCtrl::SaveFile( const CString &sFileName )
{
if (sFileName.IsEmpty())
return;
if (!CFileUtil::OverwriteFile( sFileName ))
return;
CFile file(sFileName,CFile::modeCreate|CFile::modeWrite);
m_es.dwCookie = (DWORD_PTR)&file;
m_es.pfnCallback = StreamWriteFunction;
StreamOut(SF_TEXT,m_es);
file.Close();
m_bModified = false;
}
//////////////////////////////////////////////////////////////////////////
void CTextEditorCtrl::Parse()
{
//turn off response to onchange events
long mask = GetEventMask();
SetEventMask( mask & (~ENM_CHANGE) );
//set redraw to false to reduce flicker, and to speed things up
SetRedraw(FALSE);
//call the colorizer
m_sc.Colorize(0,-1,this);
//do some cleanup
SetSel(0,0);
SetRedraw(TRUE);
RedrawWindow();
SetEventMask( mask | ENM_CHANGE );
}
//////////////////////////////////////////////////////////////////////////
void CTextEditorCtrl::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
CRichEditCtrl::PreSubclassWindow();
//set the event mask to accept ENM_CHANGE messages
SetEventMask( GetEventMask()|ENM_CHANGE );
}
//////////////////////////////////////////////////////////////////////////
void CTextEditorCtrl::OnChange()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CRichEditCtrl::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
CHARRANGE cr;
GetSel(cr);
//get the current line of text from the control
int len = LineLength();
int start = LineIndex();
//call the colorizer
m_sc.Colorize(start,start + len,this);
SetSel(cr);
m_bModified = true;
}
//////////////////////////////////////////////////////////////////////////
UINT CTextEditorCtrl::OnGetDlgCode()
{
// TODO: Add your message handler code here and/or call default
return CRichEditCtrl::OnGetDlgCode() | DLGC_WANTTAB;
}
//////////////////////////////////////////////////////////////////////////
void CTextEditorCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == 'S' || nChar == 's')
{
// Check if control is also pressed.
GetAsyncKeyState(VK_CONTROL);
if (GetAsyncKeyState(VK_CONTROL))
{
// Save file.
if (IsModified())
{
SaveFile( GetFilename() );
}
}
};
CRichEditCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}

View File

@@ -0,0 +1,53 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: texteditorctrl.h
// Version: v1.00
// Created: 12/2/2003 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __texteditorctrl_h__
#define __texteditorctrl_h__
#pragma once
// CTextEditorCtrl
#include "SyntaxColorizer.h"
class CTextEditorCtrl : public CRichEditCtrl
{
DECLARE_DYNAMIC(CTextEditorCtrl)
public:
CTextEditorCtrl();
virtual ~CTextEditorCtrl();
void LoadFile( const CString &sFileName );
void SaveFile( const CString &sFileName );
CString GetFilename() const { return m_filename; }
void Parse();
bool IsModified() const { return m_bModified; }
//! Must be called after OnChange message.
void OnChange();
protected:
DECLARE_MESSAGE_MAP()
virtual void PreSubclassWindow();
CString m_filename;
CSyntaxColorizer m_sc;
EDITSTREAM m_es;
bool m_bModified;
public:
afx_msg UINT OnGetDlgCode();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
};
#endif // __texteditorctrl_h__

View File

@@ -0,0 +1,53 @@
// ToolBarContainer.cpp : implementation file
//
#include "stdafx.h"
#include "ToolBarContainer.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CToolBarContainer
CToolBarContainer::CToolBarContainer()
{
}
CToolBarContainer::~CToolBarContainer()
{
}
BEGIN_MESSAGE_MAP(CToolBarContainer, CWnd)
//{{AFX_MSG_MAP(CToolBarContainer)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CToolBarContainer message handlers
void CToolBarContainer::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rect;
CBrush cFillBrush;
// Paint the window with a dark gray bursh
// Get the rect of the client window
GetClientRect(&rect);
// Create the brush
cFillBrush.CreateStockObject(BLACK_BRUSH);
// Fill the entire client area
dc.FillRect(&rect, &cFillBrush);
// Do not call CView::OnPaint() for painting messages
}

View File

@@ -0,0 +1,47 @@
#if !defined(AFX_TOOLBARCONTAINER_H__1EE442FA_871E_4FE8_BCCA_F2E53919548C__INCLUDED_)
#define AFX_TOOLBARCONTAINER_H__1EE442FA_871E_4FE8_BCCA_F2E53919548C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ToolBarContainer.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CToolBarContainer window
class CToolBarContainer : public CWnd
{
// Construction
public:
CToolBarContainer();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CToolBarContainer)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CToolBarContainer();
// Generated message map functions
protected:
//{{AFX_MSG(CToolBarContainer)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_TOOLBARCONTAINER_H__1EE442FA_871E_4FE8_BCCA_F2E53919548C__INCLUDED_)

View File

@@ -0,0 +1,206 @@
// ToolBarTab.cpp : implementation file
//
#include "stdafx.h"
#include "ToolBarTab.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CToolBarTab
CToolBarTab::CToolBarTab()
{
}
CToolBarTab::~CToolBarTab()
{
}
BEGIN_MESSAGE_MAP(CToolBarTab, CTabCtrl)
//{{AFX_MSG_MAP(CToolBarTab)
ON_WM_CREATE()
ON_WM_SIZE()
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange)
ON_NOTIFY_REFLECT(TCN_SELCHANGING, OnSelchanging)
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CToolBarTab message handlers
int CToolBarTab::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
// Set another font for the tab control
SendMessage(WM_SETFONT, (WPARAM)
GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(FALSE, 0));
// Create the scrolling controls
m_cScrollBar.Create(WS_CHILD | WS_VISIBLE | SBS_VERT,
CRect(90, 20, 110, 400), this, NULL);
m_cScrollBar.EnableScrollBar();
m_cScrollBar.ShowScrollBar();
return 0;
}
void CToolBarTab::OnSize(UINT nType, int cx, int cy)
{
////////////////////////////////////////////////////////////////////////
// Resize all toolbars that are linked with tabs
////////////////////////////////////////////////////////////////////////
CTabCtrl::OnSize(nType, cx, cy);
// Resize the plugin windows in the tab control
ResizeAllContainers();
// Resize the scrollbar
m_cScrollBar.SetWindowPos(NULL, 159, 28, 16, cy - 30, SWP_NOZORDER);
}
void CToolBarTab::ResizeAllContainers()
{
////////////////////////////////////////////////////////////////////////
// Center all containers in the tab control
////////////////////////////////////////////////////////////////////////
unsigned int i;
TCITEM tci;
RECT rcClient;
RECT rcWndOldClient;
GetClientRect(&rcClient);
for (i=0; i<GetItemCount(); i++)
{
// Get the item, retrieve the application specific parameter
tci.mask = TCIF_PARAM;
GetItem(i, &tci);
ASSERT(::IsWindow((HWND) tci.lParam));
// Save the window dimensions so we can restore the height later
::GetClientRect((HWND) tci.lParam, &rcWndOldClient);
// Resize it
::SetWindowPos((HWND) tci.lParam, NULL, 0, 25, rcClient.right - 2,
rcWndOldClient.bottom, SWP_NOZORDER);
}
RECT rcClientContainer, rcClientUIElements;
GetClientRect(&rcClientContainer);
::GetClientRect((HWND) tci.lParam, &rcClientUIElements);
if ((rcClientUIElements.bottom - rcClientUIElements.top) + 175 > rcClientContainer.bottom - rcClientContainer.top)
m_cScrollBar.ShowWindow(SW_SHOW);
else
m_cScrollBar.ShowWindow(SW_HIDE);
/*
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL;
info.nMin = 0;
info.nMax = 100;
info.nPage = 2;
info.nPos = 5;
info.nTrackPos = 0;
m_cScrollBar.SetScrollInfo(&info);
*/
m_cScrollBar.SetScrollRange(0, 100);
//m_cScrollBar.SetScrollRange(25, 25 + (rcClientUIElements.bottom - rcClientUIElements.top) + 175);
}
void CToolBarTab::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult)
{
////////////////////////////////////////////////////////////////////////
// Show the toolbar associated with the current tab
////////////////////////////////////////////////////////////////////////
// TODO: Add your control notification handler code here
TCITEM tci;
tci.mask = TCIF_PARAM;
GetItem(GetCurSel(), &tci);
ASSERT(::IsWindow((HWND) tci.lParam));
// Show the current toolbar window
::ShowWindow((HWND) tci.lParam, SW_NORMAL);
// Make sure the window is placed correctly
ResizeAllContainers();
*pResult = 0;
}
void CToolBarTab::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult)
{
////////////////////////////////////////////////////////////////////////
// Current tab is about to change, hide the toolbar associated with the
// current tab
////////////////////////////////////////////////////////////////////////
// TODO: Add your control notification handler code here
TCITEM tci;
// Hide the current toolbar
tci.mask = TCIF_PARAM;
GetItem(GetCurSel(), &tci);
ASSERT(::IsWindow((HWND) tci.lParam));
::ShowWindow((HWND) tci.lParam, SW_HIDE);
*pResult = 0;
}
BOOL CToolBarTab::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
////////////////////////////////////////////////////////////////////////
// Route the toolbars events to the main window
////////////////////////////////////////////////////////////////////////
// TODO: Add your specialized code here and/or call the base class
if (AfxGetMainWnd())
AfxGetMainWnd()->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
return CTabCtrl::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
void CToolBarTab::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// Change the position of the UI elements to reflect the new scrollbar position
//ResizeAllContainers();
switch (nSBCode)
{
case SB_LINEDOWN:
pScrollBar->SetScrollPos(nPos + 1);
break;
}
CTabCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}

View File

@@ -0,0 +1,61 @@
#if !defined(AFX_TOOLBARTAB_H__691888C3_A10C_4EB0_94B8_C1E68110106E__INCLUDED_)
#define AFX_TOOLBARTAB_H__691888C3_A10C_4EB0_94B8_C1E68110106E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ToolBarTab.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CToolBarTab window
#include "HiColorToolBar.h"
class CToolBarTab : public CTabCtrl
{
// Construction
public:
CToolBarTab();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CToolBarTab)
public:
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CToolBarTab();
void ResizeAllContainers();
// Generated message map functions
protected:
CScrollBar m_cScrollBar;
//{{AFX_MSG(CToolBarTab)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnSelchange(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_TOOLBARTAB_H__691888C3_A10C_4EB0_94B8_C1E68110106E__INCLUDED_)

View File

@@ -0,0 +1,143 @@
// ToolButton.cpp : implementation file
//
#include "stdafx.h"
#include "ToolButton.h"
#include "EditTool.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TOOLBUTTON_TIMERID 1001
/////////////////////////////////////////////////////////////////////////////
// CToolButton
IMPLEMENT_DYNAMIC(CToolButton,CColorCheckBox)
//////////////////////////////////////////////////////////////////////////
CToolButton::CToolButton()
{
m_toolClass = 0;
m_userData = 0;
m_nTimer = 0;
}
CToolButton::~CToolButton()
{
StopTimer();
}
void CToolButton::SetToolClass( CRuntimeClass *toolClass,void *userData )
{
m_toolClass = toolClass;
m_userData = userData;
}
BEGIN_MESSAGE_MAP(CToolButton, CButton)
//{{AFX_MSG_MAP(CToolButton)
ON_WM_TIMER()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CToolButton message handlers
void CToolButton::OnTimer(UINT_PTR nIDEvent)
{
// Check tool state.
CEditTool *tool = GetIEditor()->GetEditTool();
CRuntimeClass *toolClass = 0;
if (tool)
toolClass = tool->GetRuntimeClass();
int c = GetCheck();
if (toolClass != m_toolClass)
{
if (GetCheck() == 1)
SetCheck(0);
StopTimer();
}
CButton::OnTimer(nIDEvent);
}
void CToolButton::OnDestroy()
{
StopTimer();
CButton::OnDestroy();
}
//////////////////////////////////////////////////////////////////////////
void CToolButton::OnPaint()
{
CColorCheckBox::OnPaint();
// Check if tool is current tool.
CEditTool *tool = GetIEditor()->GetEditTool();
if (tool && tool->GetRuntimeClass() == m_toolClass)
{
if (GetCheck() == 0)
{
SetCheck(1);
StartTimer();
}
}
else
{
if (GetCheck() == 1)
{
SetCheck(0);
StopTimer();
}
}
}
//////////////////////////////////////////////////////////////////////////
void CToolButton::OnClicked()
{
if (!m_toolClass)
return;
CEditTool *tool = GetIEditor()->GetEditTool();
if (tool && tool->GetRuntimeClass() == m_toolClass)
{
GetIEditor()->SetEditTool(0);
SetCheck(0);
StopTimer();
}
else
{
CEditTool *tool = (CEditTool*)m_toolClass->CreateObject();
if (!tool)
return;
SetCheck(1);
StartTimer();
if (m_userData)
tool->SetUserData( m_userData );
// Must be last function, can delete this.
GetIEditor()->SetEditTool( tool );
}
}
void CToolButton::StartTimer()
{
StopTimer();
m_nTimer = SetTimer(TOOLBUTTON_TIMERID,200,NULL);
}
void CToolButton::StopTimer()
{
if (m_nTimer != 0)
KillTimer(m_nTimer);
m_nTimer = 0;
}

View File

@@ -0,0 +1,64 @@
#if !defined(AFX_TOOLBUTTON_H__5CB83738_43F3_48F5_A1DD_940B3BF330CA__INCLUDED_)
#define AFX_TOOLBUTTON_H__5CB83738_43F3_48F5_A1DD_940B3BF330CA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ToolButton.h : header file
//
#include "ColorCheckBox.h"
/////////////////////////////////////////////////////////////////////////////
// CToolButton window
class CToolButton : public CColorCheckBox
{
DECLARE_DYNAMIC(CToolButton)
// Construction
public:
CToolButton();
void SetToolClass( CRuntimeClass *toolClass,void *userData=0 );
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CToolButton)
protected:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CToolButton();
// Generated message map functions
protected:
//{{AFX_MSG(CToolButton)
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnDestroy();
afx_msg void OnClicked();
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
void StartTimer();
void StopTimer();
//! Tool associated with this button.
CRuntimeClass *m_toolClass;
void *m_userData;
int m_nTimer;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_TOOLBUTTON_H__5CB83738_43F3_48F5_A1DD_940B3BF330CA__INCLUDED_)

View File

@@ -0,0 +1,498 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: treectrlex.cpp
// Version: v1.00
// Created: 1/8/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TreeCtrlEx.h"
// CTreeCtrlEx
IMPLEMENT_DYNAMIC(CTreeCtrlEx, CTreeCtrl)
CTreeCtrlEx::CTreeCtrlEx()
{
// When this tree is initialized, no dragging of course
m_bLDragging = false;
m_pDragImage = NULL;
m_hitemDrag = NULL;
m_hitemDrop = NULL;
m_dropCursor = LoadCursor(NULL,IDC_ARROW);
m_noDropCursor = LoadCursor(NULL,IDC_NO);
}
CTreeCtrlEx::~CTreeCtrlEx()
{
}
BEGIN_MESSAGE_MAP(CTreeCtrlEx, CTreeCtrl)
ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBeginDrag)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
// CTreeCtrlEx message handlers
//////////////////////////////////////////////////////////////////////////
// CopyItem - Copies an item to a new location
// Returns - Handle of the new item
// hItem - Item to be copied
// htiNewParent - Handle of the parent for new item
// htiAfter - Item after which the new item should be created
HTREEITEM CTreeCtrlEx::CopyItem( HTREEITEM hItem, HTREEITEM htiNewParent,
HTREEITEM htiAfter /*= TVI_LAST*/ )
{
TV_INSERTSTRUCT tvstruct;
HTREEITEM hNewItem;
CString sText;
// get information of the source item
tvstruct.item.hItem = hItem;
tvstruct.item.mask = TVIF_CHILDREN | TVIF_HANDLE |
TVIF_IMAGE | TVIF_SELECTEDIMAGE;
GetItem(&tvstruct.item);
sText = GetItemText( hItem );
tvstruct.item.cchTextMax = sText.GetLength();
tvstruct.item.pszText = sText.LockBuffer();
// Insert the item at proper location
tvstruct.hParent = htiNewParent;
tvstruct.hInsertAfter = htiAfter;
tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
hNewItem = InsertItem(&tvstruct);
sText.ReleaseBuffer();
// Now copy item data and item state.
SetItemData( hNewItem, GetItemData( hItem ));
SetItemState( hNewItem, GetItemState( hItem, TVIS_STATEIMAGEMASK | TVIS_EXPANDED ),
TVIS_STATEIMAGEMASK | TVIS_EXPANDED );
// Call virtual function to allow further processing in derived class
OnItemCopied( hItem, hNewItem );
return hNewItem;
}
//////////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::OnItemCopied(HTREEITEM /*hItem*/, HTREEITEM /*hNewItem*/ )
{
// Virtual function
}
//////////////////////////////////////////////////////////////////////////
// CopyBranch - Copies all items in a branch to a new location
// Returns - The new branch node
// htiBranch - The node that starts the branch
// htiNewParent - Handle of the parent for new branch
// htiAfter - Item after which the new branch should be created
HTREEITEM CTreeCtrlEx::CopyBranch( HTREEITEM htiBranch, HTREEITEM htiNewParent,
HTREEITEM htiAfter /*= TVI_LAST*/ )
{
HTREEITEM hChild;
HTREEITEM hNewItem = CopyItem( htiBranch, htiNewParent, htiAfter );
SetItemState(hNewItem, GetItemState(htiBranch, 0xffffffff), 0xffffffff);
hChild = GetChildItem(htiBranch);
while( hChild != NULL)
{
// recursively transfer all the items
CopyBranch(hChild, hNewItem);
hChild = GetNextSiblingItem( hChild );
}
return hNewItem;
}
//////////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
*pResult = 0;
m_hitemDrag = pNMTreeView->itemNew.hItem;
m_hitemDrop = NULL;
if (!IsDropSource(m_hitemDrag))
return;
m_pDragImage = CreateDragImage(m_hitemDrag); // get the image list for dragging
// CreateDragImage() returns NULL if no image list
// associated with the tree view control
if( !m_pDragImage )
return;
m_bLDragging = true;
// Calculate the offset to the hotspot
CPoint offsetPt(8,8); // Initialize a default offset
CPoint dragPt = pNMTreeView->ptDrag; // Get the Drag point
UINT nHitFlags = 0;
HTREEITEM htiHit = HitTest(dragPt, &nHitFlags);
if (NULL != htiHit)
{
// The drag point has Hit an item in the tree
CRect itemRect;
// Get the text bounding rectangle
if (GetItemRect(htiHit, &itemRect, TRUE))
{
// Calculate the new offset
offsetPt.y = dragPt.y - itemRect.top;
offsetPt.x = dragPt.x - (itemRect.left - GetIndent());
}
/*
if (GetItemRect(htiHit, &itemRect, FALSE))
{
// Count indent levels
HTREEITEM htiParent = htiHit;
int nIndentCnt = 0;
while (htiParent != NULL)
{
htiParent = GetParentItem(htiParent);
nIndentCnt++;
}
if (!(GetStyle() & TVS_LINESATROOT))
nIndentCnt--;
// Calculate the new offset
offsetPt.y = dragPt.y - itemRect.top;
offsetPt.x = dragPt.x - (nIndentCnt * GetIndent()) + GetScrollPos(SB_HORZ);
CImageList* pImageListState = GetImageList(TVSIL_STATE);
UINT nState = GetItemState( htiHit, LVIS_STATEIMAGEMASK );
if (pImageListState && nState)
{
(nState>>=12)--;
IMAGEINFO ImageInfo;
//State Image list
pImageListState->GetImageInfo(nState,&ImageInfo);
offsetPt.x -= (ImageInfo.rcImage.right-ImageInfo.rcImage.left);
}
}
*/
}
/*
CImageList* pList = GetImageList(TVSIL_STATE);
if (pList)
{
IMAGEINFO info;
pList->GetImageInfo(1, &info);
offsetPt.x -= info.rcImage.right-info.rcImage.left;
}
*/
// Begin the Drag operation using the Drag image and the calculated hotspot offset
m_pDragImage->BeginDrag(0, offsetPt);
//m_pDragImage->BeginDrag(0, CPoint(-15,-15));
POINT pt = pNMTreeView->ptDrag;
ClientToScreen( &pt );
m_pDragImage->DragEnter(NULL, pt);
SetCapture();
}
//////////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::OnMouseMove(UINT nFlags, CPoint point)
{
HTREEITEM hitem;
UINT flags;
if (m_bLDragging)
{
POINT pt = point;
ClientToScreen( &pt );
CImageList::DragMove(pt);
hitem = HitTest(point, &flags);
if (m_hitemDrop != hitem)
{
CImageList::DragShowNolock(FALSE);
SelectDropTarget(hitem);
m_hitemDrop = hitem;
CImageList::DragShowNolock(TRUE);
}
if(hitem)
hitem = GetDropTarget(hitem);
if (hitem)
SetCursor(m_dropCursor);
else
SetCursor(m_noDropCursor);
}
CTreeCtrl::OnMouseMove(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::OnLButtonUp(UINT nFlags, CPoint point)
{
CTreeCtrl::OnLButtonUp(nFlags, point);
if (m_bLDragging)
{
m_bLDragging = false;
CImageList::DragLeave(this);
CImageList::EndDrag();
ReleaseCapture();
delete m_pDragImage;
// Remove drop target highlighting
SelectDropTarget(NULL);
m_hitemDrop = GetDropTarget(m_hitemDrop);
if(m_hitemDrop == NULL)
return;
if( m_hitemDrag == m_hitemDrop )
return;
Expand( m_hitemDrop, TVE_EXPAND ) ;
HTREEITEM htiNew = CopyBranch( m_hitemDrag, m_hitemDrop, TVI_LAST );
DeleteItem(m_hitemDrag);
SelectItem( htiNew );
}
}
void CTreeCtrlEx::OnLButtonDown(UINT nFlags, CPoint point)
{
// Set focus on tree when clicked.
SetFocus();
CTreeCtrl::OnLButtonDown(nFlags, point);
}
BOOL CTreeCtrlEx::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN )
{
bool bHandledHere = false;
// When an item is being edited make sure the edit control
// receives certain important key strokes
if (GetKeyState( VK_CONTROL))
{
bHandledHere = true;
}
CString m_Test;
switch(pMsg->wParam)
{
case VK_RETURN:
//GetEditControl()->GetWindowText(m_Test);
//if(SetItemText(m_CurItem.p_Item, m_Test) == NULL)
//TRACE("Unable to Change Item Text(Enter Message)!!!\n");
bHandledHere = true;
break;
case VK_DELETE:
//GetEditControl()->SetWindowText("");
bHandledHere = true;
break;
case VK_ESCAPE:
break;
bHandledHere = true;
}
if (bHandledHere)
{
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE; // DO NOT process further
}
}
if (pMsg->message == WM_KEYDOWN && m_bLDragging)
{
if (pMsg->wParam == VK_ESCAPE)
{
m_bLDragging = false;
CImageList::DragLeave(NULL);
CImageList::EndDrag();
ReleaseCapture();
SelectDropTarget(NULL);
delete m_pDragImage;
m_pDragImage = NULL;
}
return TRUE; // DO NOT process further
}
return CTreeCtrl::PreTranslateMessage(pMsg);
}
//////////////////////////////////////////////////////////////////////////
BOOL CTreeCtrlEx::IsDropSource(HTREEITEM hItem)
{
if (m_bOnlyLeafsDrag)
{
if (GetParentItem(hItem) == TVI_ROOT)
return FALSE;
}
return TRUE; // all other items are valid sources
}
//////////////////////////////////////////////////////////////////////////
HTREEITEM CTreeCtrlEx::GetDropTarget(HTREEITEM hItem)
{
if (hItem != m_hitemDrag && hItem != GetParentItem(m_hitemDrag))
{
if (m_bOnlyLeafsDrag)
{
if (GetParentItem(hItem) != TVI_ROOT)
return GetParentItem(hItem);
}
HTREEITEM htiParent = hItem;
while((htiParent = GetParentItem( htiParent )) != NULL )
{
if( htiParent == m_hitemDrag )
return NULL;
}
return hItem;
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
HTREEITEM CTreeCtrlEx::GetNextItem( HTREEITEM hItem, UINT nCode )
{
return CTreeCtrl::GetNextItem( hItem, nCode );
}
//////////////////////////////////////////////////////////////////////////
HTREEITEM CTreeCtrlEx::GetNextItem(HTREEITEM hItem)
{
HTREEITEM hti = NULL;
if (ItemHasChildren(hItem))
hti = GetChildItem(hItem); // return first child
if (hti == NULL) {
// return next sibling item
// Go up the tree to find a parent's sibling if needed.
while ((hti = GetNextSiblingItem(hItem)) == NULL)
{
if ((hItem = GetParentItem(hItem)) == NULL)
return NULL;
}
}
return hti;
}
//////////////////////////////////////////////////////////////////////////
HTREEITEM CTreeCtrlEx::FindNextItem(TV_ITEM* pItem, HTREEITEM hItem)
{
ASSERT(::IsWindow(m_hWnd));
TV_ITEM hNextItem;
//Clear Item data
ZeroMemory(&hNextItem, sizeof(hNextItem));
//The mask is used to retrieve the data to compare
hNextItem.mask = pItem->mask;
hNextItem.hItem = (hItem) ? GetNextItem(hItem) : GetRootItem();
//Prepare to compare pszText
//Testing pItem->pszText protects the code from a client setting the
//TVIF_TEXT bit but passing in a NULL pointer.
if((pItem->mask & TVIF_TEXT) && pItem->pszText)
{
hNextItem.cchTextMax = strlen(pItem->pszText);
if(hNextItem.cchTextMax)
hNextItem.pszText = new char[++hNextItem.cchTextMax];
}
while(hNextItem.hItem)
{
if(CompareItems(pItem, hNextItem))
{
//Copy all the information into pItem and return
memcpy(pItem, &hNextItem, sizeof(TV_ITEM));
//Free resources
if(hNextItem.pszText)
delete hNextItem.pszText;
return pItem->hItem;
}
//The mask is used to retrieve the data to compare and must be
//reset before calling Compare
hNextItem.mask = pItem->mask;
hNextItem.hItem = GetNextItem(hNextItem.hItem);
}
//Set hItem in pItem
pItem->hItem = NULL;
//Free resources
if(hNextItem.pszText)
delete hNextItem.pszText;
return NULL;
}
//////////////////////////////////////////////////////////////////////////
BOOL CTreeCtrlEx::CompareItems(TV_ITEM* pItem, TV_ITEM& tvTempItem)
{
//This call uses the .mask setting to just retrieve the values
//that the client wants to compare.
//Get all the data passed in by pItem
GetItem(&tvTempItem);
//Reset the mask so I can keep track of the matching attributes
tvTempItem.mask = 0;
if((pItem->mask & TVIF_STATE) &&
(pItem->state == tvTempItem.state))
tvTempItem.mask |= TVIF_STATE;
if((pItem->mask & TVIF_IMAGE) &&
(pItem->iImage == tvTempItem.iImage))
tvTempItem.mask |= TVIF_IMAGE;
if((pItem->mask & TVIF_PARAM) &&
(pItem->lParam == tvTempItem.lParam))
tvTempItem.mask |= TVIF_PARAM;
if((pItem->mask & TVIF_TEXT) &&
pItem->pszText && tvTempItem.pszText && //Don't compare if either is NULL
!strcmp(pItem->pszText, tvTempItem.pszText))
tvTempItem.mask |= TVIF_TEXT;
if((pItem->mask & TVIF_CHILDREN) &&
(pItem->cChildren == tvTempItem.cChildren))
tvTempItem.mask |= TVIF_CHILDREN;
if((pItem->mask & TVIF_SELECTEDIMAGE) &&
(pItem->iSelectedImage == tvTempItem.iSelectedImage))
tvTempItem.mask |= TVIF_SELECTEDIMAGE;
//If by this point these two values are the same.
//tvTempItem.hItem is the desired item
return (pItem->mask == tvTempItem.mask);
}

View File

@@ -0,0 +1,103 @@
////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: treectrlex.h
// Version: v1.00
// Created: 1/8/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History: Assembled from contributions fro www.codeguru.com
//
////////////////////////////////////////////////////////////////////////////
#ifndef __treectrlex_h__
#define __treectrlex_h__
#if _MSC_VER > 1000
#pragma once
#endif
/** CTreeCtrlEx is and extended version of CTreeCtrl,
It allows Drag&Drop of leaf items, and copying of items.
*/
class CTreeCtrlEx : public CTreeCtrl
{
DECLARE_DYNAMIC(CTreeCtrlEx)
public:
CTreeCtrlEx();
virtual ~CTreeCtrlEx();
/** Get next item using standart CTreeCtrl call.
*/
HTREEITEM GetNextItem( HTREEITEM hItem, UINT nCode );
/** Get next item as if outline was completely expanded.
@return The item immediately below the reference item.
@param The reference item.
*/
HTREEITEM GetNextItem( HTREEITEM hItem);
/** FindNextItem traverses a tree searching for an item matching all the item attributes set in a TV_ITEM structure.
In the TV_ITEM structure, the mask member specifies which attributes make up the search criteria.
If a match is found, the function returns the handle otherwise NULL.
The function only searches in one direction (down) and if hItem is NULL starts from the root of the tree.
*/
HTREEITEM FindNextItem(TV_ITEM* pItem, HTREEITEM hItem);
/** Copies an item to a new location
@return Handle of the new item.
@parans hItem Item to be copied.
@param htiNewParent Handle of the parent for new item.
@param htiAfter Item after which the new item should be created.
*/
HTREEITEM CopyItem( HTREEITEM hItem, HTREEITEM htiNewParent, HTREEITEM htiAfter=TVI_LAST );
/** Copies all items in a branch to a new location.
@return The new branch node.
@param htiBranch The node that starts the branch.
@param htiNewParent Handle of the parent for new branch.
@param htiAfter Item after which the new branch should be created.
*/
HTREEITEM CopyBranch( HTREEITEM htiBranch, HTREEITEM htiNewParent,HTREEITEM htiAfter=TVI_LAST );
/** When set only leafs are allowed to be dragged.
*/
void SetOnlyLeafsDrag( bool bEnable ) { m_bOnlyLeafsDrag = bEnable; }
protected:
DECLARE_MESSAGE_MAP()
//! Callback caled when items is copied.
virtual void OnItemCopied( HTREEITEM hItem, HTREEITEM hNewItem );
//! Check if drop source.
virtual BOOL IsDropSource( HTREEITEM hItem );
//! Get item which is target for drop of this item.
virtual HTREEITEM GetDropTarget(HTREEITEM hItem);
BOOL CompareItems(TV_ITEM* pItem, TV_ITEM& tvTempItem);
//////////////////////////////////////////////////////////////////////////
// Message Handlers.
//////////////////////////////////////////////////////////////////////////
afx_msg void OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
virtual BOOL PreTranslateMessage(MSG* pMsg);
//////////////////////////////////////////////////////////////////////////
// For dragging.
CImageList* m_pDragImage;
bool m_bLDragging;
HTREEITEM m_hitemDrag,m_hitemDrop;
HCURSOR m_dropCursor,m_noDropCursor;
bool m_bOnlyLeafsDrag;
};
#endif // __treectrlex_h__

234
Editor/Controls/scbarcf.cpp Normal file
View File

@@ -0,0 +1,234 @@
/////////////////////////////////////////////////////////////////////////
//
// CSizingControlBarCF Version 2.44
//
// Created: Dec 21, 1998 Last Modified: March 31, 2002
//
// See the official site at www.datamekanix.com for documentation and
// the latest news.
//
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// cristi@datamekanix.com or post them at the message board at the site.
/////////////////////////////////////////////////////////////////////////
#include <stdafx.h>
#include "scbarcf.h"
/////////////////////////////////////////////////////////////////////////
// CSizingControlBarCF
IMPLEMENT_DYNAMIC(CSizingControlBarCF, baseCSizingControlBarCF);
int CALLBACK EnumFontFamProc(ENUMLOGFONT FAR *lpelf,
NEWTEXTMETRIC FAR *lpntm,
int FontType,
LPARAM lParam)
{
UNUSED_ALWAYS(lpelf);
UNUSED_ALWAYS(lpntm);
UNUSED_ALWAYS(FontType);
UNUSED_ALWAYS(lParam);
return 0;
}
CSizingControlBarCF::CSizingControlBarCF()
{
m_bActive = FALSE;
CDC dc;
dc.CreateCompatibleDC(NULL);
m_sFontFace = (::EnumFontFamilies(dc.m_hDC,
_T("Tahoma"), (FONTENUMPROC) EnumFontFamProc, 0) == 0) ?
_T("Tahoma") : _T("Arial");
dc.DeleteDC();
}
BEGIN_MESSAGE_MAP(CSizingControlBarCF, baseCSizingControlBarCF)
//{{AFX_MSG_MAP(CSizingControlBarCF)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SETTEXT, OnSetText)
END_MESSAGE_MAP()
void CSizingControlBarCF::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
baseCSizingControlBarCF::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
if (!HasGripper())
return;
BOOL bNeedPaint = FALSE;
CWnd* pFocus = GetFocus();
BOOL bActiveOld = m_bActive;
m_bActive = (pFocus->GetSafeHwnd() && IsChild(pFocus));
if (m_bActive != bActiveOld)
bNeedPaint = TRUE;
if (bNeedPaint)
SendMessage(WM_NCPAINT);
}
// gradient defines (if not already defined)
#ifndef COLOR_GRADIENTACTIVECAPTION
#define COLOR_GRADIENTACTIVECAPTION 27
#define COLOR_GRADIENTINACTIVECAPTION 28
#define SPI_GETGRADIENTCAPTIONS 0x1008
#endif
void CSizingControlBarCF::NcPaintGripper(CDC* pDC, CRect rcClient)
{
if (!HasGripper())
return;
// compute the caption rectangle
BOOL bHorz = IsHorzDocked();
CRect rcGrip = rcClient;
CRect rcBtn = m_biHide.GetRect();
if (bHorz)
{ // right side gripper
rcGrip.left -= m_cyGripper + 1;
rcGrip.right = rcGrip.left + 11;
rcGrip.top = rcBtn.bottom + 3;
}
else
{ // gripper at top
rcGrip.top -= m_cyGripper + 1;
rcGrip.bottom = rcGrip.top + 11;
rcGrip.right = rcBtn.left - 3;
}
rcGrip.InflateRect(bHorz ? 1 : 0, bHorz ? 0 : 1);
// draw the caption background
//CBrush br;
COLORREF clrCptn = m_bActive ?
::GetSysColor(COLOR_ACTIVECAPTION) :
::GetSysColor(COLOR_INACTIVECAPTION);
// query gradient info (usually TRUE for Win98/Win2k)
BOOL bGradient = FALSE;
::SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0);
if (!bGradient)
pDC->FillSolidRect(&rcGrip, clrCptn); // solid color
else
{
// gradient from left to right or from bottom to top
// get second gradient color (the right end)
COLORREF clrCptnRight = m_bActive ?
::GetSysColor(COLOR_GRADIENTACTIVECAPTION) :
::GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
// this will make 2^6 = 64 fountain steps
int nShift = 6;
int nSteps = 1 << nShift;
for (int i = 0; i < nSteps; i++)
{
// do a little alpha blending
int nR = (GetRValue(clrCptn) * (nSteps - i) +
GetRValue(clrCptnRight) * i) >> nShift;
int nG = (GetGValue(clrCptn) * (nSteps - i) +
GetGValue(clrCptnRight) * i) >> nShift;
int nB = (GetBValue(clrCptn) * (nSteps - i) +
GetBValue(clrCptnRight) * i) >> nShift;
COLORREF cr = RGB(nR, nG, nB);
// then paint with the resulting color
CRect r2 = rcGrip;
if (bHorz)
{
r2.bottom = rcGrip.bottom -
((i * rcGrip.Height()) >> nShift);
r2.top = rcGrip.bottom -
(((i + 1) * rcGrip.Height()) >> nShift);
if (r2.Height() > 0)
pDC->FillSolidRect(r2, cr);
}
else
{
r2.left = rcGrip.left +
((i * rcGrip.Width()) >> nShift);
r2.right = rcGrip.left +
(((i + 1) * rcGrip.Width()) >> nShift);
if (r2.Width() > 0)
pDC->FillSolidRect(r2, cr);
}
}
}
// draw the caption text - first select a font
CFont font;
int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
int pointsize = MulDiv(85, 96, ppi); // 8.5 points at 96 ppi
LOGFONT lf;
BOOL bFont = font.CreatePointFont(pointsize, m_sFontFace);
if (bFont)
{
// get the text color
COLORREF clrCptnText = m_bActive ?
::GetSysColor(COLOR_CAPTIONTEXT) :
::GetSysColor(COLOR_INACTIVECAPTIONTEXT);
int nOldBkMode = pDC->SetBkMode(TRANSPARENT);
COLORREF clrOldText = pDC->SetTextColor(clrCptnText);
if (bHorz)
{
// rotate text 90 degrees CCW if horizontally docked
font.GetLogFont(&lf);
font.DeleteObject();
lf.lfEscapement = 900;
font.CreateFontIndirect(&lf);
}
CFont* pOldFont = pDC->SelectObject(&font);
CString sTitle;
GetWindowText(sTitle);
CPoint ptOrg = bHorz ?
CPoint(rcGrip.left - 1, rcGrip.bottom - 3) :
CPoint(rcGrip.left + 3, rcGrip.top - 1);
pDC->ExtTextOut(ptOrg.x, ptOrg.y,
ETO_CLIPPED, rcGrip, sTitle, NULL);
pDC->SelectObject(pOldFont);
pDC->SetBkMode(nOldBkMode);
pDC->SetTextColor(clrOldText);
}
// draw the button
m_biHide.Paint(pDC);
}
LRESULT CSizingControlBarCF::OnSetText(WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = baseCSizingControlBarCF::OnSetText(wParam, lParam);
SendMessage(WM_NCPAINT);
return lResult;
}

79
Editor/Controls/scbarcf.h Normal file
View File

@@ -0,0 +1,79 @@
/////////////////////////////////////////////////////////////////////////
//
// CSizingControlBarCF Version 2.44
//
// Created: Dec 21, 1998 Last Modified: March 31, 2002
//
// See the official site at www.datamekanix.com for documentation and
// the latest news.
//
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// cristi@datamekanix.com or post them at the message board at the site.
/////////////////////////////////////////////////////////////////////////
#if !defined(__SCBARCF_H__)
#define __SCBARCF_H__
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// scbarcf.h : header file
//
#include "sizecbar.h"
#include "scbarg.h"
/////////////////////////////////////////////////////////////////////////
// CSizingControlBarCF
#ifndef baseCSizingControlBarCF
#define baseCSizingControlBarCF CSizingControlBarG
#endif
class CSizingControlBarCF : public baseCSizingControlBarCF
{
DECLARE_DYNAMIC(CSizingControlBarCF)
// Construction
public:
CSizingControlBarCF();
// Overridables
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
// Implementation
protected:
// implementation helpers
virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
protected:
BOOL m_bActive; // a child has focus
CString m_sFontFace;
// Generated message map functions
protected:
//{{AFX_MSG(CSizingControlBarCF)
//}}AFX_MSG
afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////
#endif // !defined(__SCBARCF_H__)

241
Editor/Controls/scbarg.cpp Normal file
View File

@@ -0,0 +1,241 @@
/////////////////////////////////////////////////////////////////////////
//
// CSizingControlBarG Version 2.44
//
// Created: Jan 24, 1998 Last Modified: March 31, 2002
//
// See the official site at www.datamekanix.com for documentation and
// the latest news.
//
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// cristi@datamekanix.com or post them at the message board at the site.
/////////////////////////////////////////////////////////////////////////
// sizecbar.cpp : implementation file
//
#include "stdafx.h"
#include "scbarg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////
// CSizingControlBarG
IMPLEMENT_DYNAMIC(CSizingControlBarG, baseCSizingControlBarG);
CSizingControlBarG::CSizingControlBarG()
{
m_cyGripper = 12;
}
CSizingControlBarG::~CSizingControlBarG()
{
}
BEGIN_MESSAGE_MAP(CSizingControlBarG, baseCSizingControlBarG)
//{{AFX_MSG_MAP(CSizingControlBarG)
ON_WM_NCLBUTTONUP()
ON_WM_NCHITTEST()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SETTEXT, OnSetText)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////
// CSizingControlBarG message handlers
/////////////////////////////////////////////////////////////////////////
// Mouse Handling
//
void CSizingControlBarG::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
if (nHitTest == HTCLOSE)
m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide
baseCSizingControlBarG::OnNcLButtonUp(nHitTest, point);
}
void CSizingControlBarG::NcCalcClient(LPRECT pRc, UINT nDockBarID)
{
CRect rcBar(pRc); // save the bar rect
// subtract edges
baseCSizingControlBarG::NcCalcClient(pRc, nDockBarID);
if (!HasGripper())
return;
CRect rc(pRc); // the client rect as calculated by the base class
BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
(nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
if (bHorz)
rc.DeflateRect(m_cyGripper, 0, 0, 0);
else
rc.DeflateRect(0, m_cyGripper, 0, 0);
// set position for the "x" (hide bar) button
CPoint ptOrgBtn;
if (bHorz)
ptOrgBtn = CPoint(rc.left - 13, rc.top);
else
ptOrgBtn = CPoint(rc.right - 12, rc.top - 13);
m_biHide.Move(ptOrgBtn - rcBar.TopLeft());
*pRc = rc;
}
void CSizingControlBarG::NcPaintGripper(CDC* pDC, CRect rcClient)
{
if (!HasGripper())
return;
// paints a simple "two raised lines" gripper
// override this if you want a more sophisticated gripper
CRect gripper = rcClient;
CRect rcbtn = m_biHide.GetRect();
BOOL bHorz = IsHorzDocked();
gripper.DeflateRect(1, 1);
if (bHorz)
{ // gripper at left
gripper.left -= m_cyGripper;
gripper.right = gripper.left + 3;
gripper.top = rcbtn.bottom + 3;
}
else
{ // gripper at top
gripper.top -= m_cyGripper;
gripper.bottom = gripper.top + 3;
gripper.right = rcbtn.left - 3;
}
pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
gripper.OffsetRect(bHorz ? 3 : 0, bHorz ? 0 : 3);
pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
m_biHide.Paint(pDC);
}
UINT CSizingControlBarG::OnNcHitTest(CPoint point)
{
CRect rcBar;
GetWindowRect(rcBar);
UINT nRet = baseCSizingControlBarG::OnNcHitTest(point);
if (nRet != HTCLIENT)
return nRet;
CRect rc = m_biHide.GetRect();
rc.OffsetRect(rcBar.TopLeft());
if (rc.PtInRect(point))
return HTCLOSE;
return HTCLIENT;
}
/////////////////////////////////////////////////////////////////////////
// CSizingControlBarG implementation helpers
void CSizingControlBarG::OnUpdateCmdUI(CFrameWnd* pTarget,
BOOL bDisableIfNoHndler)
{
UNUSED_ALWAYS(bDisableIfNoHndler);
UNUSED_ALWAYS(pTarget);
if (!HasGripper())
return;
BOOL bNeedPaint = FALSE;
CPoint pt;
::GetCursorPos(&pt);
BOOL bHit = (OnNcHitTest(pt) == HTCLOSE);
BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0);
BOOL bWasPushed = m_biHide.bPushed;
m_biHide.bPushed = bHit && bLButtonDown;
BOOL bWasRaised = m_biHide.bRaised;
m_biHide.bRaised = bHit && !bLButtonDown;
bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) ||
(m_biHide.bRaised ^ bWasRaised);
if (bNeedPaint)
SendMessage(WM_NCPAINT);
}
/////////////////////////////////////////////////////////////////////////
// CSCBButton
CSCBButton::CSCBButton()
{
bRaised = FALSE;
bPushed = FALSE;
}
void CSCBButton::Paint(CDC* pDC)
{
CRect rc = GetRect();
if (bPushed)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
else
if (bRaised)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
COLORREF clrOldTextColor = pDC->GetTextColor();
pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
CFont font;
int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
int pointsize = MulDiv(60, 96, ppi); // 6 points at 96 ppi
font.CreatePointFont(pointsize, _T("Marlett"));
CFont* oldfont = pDC->SelectObject(&font);
pDC->TextOut(ptOrg.x + 2, ptOrg.y + 2, CString(_T("r"))); // x-like
pDC->SelectObject(oldfont);
pDC->SetBkMode(nPrevBkMode);
pDC->SetTextColor(clrOldTextColor);
}
BOOL CSizingControlBarG::HasGripper() const
{
#if defined(_SCB_MINIFRAME_CAPTION) || !defined(_SCB_REPLACE_MINIFRAME)
// if the miniframe has a caption, don't display the gripper
if (IsFloating())
return FALSE;
#endif //_SCB_MINIFRAME_CAPTION
return TRUE;
}

113
Editor/Controls/scbarg.h Normal file
View File

@@ -0,0 +1,113 @@
/////////////////////////////////////////////////////////////////////////
//
// CSizingControlBarG Version 2.44
//
// Created: Jan 24, 1998 Last Modified: March 31, 2002
//
// See the official site at www.datamekanix.com for documentation and
// the latest news.
//
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// cristi@datamekanix.com or post them at the message board at the site.
/////////////////////////////////////////////////////////////////////////
#if !defined(__SCBARG_H__)
#define __SCBARG_H__
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "sizecbar.h"
/////////////////////////////////////////////////////////////////////////
// CSCBButton (button info) helper class
class CSCBButton
{
public:
CSCBButton();
void Move(CPoint ptTo) {ptOrg = ptTo; };
CRect GetRect() { return CRect(ptOrg, CSize(11, 11)); };
void Paint(CDC* pDC);
BOOL bPushed;
BOOL bRaised;
protected:
CPoint ptOrg;
};
/////////////////////////////////////////////////////////////////////////
// CSizingControlBar control bar
#ifndef baseCSizingControlBarG
#define baseCSizingControlBarG CSizingControlBar
#endif
class CSizingControlBarG : public baseCSizingControlBarG
{
DECLARE_DYNAMIC(CSizingControlBarG);
// Construction
public:
CSizingControlBarG();
// Attributes
public:
virtual BOOL HasGripper() const;
// Operations
public:
// Overridables
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSizingControlBarG)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSizingControlBarG();
protected:
// implementation helpers
virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
virtual void NcCalcClient(LPRECT pRc, UINT nDockBarID);
protected:
int m_cyGripper;
CSCBButton m_biHide;
// Generated message map functions
protected:
//{{AFX_MSG(CSizingControlBarG)
afx_msg UINT OnNcHitTest(CPoint point);
afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // !defined(__SCBARG_H__)

1414
Editor/Controls/sizecbar.cpp Normal file

File diff suppressed because it is too large Load Diff

239
Editor/Controls/sizecbar.h Normal file
View File

@@ -0,0 +1,239 @@
/////////////////////////////////////////////////////////////////////////
//
// CSizingControlBar Version 2.44
//
// Created: Jan 24, 1998 Last Modified: March 31, 2002
//
// See the official site at www.datamekanix.com for documentation and
// the latest news.
//
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// cristi@datamekanix.com or post them at the message board at the site.
/////////////////////////////////////////////////////////////////////////
#if !defined(__SIZECBAR_H__)
#define __SIZECBAR_H__
#include <afxpriv.h> // for CDockContext
#include <afxtempl.h> // for CTypedPtrArray
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#if defined(_SCB_MINIFRAME_CAPTION) && !defined(_SCB_REPLACE_MINIFRAME)
#error "_SCB_MINIFRAME_CAPTION requires _SCB_REPLACE_MINIFRAME"
#endif
/////////////////////////////////////////////////////////////////////////
// CSCBDockBar dummy class for access to protected members
class CSCBDockBar : public CDockBar
{
friend class CSizingControlBar;
};
/////////////////////////////////////////////////////////////////////////
// CSizingControlBar control bar styles
#define SCBS_EDGELEFT 0x00000001
#define SCBS_EDGERIGHT 0x00000002
#define SCBS_EDGETOP 0x00000004
#define SCBS_EDGEBOTTOM 0x00000008
#define SCBS_EDGEALL 0x0000000F
#define SCBS_SHOWEDGES 0x00000010
#define SCBS_SIZECHILD 0x00000020
/////////////////////////////////////////////////////////////////////////
// CSizingControlBar control bar
#ifndef baseCSizingControlBar
#define baseCSizingControlBar CControlBar
#endif
class CSizingControlBar;
typedef CTypedPtrArray <CPtrArray, CSizingControlBar*> CSCBArray;
class CSizingControlBar : public baseCSizingControlBar
{
DECLARE_DYNAMIC(CSizingControlBar);
// Construction
public:
CSizingControlBar();
virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
CSize sizeDefault, BOOL bHasGripper,
UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
virtual BOOL Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
UINT nID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
// Attributes
public:
const BOOL IsFloating() const;
const BOOL IsHorzDocked() const;
const BOOL IsVertDocked() const;
const BOOL IsSideTracking() const;
const BOOL GetSCBStyle() const {return m_dwSCBStyle;}
// Operations
public:
#if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
void EnableDocking(DWORD dwDockStyle);
#endif
virtual void LoadState(LPCTSTR lpszProfileName);
virtual void SaveState(LPCTSTR lpszProfileName);
static void GlobalLoadState(CFrameWnd* pFrame, LPCTSTR lpszProfileName);
static void GlobalSaveState(CFrameWnd* pFrame, LPCTSTR lpszProfileName);
void SetSCBStyle(DWORD dwSCBStyle)
{m_dwSCBStyle = (dwSCBStyle & ~SCBS_EDGEALL);}
// Overridables
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSizingControlBar)
public:
virtual CSize CalcFixedLayout(BOOL bStretch, BOOL bHorz);
virtual CSize CalcDynamicLayout(int nLength, DWORD dwMode);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSizingControlBar();
protected:
// implementation helpers
UINT GetEdgeHTCode(int nEdge);
BOOL GetEdgeRect(CRect rcWnd, UINT nHitTest, CRect& rcEdge);
virtual void StartTracking(UINT nHitTest, CPoint point);
virtual void StopTracking();
virtual void OnTrackUpdateSize(CPoint& point);
virtual void OnTrackInvertTracker();
virtual void NcPaintGripper(CDC* pDC, CRect rcClient);
virtual void NcCalcClient(LPRECT pRc, UINT nDockBarID);
virtual void AlignControlBars();
void GetRowInfo(int& nFirst, int& nLast, int& nThis);
void GetRowSizingBars(CSCBArray& arrSCBars);
void GetRowSizingBars(CSCBArray& arrSCBars, int& nThis);
BOOL NegotiateSpace(int nLengthTotal, BOOL bHorz);
protected:
DWORD m_dwSCBStyle;
UINT m_htEdge;
CSize m_szHorz;
CSize m_szVert;
CSize m_szFloat;
CSize m_szMinHorz;
CSize m_szMinVert;
CSize m_szMinFloat;
int m_nTrackPosMin;
int m_nTrackPosMax;
int m_nTrackPosOld;
int m_nTrackEdgeOfs;
BOOL m_bTracking;
BOOL m_bKeepSize;
BOOL m_bParentSizing;
BOOL m_bDragShowContent;
UINT m_nDockBarID;
int m_cxEdge;
// Generated message map functions
protected:
//{{AFX_MSG(CSizingControlBar)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnNcPaint();
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp);
afx_msg UINT OnNcHitTest(CPoint point);
afx_msg void OnCaptureChanged(CWnd *pWnd);
afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
afx_msg void OnPaint();
afx_msg void OnClose();
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
#ifdef _SCB_REPLACE_MINIFRAME
friend class CSCBMiniDockFrameWnd;
#endif //_SCB_REPLACE_MINIFRAME
};
#ifdef _SCB_REPLACE_MINIFRAME
#ifndef _SCB_MINIFRAME_CAPTION
/////////////////////////////////////////////////////////////////////////
// CSCBDockContext dockcontext
class CSCBDockContext : public CDockContext
{
public:
// Construction
CSCBDockContext(CControlBar* pBar) : CDockContext(pBar) {}
// Drag Operations
virtual void StartDrag(CPoint pt);
};
#endif //_SCB_MINIFRAME_CAPTION
/////////////////////////////////////////////////////////////////////////
// CSCBMiniDockFrameWnd miniframe
#ifndef baseCSCBMiniDockFrameWnd
#define baseCSCBMiniDockFrameWnd CMiniDockFrameWnd
#endif
class CSCBMiniDockFrameWnd : public baseCSCBMiniDockFrameWnd
{
DECLARE_DYNCREATE(CSCBMiniDockFrameWnd)
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSCBMiniDockFrameWnd)
public:
virtual BOOL Create(CWnd* pParent, DWORD dwBarStyle);
//}}AFX_VIRTUAL
// Implementation
public:
CSizingControlBar* GetSizingControlBar();
//{{AFX_MSG(CSCBMiniDockFrameWnd)
afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
afx_msg void OnSize(UINT nType, int cx, int cy);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif //_SCB_REPLACE_MINIFRAME
#endif // !defined(__SIZECBAR_H__)