1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2007 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "FilterEdit.h"
22 IMPLEMENT_DYNAMIC(CFilterEdit
, CEdit
)
24 CFilterEdit::CFilterEdit() : m_hIconCancelNormal(NULL
)
25 , m_hIconCancelPressed(NULL
)
28 , m_bShowCancelButtonAlways(FALSE
)
29 , m_iButtonClickedMessageId(WM_FILTEREDIT_INFOCLICKED
)
30 , m_iCancelClickedMessageId(WM_FILTEREDIT_CANCELCLICKED
)
32 , m_backColor(GetSysColor(COLOR_WINDOW
))
36 m_rcEditArea
.SetRect(0, 0, 0, 0);
37 m_rcButtonArea
.SetRect(0, 0, 0, 0);
38 m_rcInfoArea
.SetRect(0, 0, 0, 0);
39 m_sizeInfoIcon
.SetSize(0, 0);
40 m_sizeCancelIcon
.SetSize(0, 0);
43 CFilterEdit::~CFilterEdit()
45 if (m_hIconCancelNormal
)
46 DestroyIcon(m_hIconCancelNormal
);
47 if (m_hIconCancelPressed
)
48 DestroyIcon(m_hIconCancelPressed
);
50 DestroyIcon(m_hIconInfo
);
52 DeleteObject(m_brBack
);
54 delete [] m_pCueBanner
;
57 BEGIN_MESSAGE_MAP(CFilterEdit
, CEdit
)
59 ON_MESSAGE(WM_SETFONT
, OnSetFont
)
67 ON_CONTROL_REFLECT_EX(EN_CHANGE
, &CFilterEdit::OnEnChange
)
68 ON_WM_CTLCOLOR_REFLECT()
70 ON_CONTROL_REFLECT(EN_KILLFOCUS
, &CFilterEdit::OnEnKillfocus
)
71 ON_CONTROL_REFLECT(EN_SETFOCUS
, &CFilterEdit::OnEnSetfocus
)
76 // CFilterEdit message handlers
78 void CFilterEdit::PreSubclassWindow( )
80 // We must have a multi line edit
81 // to be able to set the edit rect
82 ASSERT( GetStyle() & ES_MULTILINE
);
87 BOOL
CFilterEdit::PreTranslateMessage( MSG
* pMsg
)
89 return CEdit::PreTranslateMessage(pMsg
);
92 BOOL
CFilterEdit::SetCancelBitmaps(UINT uCancelNormal
, UINT uCancelPressed
, BOOL bShowAlways
)
94 m_bShowCancelButtonAlways
= bShowAlways
;
96 if (m_hIconCancelNormal
)
97 DestroyIcon(m_hIconCancelNormal
);
98 if (m_hIconCancelPressed
)
99 DestroyIcon(m_hIconCancelPressed
);
101 m_hIconCancelNormal
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(uCancelNormal
), IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
102 m_hIconCancelPressed
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(uCancelPressed
), IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
104 if ((m_hIconCancelNormal
== 0) || (m_hIconCancelPressed
== 0))
107 m_sizeCancelIcon
= GetIconSize(m_hIconCancelNormal
);
113 BOOL
CFilterEdit::SetInfoIcon(UINT uInfo
)
116 DestroyIcon(m_hIconInfo
);
118 m_hIconInfo
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(uInfo
), IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
120 if (m_hIconInfo
== 0)
123 m_sizeInfoIcon
= GetIconSize(m_hIconInfo
);
129 BOOL
CFilterEdit::SetCueBanner(LPCWSTR lpcwText
)
134 delete [] m_pCueBanner
;
135 size_t len
= _tcslen(lpcwText
);
136 m_pCueBanner
= new TCHAR
[len
+1];
137 _tcscpy_s(m_pCueBanner
, len
+1, lpcwText
);
138 InvalidateRect(NULL
, TRUE
);
144 void CFilterEdit::ResizeWindow()
146 if (!::IsWindow(m_hWnd
))
152 editrc
.left
= rc
.left
+ 4;
153 editrc
.top
= rc
.top
+ 1;
154 editrc
.right
= rc
.right
- 4;
155 editrc
.bottom
= rc
.bottom
- 4;
157 m_rcEditArea
.left
= editrc
.left
+ m_sizeInfoIcon
.cx
;
158 m_rcEditArea
.right
= editrc
.right
- m_sizeCancelIcon
.cx
- 5;
159 m_rcEditArea
.top
= editrc
.top
;
160 m_rcEditArea
.bottom
= editrc
.bottom
;
162 m_rcButtonArea
.left
= m_rcEditArea
.right
+ 5;
163 m_rcButtonArea
.right
= rc
.right
;
164 m_rcButtonArea
.top
= (((rc
.bottom
)-m_sizeCancelIcon
.cy
)/2);
165 m_rcButtonArea
.bottom
= m_rcButtonArea
.top
+ m_sizeCancelIcon
.cy
;
167 m_rcInfoArea
.left
= 0;
168 m_rcInfoArea
.right
= m_rcEditArea
.left
;
169 m_rcInfoArea
.top
= (((rc
.bottom
)-m_sizeInfoIcon
.cy
)/2);
170 m_rcInfoArea
.bottom
= m_rcInfoArea
.top
+ m_sizeInfoIcon
.cy
;
172 SetRect(&m_rcEditArea
);
175 void CFilterEdit::SetButtonClickedMessageId(UINT iButtonClickedMessageId
, UINT iCancelClickedMessageId
)
177 m_iButtonClickedMessageId
= iButtonClickedMessageId
;
178 m_iCancelClickedMessageId
= iCancelClickedMessageId
;
181 CSize
CFilterEdit::GetIconSize(HICON hIcon
)
185 if (GetIconInfo(hIcon
, &iconinfo
))
188 if (GetObject(iconinfo
.hbmColor
, sizeof(BITMAP
), &bmp
))
190 size
.cx
= bmp
.bmWidth
;
191 size
.cy
= bmp
.bmHeight
;
197 BOOL
CFilterEdit::OnEraseBkgnd(CDC
* pDC
)
201 pDC
->FillSolidRect(&rc
, m_backColor
);
203 if (GetWindowTextLength() || m_bShowCancelButtonAlways
)
207 DrawIconEx(pDC
->GetSafeHdc(), m_rcButtonArea
.left
, m_rcButtonArea
.top
, m_hIconCancelNormal
,
208 m_sizeCancelIcon
.cx
, m_sizeCancelIcon
.cy
, 0, NULL
, DI_NORMAL
);
212 DrawIconEx(pDC
->GetSafeHdc(), m_rcButtonArea
.left
, m_rcButtonArea
.top
, m_hIconCancelPressed
,
213 m_sizeCancelIcon
.cx
, m_sizeCancelIcon
.cy
, 0, NULL
, DI_NORMAL
);
218 DrawIconEx(pDC
->GetSafeHdc(), m_rcInfoArea
.left
, m_rcInfoArea
.top
, m_hIconInfo
,
219 m_sizeInfoIcon
.cx
, m_sizeInfoIcon
.cy
, 0, NULL
, DI_NORMAL
);
225 void CFilterEdit::OnLButtonUp(UINT nFlags
, CPoint point
)
228 InvalidateRect(NULL
);
229 if (m_rcButtonArea
.PtInRect(point
))
231 SetWindowText(_T(""));
232 CWnd
*pOwner
= GetOwner();
235 pOwner
->SendMessage(m_iCancelClickedMessageId
, 0, 0);
239 if (m_rcInfoArea
.PtInRect(point
))
241 CWnd
*pOwner
= GetOwner();
244 RECT rc
= m_rcInfoArea
;
246 pOwner
->SendMessage(m_iButtonClickedMessageId
, 0, (LPARAM
)(LPRECT
)&rc
);
250 CEdit::OnLButtonUp(nFlags
, point
);
253 void CFilterEdit::OnLButtonDown(UINT nFlags
, CPoint point
)
255 m_bPressed
= m_rcButtonArea
.PtInRect(point
);
256 //InvalidateRect(NULL);
257 CEdit::OnLButtonDown(nFlags
, point
);
260 int CFilterEdit::OnCreate(LPCREATESTRUCT lpCreateStruct
)
262 if (CEdit::OnCreate(lpCreateStruct
) == -1)
270 LRESULT
CFilterEdit::OnSetFont( WPARAM wParam
, LPARAM lParam
)
272 DefWindowProc( WM_SETFONT
, wParam
, lParam
);
279 void CFilterEdit::OnSize( UINT nType
, int cx
, int cy
)
281 CEdit::OnSize( nType
, cx
, cy
);
285 BOOL
CFilterEdit::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
288 GetCursorPos(&pntCursor
);
289 ScreenToClient(&pntCursor
);
290 // if the cursor is not in the edit area, show the normal arrow cursor
291 if (!m_rcEditArea
.PtInRect(pntCursor
))
293 SetCursor(AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(IDC_ARROW
)));
297 return CEdit::OnSetCursor(pWnd
, nHitTest
, message
);
300 BOOL
CFilterEdit::OnEnChange()
302 // check whether the entered text is valid
304 InvalidateRect(NULL
);
308 HBRUSH
CFilterEdit::CtlColor(CDC
* pDC
, UINT
/*nCtlColor*/)
310 if (m_backColor
!= GetSysColor(COLOR_WINDOW
))
312 pDC
->SetBkColor(m_backColor
);
318 void CFilterEdit::Validate()
322 int len
= GetWindowTextLength();
323 TCHAR
* pBuf
= new TCHAR
[len
+1];
324 GetWindowText(pBuf
, len
+1);
325 m_backColor
= GetSysColor(COLOR_WINDOW
);
326 if (!m_pValidator
->Validate(pBuf
))
328 // Use a background color slightly shifted to red.
329 // We do this by increasing red component and decreasing green and blue.
330 const int SHIFT_PRECENTAGE
= 10;
331 int r
= GetRValue(m_backColor
);
332 int g
= GetGValue(m_backColor
);
333 int b
= GetBValue(m_backColor
);
335 r
= min(r
* (100 + SHIFT_PRECENTAGE
) / 100, 255);
336 // Ensure that there is at least some redness.
337 r
= max(r
, 255 * SHIFT_PRECENTAGE
/ 100);
338 g
= g
* (100 - SHIFT_PRECENTAGE
) / 100;
339 b
= b
* (100 - SHIFT_PRECENTAGE
) / 100;
340 m_backColor
= RGB(r
, g
, b
);
342 DeleteObject(m_brBack
);
343 m_brBack
= CreateSolidBrush(m_backColor
);
349 void CFilterEdit::OnPaint()
358 void CFilterEdit::DrawDimText()
360 if (m_pCueBanner
== NULL
)
362 if (GetWindowTextLength())
364 if (_tcslen(m_pCueBanner
) == 0)
366 if (GetFocus() == this)
369 CClientDC
dcDraw(this);
371 int iState
= dcDraw
.SaveDC();
373 GetClientRect(&rRect
);
374 rRect
.OffsetRect(1, 1);
376 dcDraw
.SelectObject((*GetFont()));
377 dcDraw
.SetTextColor(GetSysColor(COLOR_GRAYTEXT
));
378 dcDraw
.SetBkColor(GetSysColor(COLOR_WINDOW
));
379 dcDraw
.DrawText(m_pCueBanner
, (int)_tcslen(m_pCueBanner
), &rRect
, DT_CENTER
| DT_VCENTER
);
380 dcDraw
.RestoreDC(iState
);
384 void CFilterEdit::OnEnKillfocus()
386 InvalidateRect(NULL
);
389 void CFilterEdit::OnEnSetfocus()
391 InvalidateRect(NULL
);