123
This commit is contained in:
80
Editor/Controls/AnimSequences.cpp
Normal file
80
Editor/Controls/AnimSequences.cpp
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
50
Editor/Controls/AnimSequences.h
Normal file
50
Editor/Controls/AnimSequences.h
Normal 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_)
|
||||
179
Editor/Controls/AnimationToolBar.cpp
Normal file
179
Editor/Controls/AnimationToolBar.cpp
Normal 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;
|
||||
}
|
||||
56
Editor/Controls/AnimationToolBar.h
Normal file
56
Editor/Controls/AnimationToolBar.h
Normal 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_)
|
||||
61
Editor/Controls/ColorCheckBox.cpp
Normal file
61
Editor/Controls/ColorCheckBox.cpp
Normal 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 );
|
||||
}
|
||||
62
Editor/Controls/ColorCheckBox.h
Normal file
62
Editor/Controls/ColorCheckBox.h
Normal 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
796
Editor/Controls/ColorCtrl.h
Normal 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_)
|
||||
|
||||
384
Editor/Controls/ConsoleSCB.cpp
Normal file
384
Editor/Controls/ConsoleSCB.cpp
Normal 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( "" );
|
||||
}
|
||||
63
Editor/Controls/ConsoleSCB.h
Normal file
63
Editor/Controls/ConsoleSCB.h
Normal 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_)
|
||||
98
Editor/Controls/CustomComboBoxEx.h
Normal file
98
Editor/Controls/CustomComboBoxEx.h
Normal 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
170
Editor/Controls/DLGBARS.CPP
Normal 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
73
Editor/Controls/DLGBARS.H
Normal 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__
|
||||
|
||||
|
||||
|
||||
244
Editor/Controls/DropListBox.cpp
Normal file
244
Editor/Controls/DropListBox.cpp
Normal 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;
|
||||
}
|
||||
94
Editor/Controls/DropListBox.h
Normal file
94
Editor/Controls/DropListBox.h
Normal 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_)
|
||||
199
Editor/Controls/DropScrollBar.cpp
Normal file
199
Editor/Controls/DropScrollBar.cpp
Normal 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);
|
||||
}
|
||||
|
||||
77
Editor/Controls/DropScrollBar.h
Normal file
77
Editor/Controls/DropScrollBar.h
Normal 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
471
Editor/Controls/DropWnd.cpp
Normal 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
104
Editor/Controls/DropWnd.h
Normal 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_)
|
||||
528
Editor/Controls/EditModeToolBar.cpp
Normal file
528
Editor/Controls/EditModeToolBar.cpp
Normal 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();
|
||||
}
|
||||
86
Editor/Controls/EditModeToolBar.h
Normal file
86
Editor/Controls/EditModeToolBar.h
Normal 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_)
|
||||
163
Editor/Controls/FileTree.cpp
Normal file
163
Editor/Controls/FileTree.cpp
Normal 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("");
|
||||
}
|
||||
68
Editor/Controls/FileTree.h
Normal file
68
Editor/Controls/FileTree.h
Normal 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_)
|
||||
286
Editor/Controls/HiColorToolBar.cpp
Normal file
286
Editor/Controls/HiColorToolBar.cpp
Normal 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;
|
||||
}
|
||||
84
Editor/Controls/HiColorToolBar.h
Normal file
84
Editor/Controls/HiColorToolBar.h
Normal 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_)
|
||||
48
Editor/Controls/InPlaceButton.cpp
Normal file
48
Editor/Controls/InPlaceButton.cpp
Normal 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();
|
||||
}
|
||||
47
Editor/Controls/InPlaceButton.h
Normal file
47
Editor/Controls/InPlaceButton.h
Normal 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__
|
||||
743
Editor/Controls/InPlaceComboBox.cpp
Normal file
743
Editor/Controls/InPlaceComboBox.cpp
Normal 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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
238
Editor/Controls/InPlaceComboBox.h
Normal file
238
Editor/Controls/InPlaceComboBox.h
Normal 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
|
||||
|
||||
|
||||
99
Editor/Controls/InPlaceEdit.cpp
Normal file
99
Editor/Controls/InPlaceEdit.cpp
Normal 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;
|
||||
}
|
||||
57
Editor/Controls/InPlaceEdit.h
Normal file
57
Editor/Controls/InPlaceEdit.h
Normal 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__
|
||||
743
Editor/Controls/LayersListBox.cpp
Normal file
743
Editor/Controls/LayersListBox.cpp
Normal 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;
|
||||
}
|
||||
120
Editor/Controls/LayersListBox.h
Normal file
120
Editor/Controls/LayersListBox.h
Normal 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
152
Editor/Controls/MemDC.h
Normal 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
|
||||
888
Editor/Controls/MltiTree.cpp
Normal file
888
Editor/Controls/MltiTree.cpp
Normal 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
148
Editor/Controls/MltiTree.h
Normal 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
6185
Editor/Controls/NewMenu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
892
Editor/Controls/NewMenu.h
Normal file
892
Editor/Controls/NewMenu.h
Normal 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_
|
||||
661
Editor/Controls/NumberCtrl.cpp
Normal file
661
Editor/Controls/NumberCtrl.cpp
Normal 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;
|
||||
}
|
||||
148
Editor/Controls/NumberCtrl.h
Normal file
148
Editor/Controls/NumberCtrl.h
Normal 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_)
|
||||
109
Editor/Controls/NumberCtrlEdit.cpp
Normal file
109
Editor/Controls/NumberCtrlEdit.cpp
Normal 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);
|
||||
}
|
||||
64
Editor/Controls/NumberCtrlEdit.h
Normal file
64
Editor/Controls/NumberCtrlEdit.h
Normal 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__
|
||||
73
Editor/Controls/PickObjectButton.cpp
Normal file
73
Editor/Controls/PickObjectButton.cpp
Normal 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;
|
||||
}
|
||||
70
Editor/Controls/PickObjectButton.h
Normal file
70
Editor/Controls/PickObjectButton.h
Normal 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__
|
||||
712
Editor/Controls/PreviewModelCtrl.cpp
Normal file
712
Editor/Controls/PreviewModelCtrl.cpp
Normal 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;
|
||||
}
|
||||
128
Editor/Controls/PreviewModelCtrl.h
Normal file
128
Editor/Controls/PreviewModelCtrl.h
Normal 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_)
|
||||
1530
Editor/Controls/PropertyCtrl.cpp
Normal file
1530
Editor/Controls/PropertyCtrl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
257
Editor/Controls/PropertyCtrl.h
Normal file
257
Editor/Controls/PropertyCtrl.h
Normal 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__
|
||||
1485
Editor/Controls/PropertyItem.cpp
Normal file
1485
Editor/Controls/PropertyItem.cpp
Normal file
File diff suppressed because it is too large
Load Diff
317
Editor/Controls/PropertyItem.h
Normal file
317
Editor/Controls/PropertyItem.h
Normal 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__
|
||||
147
Editor/Controls/RollupBar.cpp
Normal file
147
Editor/Controls/RollupBar.cpp
Normal 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];
|
||||
}
|
||||
45
Editor/Controls/RollupBar.h
Normal file
45
Editor/Controls/RollupBar.h
Normal 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_)
|
||||
905
Editor/Controls/RollupCtrl.cpp
Normal file
905
Editor/Controls/RollupCtrl.cpp
Normal 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;
|
||||
}
|
||||
180
Editor/Controls/RollupCtrl.h
Normal file
180
Editor/Controls/RollupCtrl.h
Normal 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_)
|
||||
91
Editor/Controls/SelectionCombo.cpp
Normal file
91
Editor/Controls/SelectionCombo.cpp
Normal 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);
|
||||
}
|
||||
54
Editor/Controls/SelectionCombo.h
Normal file
54
Editor/Controls/SelectionCombo.h
Normal 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_)
|
||||
81
Editor/Controls/SplitterWndEx.cpp
Normal file
81
Editor/Controls/SplitterWndEx.cpp
Normal 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();
|
||||
}
|
||||
45
Editor/Controls/SplitterWndEx.h
Normal file
45
Editor/Controls/SplitterWndEx.h
Normal 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__
|
||||
571
Editor/Controls/SyntaxColorizer.cpp
Normal file
571
Editor/Controls/SyntaxColorizer.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
113
Editor/Controls/SyntaxColorizer.h
Normal file
113
Editor/Controls/SyntaxColorizer.h
Normal 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
105
Editor/Controls/TemplDef.h
Normal 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_)
|
||||
222
Editor/Controls/TextEditorCtrl.cpp
Normal file
222
Editor/Controls/TextEditorCtrl.cpp
Normal 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);
|
||||
}
|
||||
53
Editor/Controls/TextEditorCtrl.h
Normal file
53
Editor/Controls/TextEditorCtrl.h
Normal 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__
|
||||
53
Editor/Controls/ToolBarContainer.cpp
Normal file
53
Editor/Controls/ToolBarContainer.cpp
Normal 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
|
||||
}
|
||||
47
Editor/Controls/ToolBarContainer.h
Normal file
47
Editor/Controls/ToolBarContainer.h
Normal 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_)
|
||||
206
Editor/Controls/ToolBarTab.cpp
Normal file
206
Editor/Controls/ToolBarTab.cpp
Normal 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);
|
||||
}
|
||||
61
Editor/Controls/ToolBarTab.h
Normal file
61
Editor/Controls/ToolBarTab.h
Normal 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_)
|
||||
143
Editor/Controls/ToolButton.cpp
Normal file
143
Editor/Controls/ToolButton.cpp
Normal 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;
|
||||
}
|
||||
64
Editor/Controls/ToolButton.h
Normal file
64
Editor/Controls/ToolButton.h
Normal 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_)
|
||||
498
Editor/Controls/TreeCtrlEx.cpp
Normal file
498
Editor/Controls/TreeCtrlEx.cpp
Normal 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);
|
||||
}
|
||||
103
Editor/Controls/TreeCtrlEx.h
Normal file
103
Editor/Controls/TreeCtrlEx.h
Normal 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
234
Editor/Controls/scbarcf.cpp
Normal 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
79
Editor/Controls/scbarcf.h
Normal 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
241
Editor/Controls/scbarg.cpp
Normal 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
113
Editor/Controls/scbarg.h
Normal 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
1414
Editor/Controls/sizecbar.cpp
Normal file
File diff suppressed because it is too large
Load Diff
239
Editor/Controls/sizecbar.h
Normal file
239
Editor/Controls/sizecbar.h
Normal 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__)
|
||||
|
||||
Reference in New Issue
Block a user