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()
33 m_pCacheBitmap
= NULL
;
34 m_bMouseWithin
= FALSE
;
37 CLocatorBar::~CLocatorBar()
41 m_pCacheBitmap
->DeleteObject();
42 delete m_pCacheBitmap
;
43 m_pCacheBitmap
= NULL
;
47 BEGIN_MESSAGE_MAP(CLocatorBar
, CPaneDialog
)
53 ON_MESSAGE(WM_MOUSELEAVE
, OnMouseLeave
)
56 void CLocatorBar::DocumentUpdated()
58 m_pMainFrm
= (CMainFrame
*)this->GetParentFrame();
59 m_arLeftIdent
.RemoveAll();
60 m_arLeftState
.RemoveAll();
61 m_arRightIdent
.RemoveAll();
62 m_arRightState
.RemoveAll();
63 m_arBottomIdent
.RemoveAll();
64 m_arBottomState
.RemoveAll();
65 DiffStates state
= DIFFSTATE_UNKNOWN
;
68 if (m_pMainFrm
->m_pwndLeftView
->m_pViewData
)
70 if (m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetCount())
71 state
= m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetState(0);
72 for (int i
=0; i
<m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetCount(); i
++)
74 if (state
== m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetState(i
))
80 m_arLeftIdent
.Add(identcount
);
81 m_arLeftState
.Add(state
);
82 state
= m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetState(i
);
86 m_arLeftIdent
.Add(identcount
);
87 m_arLeftState
.Add(state
);
90 if (m_pMainFrm
->m_pwndRightView
->m_pViewData
)
92 if (m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount())
93 state
= m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetState(0);
95 for (int i
=0; i
<m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount(); i
++)
97 if (state
== m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetState(i
))
103 m_arRightIdent
.Add(identcount
);
104 m_arRightState
.Add(state
);
105 state
= m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetState(i
);
109 m_arRightIdent
.Add(identcount
);
110 m_arRightState
.Add(state
);
113 if (m_pMainFrm
->m_pwndBottomView
->m_pViewData
)
115 if (m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetCount())
116 state
= m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetState(0);
118 for (int i
=0; i
<m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetCount(); i
++)
120 if (state
== m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetState(i
))
126 m_arBottomIdent
.Add(identcount
);
127 m_arBottomState
.Add(state
);
128 state
= m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetState(i
);
132 m_arBottomIdent
.Add(identcount
);
133 m_arBottomState
.Add(state
);
134 m_nLines
= (int)max(m_pMainFrm
->m_pwndBottomView
->m_pViewData
->GetCount(), m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount());
136 else if (m_pMainFrm
->m_pwndRightView
->m_pViewData
)
137 m_nLines
= (int)max(0, m_pMainFrm
->m_pwndRightView
->m_pViewData
->GetCount());
139 if (m_pMainFrm
->m_pwndLeftView
->m_pViewData
)
140 m_nLines
= (int)max(m_nLines
, m_pMainFrm
->m_pwndLeftView
->m_pViewData
->GetCount());
147 void CLocatorBar::OnPaint()
149 CPaintDC
dc(this); // device context for painting
152 long height
= rect
.Height();
153 long width
= rect
.Width();
155 long nBottomLine
= 0;
156 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
158 nTopLine
= m_pMainFrm
->m_pwndLeftView
->m_nTopLine
;
159 nBottomLine
= nTopLine
+ m_pMainFrm
->m_pwndLeftView
->GetScreenLines();
162 VERIFY(cacheDC
.CreateCompatibleDC(&dc
));
164 if (m_pCacheBitmap
== NULL
)
166 m_pCacheBitmap
= new CBitmap
;
167 VERIFY(m_pCacheBitmap
->CreateCompatibleBitmap(&dc
, width
, height
));
169 CBitmap
*pOldBitmap
= cacheDC
.SelectObject(m_pCacheBitmap
);
172 COLORREF color
, color2
;
174 CDiffColors::GetInstance().GetColors(DIFFSTATE_UNKNOWN
, color
, color2
);
175 cacheDC
.FillSolidRect(rect
, color
);
177 long barwidth
= (width
/3);
183 cacheDC
.FillSolidRect(rect
.left
, height
*nTopLine
/m_nLines
,
184 rect
.Width(), (height
*nBottomLine
/m_nLines
)-(height
*nTopLine
/m_nLines
), RGB(180,180,255));
185 if (m_pMainFrm
->m_pwndLeftView
->IsWindowVisible())
187 for (long i
=0; i
<m_arLeftIdent
.GetCount(); i
++)
189 identcount
= m_arLeftIdent
.GetAt(i
);
190 state
= m_arLeftState
.GetAt(i
);
191 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
192 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
193 cacheDC
.FillSolidRect(rect
.left
, height
*linecount
/m_nLines
,
194 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
195 linecount
+= identcount
;
202 if (m_pMainFrm
->m_pwndRightView
->IsWindowVisible())
204 for (long i
=0; i
<m_arRightIdent
.GetCount(); i
++)
206 identcount
= m_arRightIdent
.GetAt(i
);
207 state
= m_arRightState
.GetAt(i
);
208 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
209 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
210 cacheDC
.FillSolidRect(rect
.left
+ (width
*2/3), height
*linecount
/m_nLines
,
211 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
212 linecount
+= identcount
;
218 if (m_pMainFrm
->m_pwndBottomView
->IsWindowVisible())
220 for (long i
=0; i
<m_arBottomIdent
.GetCount(); i
++)
222 identcount
= m_arBottomIdent
.GetAt(i
);
223 state
= m_arBottomState
.GetAt(i
);
224 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
225 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
226 cacheDC
.FillSolidRect(rect
.left
+ (width
/3), height
*linecount
/m_nLines
,
227 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
228 linecount
+= identcount
;
234 cacheDC
.FillSolidRect(rect
.left
, height
*nTopLine
/m_nLines
,
235 rect
.Width(), 2, RGB(0,0,0));
236 cacheDC
.FillSolidRect(rect
.left
, height
*nBottomLine
/m_nLines
,
237 rect
.Width(), 2, RGB(0,0,0));
238 //draw two vertical lines, so there are three rows visible indicating the three panes
239 cacheDC
.FillSolidRect(rect
.left
+ (width
/3), rect
.top
, 1, height
, RGB(0,0,0));
240 cacheDC
.FillSolidRect(rect
.left
+ (width
*2/3), rect
.top
, 1, height
, RGB(0,0,0));
245 int fishstart
= m_MousePos
.y
- height
/20;
246 int fishheight
= height
/10;
247 cacheDC
.FillSolidRect(rect
.left
, fishstart
-1, width
, 1, RGB(0,0,100));
248 cacheDC
.FillSolidRect(rect
.left
, fishstart
+fishheight
+1, width
, 1, RGB(0,0,100));
249 VERIFY(cacheDC
.StretchBlt(rect
.left
, fishstart
, width
, fishheight
,
250 &cacheDC
, 0, fishstart
+ (3*fishheight
/8), width
, fishheight
/4, SRCCOPY
));
251 // draw the magnified area a little darker, so the
252 // user has a clear indication of the magnifier
253 for (int i
=rect
.left
; i
<(width
- rect
.left
); i
++)
255 for (int j
=fishstart
; j
<fishstart
+fishheight
; j
++)
257 color
= cacheDC
.GetPixel(i
, j
);
259 r
= max(GetRValue(color
)-20, 0);
260 g
= max(GetGValue(color
)-20, 0);
261 b
= max(GetBValue(color
)-20, 0);
262 cacheDC
.SetPixel(i
, j
, RGB(r
,g
,b
));
266 VERIFY(dc
.BitBlt(rect
.left
, rect
.top
, width
, height
, &cacheDC
, 0, 0, SRCCOPY
));
268 cacheDC
.SelectObject(pOldBitmap
);
272 void CLocatorBar::OnSize(UINT nType
, int cx
, int cy
)
274 CPaneDialog::OnSize(nType
, cx
, cy
);
276 if (m_pCacheBitmap
!= NULL
)
278 m_pCacheBitmap
->DeleteObject();
279 delete m_pCacheBitmap
;
280 m_pCacheBitmap
= NULL
;
285 BOOL
CLocatorBar::OnEraseBkgnd(CDC
* /*pDC*/)
290 void CLocatorBar::OnLButtonDown(UINT nFlags
, CPoint point
)
294 int nLine
= point
.y
*m_nLines
/rect
.Height();
298 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndBottomView
))
299 m_pMainFrm
->m_pwndBottomView
->GoToLine(nLine
, FALSE
);
300 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
301 m_pMainFrm
->m_pwndLeftView
->GoToLine(nLine
, FALSE
);
302 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndRightView
))
303 m_pMainFrm
->m_pwndRightView
->GoToLine(nLine
, FALSE
);
305 CPaneDialog::OnLButtonDown(nFlags
, point
);
308 void CLocatorBar::OnMouseMove(UINT nFlags
, CPoint point
)
313 m_bMouseWithin
= TRUE
;
315 tme
.cbSize
= sizeof(TRACKMOUSEEVENT
);
316 tme
.dwFlags
= TME_LEAVE
;
317 tme
.hwndTrack
= m_hWnd
;
318 _TrackMouseEvent(&tme
);
321 if (nFlags
& MK_LBUTTON
)
325 int nLine
= point
.y
*m_nLines
/rect
.Height();
329 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndBottomView
))
330 m_pMainFrm
->m_pwndBottomView
->GoToLine(nLine
, FALSE
);
331 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
332 m_pMainFrm
->m_pwndLeftView
->GoToLine(nLine
, FALSE
);
333 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndRightView
))
334 m_pMainFrm
->m_pwndRightView
->GoToLine(nLine
, FALSE
);
339 LRESULT
CLocatorBar::OnMouseLeave(WPARAM
, LPARAM
)
341 m_bMouseWithin
= FALSE
;