mirror of
https://github.com/balloonwj/TeamTalk.git
synced 2026-10-21 00:36:35 +08:00
774 lines
21 KiB
C++
774 lines
21 KiB
C++
#include "StdAfx.h"
|
|
#include "UIMenu.h"
|
|
//#include "utility/utilStrCodingAPI.h"
|
|
//#include "UI/MainDialog.h"
|
|
namespace DuiLib {
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
ContextMenuObserver s_context_menu_observer;
|
|
|
|
// MenuUI
|
|
const TCHAR* const kMenuUIClassName = _T("MenuUI");
|
|
const TCHAR* const kMenuUIInterfaceName = _T("Menu");
|
|
|
|
CMenuUI::CMenuUI()
|
|
{
|
|
if (GetHeader() != NULL)
|
|
GetHeader()->SetVisible(false);
|
|
}
|
|
|
|
CMenuUI::~CMenuUI()
|
|
{}
|
|
|
|
LPCTSTR CMenuUI::GetClass() const
|
|
{
|
|
return kMenuUIClassName;
|
|
}
|
|
|
|
LPVOID CMenuUI::GetInterface(LPCTSTR pstrName)
|
|
{
|
|
if( _tcsicmp(pstrName, kMenuUIInterfaceName) == 0 ) return static_cast<CMenuUI*>(this);
|
|
return CListUI::GetInterface(pstrName);
|
|
}
|
|
|
|
void CMenuUI::DoEvent(TEventUI& event)
|
|
{
|
|
//CString strOutPut;
|
|
//strOutPut.Format(_T("CMenuUI::DoEvent-UIEVENT_BUTTONDOWN %d \n\r"), event.Type);
|
|
//OutputDebugString(strOutPut);
|
|
if (event.Type == UIEVENT_BUTTONDOWN)
|
|
{
|
|
//OutputDebugString(_T("CMenuUI::DoEvent-UIEVENT_BUTTONDOWN\\n"));
|
|
}
|
|
return __super::DoEvent(event);
|
|
}
|
|
|
|
bool CMenuUI::Add(CControlUI* pControl)
|
|
{
|
|
CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(kMenuElementUIInterfaceName));
|
|
if (pMenuItem == NULL)
|
|
return false;
|
|
|
|
for (int i = 0; i < pMenuItem->GetCount(); ++i)
|
|
{
|
|
if (pMenuItem->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL)
|
|
{
|
|
(static_cast<CMenuElementUI*>(pMenuItem->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetInternVisible(false);
|
|
}
|
|
}
|
|
return CListUI::Add(pControl);
|
|
}
|
|
|
|
bool CMenuUI::AddAt(CControlUI* pControl, int iIndex)
|
|
{
|
|
CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(kMenuElementUIInterfaceName));
|
|
if (pMenuItem == NULL)
|
|
return false;
|
|
|
|
for (int i = 0; i < pMenuItem->GetCount(); ++i)
|
|
{
|
|
if (pMenuItem->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL)
|
|
{
|
|
(static_cast<CMenuElementUI*>(pMenuItem->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetInternVisible(false);
|
|
}
|
|
}
|
|
return CListUI::AddAt(pControl, iIndex);
|
|
}
|
|
|
|
int CMenuUI::GetItemIndex(CControlUI* pControl) const
|
|
{
|
|
CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(kMenuElementUIInterfaceName));
|
|
if (pMenuItem == NULL)
|
|
return -1;
|
|
|
|
return __super::GetItemIndex(pControl);
|
|
}
|
|
|
|
bool CMenuUI::SetItemIndex(CControlUI* pControl, int iIndex)
|
|
{
|
|
CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(kMenuElementUIInterfaceName));
|
|
if (pMenuItem == NULL)
|
|
return false;
|
|
|
|
return __super::SetItemIndex(pControl, iIndex);
|
|
}
|
|
|
|
bool CMenuUI::Remove(CControlUI* pControl)
|
|
{
|
|
CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(kMenuElementUIInterfaceName));
|
|
if (pMenuItem == NULL)
|
|
return false;
|
|
|
|
return __super::Remove(pControl);
|
|
}
|
|
|
|
SIZE CMenuUI::EstimateSize(SIZE szAvailable)
|
|
{
|
|
int cxFixed = 0;
|
|
int cyFixed = 0;
|
|
for( int it = 0; it < GetCount(); it++ ) {
|
|
CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it));
|
|
if( !pControl->IsVisible() ) continue;
|
|
SIZE sz = pControl->EstimateSize(szAvailable);
|
|
cyFixed += sz.cy;
|
|
if( cxFixed < sz.cx )
|
|
cxFixed = sz.cx;
|
|
}
|
|
return CSize(cxFixed, cyFixed);
|
|
}
|
|
|
|
void CMenuUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
|
|
{
|
|
CListUI::SetAttribute(pstrName, pstrValue);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
class CMenuBuilderCallback: public IDialogBuilderCallback
|
|
{
|
|
CControlUI* CreateControl(LPCTSTR pstrClass)
|
|
{
|
|
if (_tcsicmp(pstrClass, kMenuUIInterfaceName) == 0)
|
|
{
|
|
return new CMenuUI();
|
|
}
|
|
else if (_tcsicmp(pstrClass, kMenuElementUIInterfaceName) == 0)
|
|
{
|
|
return new CMenuElementUI();
|
|
}
|
|
return NULL;
|
|
}
|
|
};
|
|
|
|
CMenuWnd::CMenuWnd(HWND hParent):
|
|
m_hParent(hParent),
|
|
m_pOwner(NULL),
|
|
m_pLayout(),
|
|
m_xml(_T(""))
|
|
{}
|
|
|
|
BOOL CMenuWnd::Receive(ContextMenuParam param)
|
|
{
|
|
switch (param.wParam)
|
|
{
|
|
case 1:
|
|
{
|
|
if (param.name.IsEmpty())
|
|
{
|
|
Close();
|
|
return TRUE;
|
|
}
|
|
::SendMessage(m_hParent, WM_MENU_NOTIFY, WPARAM(param.name.GetData()), LPARAM(m_sUserData.GetData()));
|
|
Close();
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
HWND hParent = GetParent(m_hWnd);
|
|
while (hParent != NULL)
|
|
{
|
|
if (hParent == param.hWnd)
|
|
{
|
|
Close();
|
|
break;
|
|
}
|
|
hParent = GetParent(hParent);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CMenuWnd::Init(CMenuElementUI* pOwner, STRINGorID xml, LPCTSTR pSkinType, POINT point)
|
|
{
|
|
|
|
m_BasedPoint = point;
|
|
m_pOwner = pOwner;
|
|
m_pLayout = NULL;
|
|
|
|
if (pSkinType != NULL)
|
|
m_sType = pSkinType;
|
|
|
|
m_xml = xml;
|
|
|
|
s_context_menu_observer.AddReceiver(this);
|
|
|
|
Create((m_pOwner == NULL) ? m_hParent : m_pOwner->GetManager()->GetPaintWindow(), NULL, WS_POPUP, WS_EX_TOOLWINDOW | WS_EX_TOPMOST, CDuiRect());
|
|
// HACK: Don't deselect the parent's caption
|
|
HWND hWndParent = m_hWnd;
|
|
while( ::GetParent(hWndParent) != NULL ) hWndParent = ::GetParent(hWndParent);
|
|
|
|
::ShowWindow(m_hWnd, SW_SHOW);
|
|
::SendMessage(hWndParent, WM_NCACTIVATE, TRUE, 0L);
|
|
AdjustPostion(point);
|
|
}
|
|
|
|
LPCTSTR CMenuWnd::GetWindowClassName() const
|
|
{
|
|
return _T("MenuWnd");
|
|
}
|
|
|
|
void CMenuWnd::OnFinalMessage(HWND hWnd)
|
|
{
|
|
RemoveObserver();
|
|
if( m_pOwner != NULL ) {
|
|
for( int i = 0; i < m_pOwner->GetCount(); i++ ) {
|
|
if( static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)) != NULL )
|
|
{
|
|
(static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetOwner(m_pOwner->GetParent());
|
|
(static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetVisible(false);
|
|
(static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetInternVisible(false);
|
|
}
|
|
}
|
|
if (m_pOwner->m_pWindow)
|
|
{
|
|
delete m_pOwner->m_pWindow;
|
|
}
|
|
m_pOwner->m_pWindow = NULL;
|
|
m_pOwner->m_uButtonState &= ~ UISTATE_PUSHED;
|
|
m_pOwner->Invalidate();
|
|
}
|
|
delete this;
|
|
}
|
|
|
|
LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if( uMsg == WM_CREATE ) {
|
|
if( m_pOwner != NULL) {
|
|
LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
|
|
styleValue &= ~WS_CAPTION;
|
|
::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
|
|
RECT rcClient;
|
|
::GetClientRect(*this, &rcClient);
|
|
::SetWindowPos(*this, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, \
|
|
rcClient.bottom - rcClient.top, SWP_FRAMECHANGED);
|
|
|
|
m_pm.Init(m_hWnd);
|
|
// The trick is to add the items to the new container. Their owner gets
|
|
// reassigned by this operation - which is why it is important to reassign
|
|
// the items back to the righfull owner/manager when the window closes.
|
|
m_pLayout = new CMenuUI();
|
|
m_pm.UseParentResource(m_pOwner->GetManager());
|
|
m_pLayout->SetManager(&m_pm, NULL, true);
|
|
LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(kMenuUIInterfaceName);
|
|
if( pDefaultAttributes ) {
|
|
m_pLayout->ApplyAttributeList(pDefaultAttributes);
|
|
}
|
|
m_pLayout->SetBkColor(0xFFFFFFFF);
|
|
m_pLayout->SetBorderColor(0xFF85E4FF);
|
|
m_pLayout->SetBorderSize(0);
|
|
m_pLayout->SetAutoDestroy(false);
|
|
m_pLayout->EnableScrollBar();
|
|
for( int i = 0; i < m_pOwner->GetCount(); i++ ) {
|
|
if(m_pOwner->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL ){
|
|
(static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetOwner(m_pLayout);
|
|
m_pLayout->Add(static_cast<CControlUI*>(m_pOwner->GetItemAt(i)));
|
|
}
|
|
}
|
|
m_pm.AttachDialog(m_pLayout);
|
|
|
|
// Position the popup window in absolute space
|
|
RECT rcOwner = m_pOwner->GetPos();
|
|
RECT rc = rcOwner;
|
|
|
|
int cxFixed = 0;
|
|
int cyFixed = 0;
|
|
|
|
#if defined(WIN32) && !defined(UNDER_CE)
|
|
MONITORINFO oMonitor = {};
|
|
oMonitor.cbSize = sizeof(oMonitor);
|
|
::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
|
|
CDuiRect rcWork = oMonitor.rcWork;
|
|
#else
|
|
CDuiRect rcWork;
|
|
GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork);
|
|
#endif
|
|
SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top };
|
|
|
|
for( int it = 0; it < m_pOwner->GetCount(); it++ ) {
|
|
if(m_pOwner->GetItemAt(it)->GetInterface(kMenuElementUIInterfaceName) != NULL ){
|
|
CControlUI* pControl = static_cast<CControlUI*>(m_pOwner->GetItemAt(it));
|
|
SIZE sz = pControl->EstimateSize(szAvailable);
|
|
cyFixed += sz.cy;
|
|
|
|
if( cxFixed < sz.cx )
|
|
cxFixed = sz.cx;
|
|
}
|
|
}
|
|
cyFixed += 4;
|
|
cxFixed += 4;
|
|
|
|
RECT rcWindow;
|
|
GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWindow);
|
|
|
|
rc.top = rcOwner.top;
|
|
rc.bottom = rc.top + cyFixed;
|
|
::MapWindowRect(m_pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc);
|
|
rc.left = rcWindow.right;
|
|
rc.right = rc.left + cxFixed;
|
|
rc.right += 2;
|
|
|
|
bool bReachBottom = false;
|
|
bool bReachRight = false;
|
|
LONG chRightAlgin = 0;
|
|
LONG chBottomAlgin = 0;
|
|
|
|
RECT rcPreWindow = {0};
|
|
ContextMenuObserver::Iterator<BOOL, ContextMenuParam> iterator(s_context_menu_observer);
|
|
ReceiverImplBase<BOOL, ContextMenuParam>* pReceiver = iterator.next();
|
|
while( pReceiver != NULL ) {
|
|
CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver);
|
|
if( pContextMenu != NULL ) {
|
|
GetWindowRect(pContextMenu->GetHWND(), &rcPreWindow);
|
|
|
|
bReachRight = rcPreWindow.left >= rcWindow.right;
|
|
bReachBottom = rcPreWindow.top >= rcWindow.bottom;
|
|
if( pContextMenu->GetHWND() == m_pOwner->GetManager()->GetPaintWindow()
|
|
|| bReachBottom || bReachRight )
|
|
break;
|
|
}
|
|
pReceiver = iterator.next();
|
|
}
|
|
|
|
if (bReachBottom)
|
|
{
|
|
rc.bottom = rcWindow.top;
|
|
rc.top = rc.bottom - cyFixed;
|
|
}
|
|
|
|
if (bReachRight)
|
|
{
|
|
rc.right = rcWindow.left;
|
|
rc.left = rc.right - cxFixed;
|
|
}
|
|
|
|
if( rc.bottom > rcWork.bottom )
|
|
{
|
|
rc.bottom = rc.top;
|
|
rc.top = rc.bottom - cyFixed;
|
|
}
|
|
|
|
if (rc.right > rcWork.right)
|
|
{
|
|
rc.right = rcWindow.left;
|
|
rc.left = rc.right - cxFixed;
|
|
|
|
rc.top = rcWindow.bottom;
|
|
rc.bottom = rc.top + cyFixed;
|
|
}
|
|
|
|
if( rc.top < rcWork.top )
|
|
{
|
|
rc.top = rcOwner.top;
|
|
rc.bottom = rc.top + cyFixed;
|
|
}
|
|
|
|
if (rc.left < rcWork.left)
|
|
{
|
|
rc.left = rcWindow.right;
|
|
rc.right = rc.left + cxFixed;
|
|
}
|
|
|
|
MoveWindow(m_hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE);
|
|
}
|
|
else {
|
|
m_pm.Init(m_hWnd);
|
|
|
|
CDialogBuilder builder;
|
|
CMenuBuilderCallback menuCallback;
|
|
|
|
CControlUI* pRoot = builder.Create(m_xml, m_sType.GetData(), &menuCallback, &m_pm);
|
|
m_pm.AttachDialog(pRoot);
|
|
|
|
#if defined(WIN32) && !defined(UNDER_CE)
|
|
MONITORINFO oMonitor = {};
|
|
oMonitor.cbSize = sizeof(oMonitor);
|
|
::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
|
|
CDuiRect rcWork = oMonitor.rcWork;
|
|
#else
|
|
CDuiRect rcWork;
|
|
GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork);
|
|
#endif
|
|
SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top };
|
|
szAvailable = pRoot->EstimateSize(szAvailable);
|
|
m_pm.SetInitSize(szAvailable.cx, szAvailable.cy);
|
|
|
|
DWORD dwAlignment = eMenuAlignment_Left | eMenuAlignment_Top;
|
|
|
|
SIZE szInit = m_pm.GetInitSize();
|
|
CDuiRect rc;
|
|
CPoint point = m_BasedPoint;
|
|
rc.left = point.x;
|
|
rc.top = point.y;
|
|
rc.right = rc.left + szInit.cx;
|
|
rc.bottom = rc.top + szInit.cy;
|
|
|
|
int nWidth = rc.GetWidth();
|
|
int nHeight = rc.GetHeight();
|
|
|
|
if (dwAlignment & eMenuAlignment_Right)
|
|
{
|
|
rc.right = point.x;
|
|
rc.left = rc.right - nWidth;
|
|
}
|
|
|
|
if (dwAlignment & eMenuAlignment_Bottom)
|
|
{
|
|
rc.bottom = point.y;
|
|
rc.top = rc.bottom - nHeight;
|
|
}
|
|
|
|
SetForegroundWindow(m_hWnd);
|
|
MoveWindow(m_hWnd, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), FALSE);
|
|
SetWindowPos(m_hWnd, HWND_TOPMOST, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), SWP_SHOWWINDOW);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
else if( uMsg == WM_CLOSE ) {
|
|
if( m_pOwner != NULL )
|
|
{
|
|
m_pOwner->SetManager(m_pOwner->GetManager(), m_pOwner->GetParent(), false);
|
|
m_pOwner->SetPos(m_pOwner->GetPos());
|
|
m_pOwner->SetFocus();
|
|
}
|
|
}
|
|
else if( uMsg == WM_RBUTTONDOWN || uMsg == WM_CONTEXTMENU || uMsg == WM_RBUTTONUP || uMsg == WM_RBUTTONDBLCLK )
|
|
{
|
|
return 0L;
|
|
}
|
|
else if( uMsg == WM_KILLFOCUS )
|
|
{
|
|
HWND hFocusWnd = (HWND)wParam;
|
|
|
|
BOOL bInMenuWindowList = FALSE;
|
|
ContextMenuParam param;
|
|
param.hWnd = GetHWND();
|
|
|
|
ContextMenuObserver::Iterator<BOOL, ContextMenuParam> iterator(s_context_menu_observer);
|
|
ReceiverImplBase<BOOL, ContextMenuParam>* pReceiver = iterator.next();
|
|
while( pReceiver != NULL ) {
|
|
CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver);
|
|
if( pContextMenu != NULL && pContextMenu->GetHWND() == hFocusWnd ) {
|
|
bInMenuWindowList = TRUE;
|
|
break;
|
|
}
|
|
pReceiver = iterator.next();
|
|
}
|
|
|
|
if( !bInMenuWindowList ) {
|
|
param.wParam = 1;
|
|
s_context_menu_observer.RBroadcast(param);
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
else if( uMsg == WM_KEYDOWN)
|
|
{
|
|
if( wParam == VK_ESCAPE)
|
|
{
|
|
Close();
|
|
}
|
|
}
|
|
|
|
LRESULT lRes = 0;
|
|
if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
|
|
return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
|
|
}
|
|
const CDuiString& CMenuWnd::GetUserData()
|
|
{
|
|
return m_sUserData;
|
|
}
|
|
|
|
void CMenuWnd::SetUserData(LPCTSTR pstrText)
|
|
{
|
|
m_sUserData = pstrText;
|
|
}
|
|
void CMenuWnd::AdjustPostion(const POINT& point)
|
|
{
|
|
OutputDebugString(_T("AdjustPostion"));
|
|
CDuiRect rcWnd;
|
|
GetWindowRect(m_hWnd, &rcWnd);
|
|
int nWidth = rcWnd.GetWidth();
|
|
int nHeight = rcWnd.GetHeight();
|
|
rcWnd.left = point.x;
|
|
rcWnd.top = point.y;
|
|
rcWnd.right = rcWnd.left + nWidth;
|
|
rcWnd.bottom = rcWnd.top + nHeight;
|
|
MONITORINFO oMonitor = {};
|
|
oMonitor.cbSize = sizeof(oMonitor);
|
|
::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
|
|
CDuiRect rcWork = oMonitor.rcWork;
|
|
|
|
if (rcWnd.bottom > rcWork.bottom) {
|
|
if (nHeight >= rcWork.GetHeight()) {
|
|
rcWnd.top = 0;
|
|
rcWnd.bottom = nHeight;
|
|
}
|
|
else {
|
|
rcWnd.bottom = rcWork.bottom;
|
|
rcWnd.top = rcWnd.bottom - nHeight;
|
|
}
|
|
}
|
|
if (rcWnd.right > rcWork.right) {
|
|
if (nWidth >= rcWork.GetWidth()) {
|
|
rcWnd.left = 0;
|
|
rcWnd.right = nWidth;
|
|
}
|
|
else {
|
|
rcWnd.right = rcWork.right;
|
|
rcWnd.left = rcWnd.right - nWidth;
|
|
}
|
|
}
|
|
::SetWindowPos(m_hWnd, NULL, rcWnd.left, rcWnd.top, rcWnd.GetWidth(), rcWnd.GetHeight(), SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
// MenuElementUI
|
|
const TCHAR* const kMenuElementUIClassName = _T("MenuElementUI");
|
|
const TCHAR* const kMenuElementUIInterfaceName = _T("MenuElement");
|
|
|
|
CMenuElementUI::CMenuElementUI():
|
|
m_pWindow(NULL)
|
|
{
|
|
m_cxyFixed.cy = 25;
|
|
m_bMouseChildEnabled = true;
|
|
|
|
SetMouseChildEnabled(false);
|
|
}
|
|
|
|
CMenuElementUI::~CMenuElementUI()
|
|
{}
|
|
|
|
LPCTSTR CMenuElementUI::GetClass() const
|
|
{
|
|
return kMenuElementUIClassName;
|
|
}
|
|
|
|
LPVOID CMenuElementUI::GetInterface(LPCTSTR pstrName)
|
|
{
|
|
if( _tcsicmp(pstrName, kMenuElementUIInterfaceName) == 0 ) return static_cast<CMenuElementUI*>(this);
|
|
return CListContainerElementUI::GetInterface(pstrName);
|
|
}
|
|
|
|
void CMenuElementUI::DoPaint(HDC hDC, const RECT& rcPaint)
|
|
{
|
|
if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return;
|
|
CMenuElementUI::DrawItemBk(hDC, m_rcItem);
|
|
DrawItemText(hDC, m_rcItem);
|
|
for (int i = 0; i < GetCount(); ++i)
|
|
{
|
|
if (GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) == NULL)
|
|
GetItemAt(i)->DoPaint(hDC, rcPaint);
|
|
}
|
|
}
|
|
|
|
void CMenuElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
|
|
{
|
|
if( m_sText.IsEmpty() ) return;
|
|
|
|
if( m_pOwner == NULL ) return;
|
|
TListInfoUI* pInfo = m_pOwner->GetListInfo();
|
|
DWORD iTextColor = pInfo->dwTextColor;
|
|
if( (m_uButtonState & UISTATE_HOT) != 0 ) {
|
|
iTextColor = pInfo->dwHotTextColor;
|
|
}
|
|
if( IsSelected() ) {
|
|
iTextColor = pInfo->dwSelectedTextColor;
|
|
}
|
|
if( !IsEnabled() ) {
|
|
iTextColor = pInfo->dwDisabledTextColor;
|
|
}
|
|
int nLinks = 0;
|
|
RECT rcText = rcItem;
|
|
rcText.left += pInfo->rcTextPadding.left;
|
|
rcText.right -= pInfo->rcTextPadding.right;
|
|
rcText.top += pInfo->rcTextPadding.top;
|
|
rcText.bottom -= pInfo->rcTextPadding.bottom;
|
|
|
|
if( pInfo->bShowHtml )
|
|
CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, iTextColor, \
|
|
NULL, NULL, nLinks, DT_SINGLELINE | pInfo->uTextStyle);
|
|
else
|
|
CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, iTextColor, \
|
|
pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
|
|
}
|
|
|
|
|
|
SIZE CMenuElementUI::EstimateSize(SIZE szAvailable)
|
|
{
|
|
SIZE cXY = {0};
|
|
for( int it = 0; it < GetCount(); it++ ) {
|
|
CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it));
|
|
if( !pControl->IsVisible() ) continue;
|
|
SIZE sz = pControl->EstimateSize(szAvailable);
|
|
cXY.cy += sz.cy;
|
|
if( cXY.cx < sz.cx )
|
|
cXY.cx = sz.cx;
|
|
}
|
|
if(cXY.cy == 0) {
|
|
TListInfoUI* pInfo = m_pOwner->GetListInfo();
|
|
|
|
DWORD iTextColor = pInfo->dwTextColor;
|
|
if( (m_uButtonState & UISTATE_HOT) != 0 ) {
|
|
iTextColor = pInfo->dwHotTextColor;
|
|
}
|
|
if( IsSelected() ) {
|
|
iTextColor = pInfo->dwSelectedTextColor;
|
|
}
|
|
if( !IsEnabled() ) {
|
|
iTextColor = pInfo->dwDisabledTextColor;
|
|
}
|
|
|
|
RECT rcText = { 0, 0, max(szAvailable.cx, m_cxyFixed.cx), 9999 };
|
|
rcText.left += pInfo->rcTextPadding.left;
|
|
rcText.right -= pInfo->rcTextPadding.right;
|
|
if( pInfo->bShowHtml ) {
|
|
int nLinks = 0;
|
|
CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, iTextColor, NULL, NULL, nLinks, DT_CALCRECT | pInfo->uTextStyle);
|
|
}
|
|
else {
|
|
CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, iTextColor, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle);
|
|
}
|
|
cXY.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right + 20;
|
|
cXY.cy = rcText.bottom - rcText.top + pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom;
|
|
}
|
|
|
|
if( m_cxyFixed.cy != 0 ) cXY.cy = m_cxyFixed.cy;
|
|
return cXY;
|
|
}
|
|
|
|
void CMenuElementUI::DoEvent(TEventUI& event)
|
|
{
|
|
if( event.Type == UIEVENT_MOUSEENTER )
|
|
{
|
|
CListContainerElementUI::DoEvent(event);
|
|
if( m_pWindow ) return;
|
|
bool hasSubMenu = false;
|
|
for( int i = 0; i < GetCount(); ++i )
|
|
{
|
|
if( GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL )
|
|
{
|
|
(static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetVisible(true);
|
|
(static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetInternVisible(true);
|
|
|
|
hasSubMenu = true;
|
|
}
|
|
}
|
|
if( hasSubMenu )
|
|
{
|
|
m_pOwner->SelectItem(GetIndex(), true);
|
|
CreateMenuWnd();
|
|
}
|
|
else
|
|
{
|
|
ContextMenuParam param;
|
|
param.hWnd = m_pManager->GetPaintWindow();
|
|
param.wParam = 2;
|
|
param.name = GetName();
|
|
s_context_menu_observer.RBroadcast(param);
|
|
m_pOwner->SelectItem(GetIndex(), true);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if( event.Type == UIEVENT_BUTTONDOWN )
|
|
{
|
|
if( IsEnabled() ){
|
|
CListContainerElementUI::DoEvent(event);
|
|
|
|
if( m_pWindow ) return;
|
|
|
|
bool hasSubMenu = false;
|
|
for( int i = 0; i < GetCount(); ++i ) {
|
|
if( GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL ) {
|
|
(static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetVisible(true);
|
|
(static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetInternVisible(true);
|
|
|
|
hasSubMenu = true;
|
|
}
|
|
}
|
|
if( hasSubMenu )
|
|
{
|
|
CreateMenuWnd();
|
|
}
|
|
else//û���Ӳ˵��������£���Ϊѡ���˱���
|
|
{
|
|
LPCTSTR p = GetClass();
|
|
ContextMenuParam param;
|
|
param.hWnd = m_pManager->GetPaintWindow();
|
|
param.wParam = 1;
|
|
param.name = GetName();
|
|
s_context_menu_observer.RBroadcast(param);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
CListContainerElementUI::DoEvent(event);
|
|
}
|
|
|
|
bool CMenuElementUI::Activate()
|
|
{
|
|
if (CListContainerElementUI::Activate() && m_bSelected)
|
|
{
|
|
if( m_pWindow ) return true;
|
|
bool hasSubMenu = false;
|
|
for (int i = 0; i < GetCount(); ++i)
|
|
{
|
|
if (GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL)
|
|
{
|
|
(static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetVisible(true);
|
|
(static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName)))->SetInternVisible(true);
|
|
|
|
hasSubMenu = true;
|
|
}
|
|
}
|
|
if (hasSubMenu)
|
|
{
|
|
CreateMenuWnd();
|
|
}
|
|
else
|
|
{
|
|
ContextMenuParam param;
|
|
param.hWnd = m_pManager->GetPaintWindow();
|
|
param.wParam = 1;
|
|
s_context_menu_observer.RBroadcast(param);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
CMenuWnd* CMenuElementUI::GetMenuWnd()
|
|
{
|
|
return m_pWindow;
|
|
}
|
|
|
|
void CMenuElementUI::CreateMenuWnd()
|
|
{
|
|
if( m_pWindow ) return;
|
|
|
|
m_pWindow = new CMenuWnd(m_pManager->GetPaintWindow());
|
|
ASSERT(m_pWindow);
|
|
|
|
ContextMenuParam param;
|
|
param.hWnd = m_pManager->GetPaintWindow();
|
|
param.wParam = 2;
|
|
s_context_menu_observer.RBroadcast(param);
|
|
|
|
m_pWindow->Init(static_cast<CMenuElementUI*>(this), _T(""), _T(""), CPoint());
|
|
}
|
|
|
|
|
|
} // namespace DuiLib
|