1 // TortoiseMerge - a Diff/Patch program
3 // Copyright (C) 2006-2008 - 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 "TortoiseMerge.h"
22 #include "LocatorBar.h"
24 #include "RightView.h"
25 #include "BottomView.h"
26 #include "DiffColors.h"
29 IMPLEMENT_DYNAMIC(CLocatorBar
, CPaneDialog
)
30 CLocatorBar::CLocatorBar() : CPaneDialog()
32 , m_pCacheBitmap(NULL
)
33 , m_bMouseWithin(FALSE
)
38 CLocatorBar::~CLocatorBar()
42 m_pCacheBitmap
->DeleteObject();
43 delete m_pCacheBitmap
;
44 m_pCacheBitmap
= NULL
;
48 BEGIN_MESSAGE_MAP(CLocatorBar
, CPaneDialog
)
54 ON_MESSAGE(WM_MOUSELEAVE
, OnMouseLeave
)
57 void CLocatorBar::DocumentUpdated()
59 m_pMainFrm
= (CMainFrame
*)this->GetParentFrame();
60 m_arLeftIdent
.RemoveAll();
61 m_arLeftState
.RemoveAll();
62 m_arRightIdent
.RemoveAll();
63 m_arRightState
.RemoveAll();
64 m_arBottomIdent
.RemoveAll();
65 m_arBottomState
.RemoveAll();
66 DiffStates state
= DIFFSTATE_UNKNOWN
;
69 if (m_pMainFrm
->m_pwndLeftView
->m_pViewData
)
71 if (m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetCount())
72 state
= m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetState(0);
73 for (int i
=0; i
<m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetCount(); i
++)
75 if (state
== m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetState(i
))
81 m_arLeftIdent
.Add(identcount
);
82 m_arLeftState
.Add(state
);
83 state
= m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetState(i
);
87 m_arLeftIdent
.Add(identcount
);
88 m_arLeftState
.Add(state
);
91 if (m_pMainFrm
->m_pwndRightView
->m_pViewData
)
93 if (m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount())
94 state
= m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetState(0);
96 for (int i
=0; i
<m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount(); i
++)
98 if (state
== m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetState(i
))
104 m_arRightIdent
.Add(identcount
);
105 m_arRightState
.Add(state
);
106 state
= m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetState(i
);
110 m_arRightIdent
.Add(identcount
);
111 m_arRightState
.Add(state
);
114 if (m_pMainFrm
->m_pwndBottomView
->m_pViewData
)
116 if (m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetCount())
117 state
= m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetState(0);
119 for (int i
=0; i
<m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetCount(); i
++)
121 if (state
== m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetState(i
))
127 m_arBottomIdent
.Add(identcount
);
128 m_arBottomState
.Add(state
);
129 state
= m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetState(i
);
133 m_arBottomIdent
.Add(identcount
);
134 m_arBottomState
.Add(state
);
135 m_nLines
= (int)max(m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetCount(), m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount());
137 else if (m_pMainFrm
->m_pwndRightView
->m_pViewData
)
138 m_nLines
= (int)max(0, m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount());
140 if (m_pMainFrm
->m_pwndLeftView
->m_pViewData
)
141 m_nLines
= (int)max(m_nLines
, m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetCount());
148 void CLocatorBar::OnPaint()
150 CPaintDC
dc(this); // device context for painting
153 long height
= rect
.Height();
154 long width
= rect
.Width();
156 long nBottomLine
= 0;
157 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
159 nTopLine
= m_pMainFrm
->m_pwndLeftView
->m_nTopLine
;
160 nBottomLine
= nTopLine
+ m_pMainFrm
->m_pwndLeftView
->GetScreenLines();
163 VERIFY(cacheDC
.CreateCompatibleDC(&dc
));
165 if (m_pCacheBitmap
== NULL
)
167 m_pCacheBitmap
= new CBitmap
;
168 VERIFY(m_pCacheBitmap
->CreateCompatibleBitmap(&dc
, width
, height
));
170 CBitmap
*pOldBitmap
= cacheDC
.SelectObject(m_pCacheBitmap
);
173 COLORREF color
, color2
;
175 CDiffColors::GetInstance().GetColors(DIFFSTATE_UNKNOWN
, color
, color2
);
176 cacheDC
.FillSolidRect(rect
, color
);
178 long barwidth
= (width
/3);
184 cacheDC
.FillSolidRect(rect
.left
, height
*nTopLine
/m_nLines
,
185 rect
.Width(), (height
*nBottomLine
/m_nLines
)-(height
*nTopLine
/m_nLines
), RGB(180,180,255));
186 if (m_pMainFrm
->m_pwndLeftView
->IsWindowVisible())
188 for (long i
=0; i
<m_arLeftIdent
.GetCount(); i
++)
190 identcount
= m_arLeftIdent
.GetAt(i
);
191 state
= m_arLeftState
.GetAt(i
);
192 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
193 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
194 cacheDC
.FillSolidRect(rect
.left
, height
*linecount
/m_nLines
,
195 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
196 linecount
+= identcount
;
203 if (m_pMainFrm
->m_pwndRightView
->IsWindowVisible())
205 for (long i
=0; i
<m_arRightIdent
.GetCount(); i
++)
207 identcount
= m_arRightIdent
.GetAt(i
);
208 state
= m_arRightState
.GetAt(i
);
209 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
210 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
211 cacheDC
.FillSolidRect(rect
.left
+ (width
*2/3), height
*linecount
/m_nLines
,
212 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
213 linecount
+= identcount
;
219 if (m_pMainFrm
->m_pwndBottomView
->IsWindowVisible())
221 for (long i
=0; i
<m_arBottomIdent
.GetCount(); i
++)
223 identcount
= m_arBottomIdent
.GetAt(i
);
224 state
= m_arBottomState
.GetAt(i
);
225 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
226 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
227 cacheDC
.FillSolidRect(rect
.left
+ (width
/3), height
*linecount
/m_nLines
,
228 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
229 linecount
+= identcount
;
235 cacheDC
.FillSolidRect(rect
.left
, height
*nTopLine
/m_nLines
,
236 rect
.Width(), 2, RGB(0,0,0));
237 cacheDC
.FillSolidRect(rect
.left
, height
*nBottomLine
/m_nLines
,
238 rect
.Width(), 2, RGB(0,0,0));
239 //draw two vertical lines, so there are three rows visible indicating the three panes
240 cacheDC
.FillSolidRect(rect
.left
+ (width
/3), rect
.top
, 1, height
, RGB(0,0,0));
241 cacheDC
.FillSolidRect(rect
.left
+ (width
*2/3), rect
.top
, 1, height
, RGB(0,0,0));
246 int fishstart
= m_MousePos
.y
- height
/20;
247 int fishheight
= height
/10;
248 cacheDC
.FillSolidRect(rect
.left
, fishstart
-1, width
, 1, RGB(0,0,100));
249 cacheDC
.FillSolidRect(rect
.left
, fishstart
+fishheight
+1, width
, 1, RGB(0,0,100));
250 VERIFY(cacheDC
.StretchBlt(rect
.left
, fishstart
, width
, fishheight
,
251 &cacheDC
, 0, fishstart
+ (3*fishheight
/8), width
, fishheight
/4, SRCCOPY
));
252 // draw the magnified area a little darker, so the
253 // user has a clear indication of the magnifier
254 for (int i
=rect
.left
; i
<(width
- rect
.left
); i
++)
256 for (int j
=fishstart
; j
<fishstart
+fishheight
; j
++)
258 color
= cacheDC
.GetPixel(i
, j
);
260 r
= max(GetRValue(color
)-20, 0);
261 g
= max(GetGValue(color
)-20, 0);
262 b
= max(GetBValue(color
)-20, 0);
263 cacheDC
.SetPixel(i
, j
, RGB(r
,g
,b
));
267 VERIFY(dc
.BitBlt(rect
.left
, rect
.top
, width
, height
, &cacheDC
, 0, 0, SRCCOPY
));
269 cacheDC
.SelectObject(pOldBitmap
);
273 void CLocatorBar::OnSize(UINT nType
, int cx
, int cy
)
275 CPaneDialog::OnSize(nType
, cx
, cy
);
277 if (m_pCacheBitmap
!= NULL
)
279 m_pCacheBitmap
->DeleteObject();
280 delete m_pCacheBitmap
;
281 m_pCacheBitmap
= NULL
;
286 BOOL
CLocatorBar::OnEraseBkgnd(CDC
* /*pDC*/)
291 void CLocatorBar::OnLButtonDown(UINT nFlags
, CPoint point
)
295 int nLine
= point
.y
*m_nLines
/rect
.Height();
299 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndBottomView
))
300 m_pMainFrm
->m_pwndBottomView
->GoToLine(nLine
, FALSE
);
301 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
302 m_pMainFrm
->m_pwndLeftView
->GoToLine(nLine
, FALSE
);
303 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndRightView
))
304 m_pMainFrm
->m_pwndRightView
->GoToLine(nLine
, FALSE
);
306 CPaneDialog::OnLButtonDown(nFlags
, point
);
309 void CLocatorBar::OnMouseMove(UINT nFlags
, CPoint point
)
314 m_bMouseWithin
= TRUE
;
316 tme
.cbSize
= sizeof(TRACKMOUSEEVENT
);
317 tme
.dwFlags
= TME_LEAVE
;
318 tme
.hwndTrack
= m_hWnd
;
319 _TrackMouseEvent(&tme
);
322 if (nFlags
& MK_LBUTTON
)
326 int nLine
= point
.y
*m_nLines
/rect
.Height();
330 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndBottomView
))
331 m_pMainFrm
->m_pwndBottomView
->GoToLine(nLine
, FALSE
);
332 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
333 m_pMainFrm
->m_pwndLeftView
->GoToLine(nLine
, FALSE
);
334 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndRightView
))
335 m_pMainFrm
->m_pwndRightView
->GoToLine(nLine
, FALSE
);
340 LRESULT
CLocatorBar::OnMouseLeave(WPARAM
, LPARAM
)
342 m_bMouseWithin
= FALSE
;