/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // CtrlEditFlags.cpp : implementation file // #include "stdafx.h" #include "WorldEditor.h" #include "CtrlEditFlags.h" #ifdef _DEBUG #undef new #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CCtrlEditFlags CCtrlEditFlags::CCtrlEditFlags() { m_iCurrentBank=0; m_ulValue=0; m_ulDefined=-1; m_ulEditable=0; m_iLastArea=0; m_iMouseDownArea=0; for(INDEX iBit=0; iBit<32; iBit++) { CTString strDescription; strDescription.PrintF("Bit %d", iBit); SetBitDescription(iBit, strDescription); } } CCtrlEditFlags::~CCtrlEditFlags() { } void CCtrlEditFlags::SetBitDescription(INDEX iBit, CTString strBitName) { m_astrBitDescription[iBit]=strBitName; } void CCtrlEditFlags::SetDialogPtr( CWnd *pDialog) { m_pDialog = pDialog; } void CCtrlEditFlags::SetEditableMask(ULONG ulEditable) { m_ulEditable=ulEditable; SetFirstEditableBank(); if( ::IsWindow(m_hWnd)) Invalidate( FALSE); } void CCtrlEditFlags::SetDefaultValue(ULONG ulDefault) { m_ulDefault=ulDefault; } void CCtrlEditFlags::SetFlags(ULONG ulFlags) { m_ulValue=ulFlags; m_ulDefined=-1; if( ::IsWindow(m_hWnd)) Invalidate( FALSE); } void CCtrlEditFlags::MergeFlags(ULONG ulFlags) { m_ulDefined&=~(ulFlags^m_ulValue); if( ::IsWindow(m_hWnd)) Invalidate( FALSE); } void CCtrlEditFlags::ApplyChange(ULONG &ulOldFlags) { ULONG ulKeepMask=~m_ulEditable|~m_ulDefined; ulOldFlags=(ulOldFlags&ulKeepMask)|(m_ulValue&~ulKeepMask); } void CCtrlEditFlags::SetPrevEditableBank( void) { if(m_iCurrentBank==0 && m_ulEditable&0xff000000) m_iCurrentBank=3; if(m_iCurrentBank==1 && m_ulEditable&0x000000ff) m_iCurrentBank=0; if(m_iCurrentBank==2 && m_ulEditable&0x0000ff00) m_iCurrentBank=1; if(m_iCurrentBank==3 && m_ulEditable&0x00ff0000) m_iCurrentBank=2; } void CCtrlEditFlags::SetNextEditableBank( void) { INDEX iOldCurrentBank=m_iCurrentBank; if(m_iCurrentBank==0 && m_ulEditable&0x0000ff00) m_iCurrentBank=1; if(m_iCurrentBank==1 && m_ulEditable&0x00ff0000) m_iCurrentBank=2; if(m_iCurrentBank==2 && m_ulEditable&0xff000000) m_iCurrentBank=3; if(m_iCurrentBank==3 && m_ulEditable&0x000000ff) m_iCurrentBank=0; if(iOldCurrentBank==m_iCurrentBank) { SetFirstEditableBank(); } Invalidate(FALSE); } void CCtrlEditFlags::SetFirstEditableBank( void) { m_iCurrentBank=0; if(m_ulEditable&0x000000ff) m_iCurrentBank=0; else if(m_ulEditable&0x0000ff00) m_iCurrentBank=1; else if(m_ulEditable&0x00ff0000) m_iCurrentBank=2; else if(m_ulEditable&0xff000000) m_iCurrentBank=3; } BEGIN_MESSAGE_MAP(CCtrlEditFlags, CButton) //{{AFX_MSG_MAP(CCtrlEditFlags) ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_WM_KILLFOCUS() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCtrlEditFlags message handlers RECT CCtrlEditFlags::GetRectForArea(INDEX iArea) const { RECT rect; rect.left = m_rectButton.left+m_dx*iArea; rect.right = m_rectButton.left+m_dx*(iArea+1); rect.top = m_rectButton.top; rect.bottom = m_rectButton.bottom; return rect; } void CCtrlEditFlags::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { EnableToolTips( TRUE); CDC *pDC = GetDC(); m_rectButton = lpDrawItemStruct->rcItem; COLORREF clrrefBcg=GetSysColor(COLOR_MENU); pDC->FillSolidRect(&m_rectButton, clrrefBcg); m_rectButton.top+=2; m_rectButton.bottom-=2; m_dx = (m_rectButton.right-m_rectButton.left)/9; INDEX ix=0; for( INDEX iBit=(m_iCurrentBank+1)*8-1; iBit>=m_iCurrentBank*8; iBit--) { RECT rectToFill=GetRectForArea(ix); ULONG ulBit=(1<FillSolidRect( &rectToFill, clrfColor); pDC->DrawEdge( &rectToFill, EDGE_SUNKEN, BF_RECT); } else { pDC->DrawEdge( &rectToFill, EDGE_ETCHED, BF_RECT); } ix++; } if( IsWindowEnabled()) { RECT rectText=GetRectForArea(8); CTString strCTBankNo; strCTBankNo.PrintF("%d",m_iCurrentBank); CString strBankNo=strCTBankNo; pDC->SetBkMode( TRANSPARENT); pDC->SetTextAlign(TA_CENTER); pDC->ExtTextOut( (rectText.left+rectText.right)/2, rectText.top, ETO_CLIPPED, &rectText, strBankNo, 1, NULL); } } INDEX CCtrlEditFlags::GetAreaUnderMouse( CPoint point) const { INDEX iResult=-1; for( INDEX iArea=0; iArea<=8; iArea++) { RECT rectToTest=GetRectForArea(iArea); if( PtInRect( &rectToTest, point)) { iResult=iArea; break;; } } return iResult; } CTString CCtrlEditFlags::GetTipForArea(INDEX iArea) const { CTString strResult; if( iArea==8) { strResult.PrintF("Bits (%d-%d)", m_iCurrentBank*8, (m_iCurrentBank+1)*8-1); return strResult; } else if( iArea!=-1) { ULONG ulBit=1<<((7-iArea)+m_iCurrentBank*8); if( m_ulEditable&ulBit) { INDEX iBit=(7-iArea)+m_iCurrentBank*8; return m_astrBitDescription[iBit]; } else { strResult.PrintF("Not editable"); } return strResult; } return "Not available"; } int CCtrlEditFlags::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const { INDEX iArea=GetAreaUnderMouse( point); if( iArea==-1) return 0; CTString strToolTip=GetTipForArea(iArea); pTI->lpszText = (wchar_t *)malloc( sizeof(wchar_t) * (strlen(strToolTip)+1)); wcscpy( pTI->lpszText, CString(strToolTip)); RECT rectToolTip; rectToolTip.left = 50; rectToolTip.right = 60; rectToolTip.top = 50; rectToolTip.bottom = 60; pTI->hwnd = GetParent()->m_hWnd; pTI->uId = (UINT) m_hWnd; pTI->rect = rectToolTip; pTI->uFlags = TTF_IDISHWND; return 1; } void CCtrlEditFlags::OnLButtonDown(UINT nFlags, CPoint point) { INDEX iArea=GetAreaUnderMouse( point); m_iMouseDownArea=iArea; CButton::OnLButtonDown(nFlags, point); } void CCtrlEditFlags::OnLButtonUp(UINT nFlags, CPoint point) { INDEX iArea=GetAreaUnderMouse( point); if(m_iMouseDownArea!=iArea) return; if( iArea==8) { SetNextEditableBank(); } else if( iArea>=0 && iArea<=7) { ULONG ulBit=1<<((7-iArea)+m_iCurrentBank*8); // if bit was defined if( m_ulDefined&ulBit) { // change bit state m_ulValue^=ulBit; } // set bit else { m_ulValue|=ulBit; } // note change if( m_pDialog!=NULL) { m_pDialog->UpdateData(TRUE); } m_ulDefined|=ulBit; } Invalidate(FALSE); CButton::OnLButtonUp(nFlags, point); } void CCtrlEditFlags::OnMouseMove(UINT nFlags, CPoint point) { m_iLastArea=GetAreaUnderMouse( point); CButton::OnMouseMove(nFlags, point); } void CCtrlEditFlags::OnKillFocus(CWnd* pNewWnd) { CButton::OnKillFocus(pNewWnd); }