1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2006-2012 - 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"
30 IMPLEMENT_DYNAMIC(CLocatorBar
, CPaneDialog
)
31 CLocatorBar::CLocatorBar() : CPaneDialog()
33 , m_pCacheBitmap(NULL
)
34 , m_regUseFishEye(_T("Software\\TortoiseGitMerge\\UseFishEye"), TRUE
)
39 CLocatorBar::~CLocatorBar()
43 m_pCacheBitmap
->DeleteObject();
44 delete m_pCacheBitmap
;
45 m_pCacheBitmap
= NULL
;
49 BEGIN_MESSAGE_MAP(CLocatorBar
, CPaneDialog
)
56 ON_MESSAGE(WM_MOUSELEAVE
, OnMouseLeave
)
59 void CLocatorBar::DocumentUpdated()
61 m_pMainFrm
= (CMainFrame
*)this->GetParentFrame();
62 if (m_pMainFrm
== NULL
)
66 DocumentUpdated(m_pMainFrm
->m_pwndLeftView
, m_arLeftIdent
, m_arLeftState
);
67 DocumentUpdated(m_pMainFrm
->m_pwndRightView
, m_arRightIdent
, m_arRightState
);
68 DocumentUpdated(m_pMainFrm
->m_pwndBottomView
, m_arBottomIdent
, m_arBottomState
);
70 if (m_pMainFrm
->m_pwndLeftView
)
72 m_nLines
= m_pMainFrm
->m_pwndLeftView
->GetLineCount();
73 if (m_pMainFrm
->m_pwndRightView
)
75 m_nLines
= std::max
<int>(m_nLines
, m_pMainFrm
->m_pwndRightView
->GetLineCount());
76 if (m_pMainFrm
->m_pwndBottomView
)
78 m_nLines
= std::max
<int>(m_nLines
, m_pMainFrm
->m_pwndBottomView
->GetLineCount());
85 void CLocatorBar::DocumentUpdated(CBaseView
* view
, CDWordArray
& indents
, CDWordArray
& states
)
89 CViewData
* viewData
= view
->m_pViewData
;
94 const int linesInView
= view
->GetLineCount();
95 DiffStates state
= DIFFSTATE_UNKNOWN
;
97 state
= viewData
->GetState(0);
98 for (int i
=1; i
<linesInView
; i
++)
100 const DiffStates lineState
= viewData
->GetState(view
->GetViewLineForScreen(i
));
101 if (state
== lineState
)
107 indents
.Add(identcount
);
113 indents
.Add(identcount
);
117 void CLocatorBar::OnPaint()
119 CPaintDC
dc(this); // device context for painting
122 const long height
= rect
.Height();
123 const long width
= rect
.Width();
125 long nBottomLine
= 0;
126 if ((m_pMainFrm
)&&(m_pMainFrm
->m_pwndLeftView
))
128 nTopLine
= m_pMainFrm
->m_pwndLeftView
->m_nTopLine
;
129 nBottomLine
= nTopLine
+ m_pMainFrm
->m_pwndLeftView
->GetScreenLines();
132 VERIFY(cacheDC
.CreateCompatibleDC(&dc
));
134 if (m_pCacheBitmap
== NULL
)
136 m_pCacheBitmap
= new CBitmap
;
137 VERIFY(m_pCacheBitmap
->CreateCompatibleBitmap(&dc
, width
, height
));
139 CBitmap
*pOldBitmap
= cacheDC
.SelectObject(m_pCacheBitmap
);
141 COLORREF color
, color2
;
142 CDiffColors::GetInstance().GetColors(DIFFSTATE_UNKNOWN
, color
, color2
);
143 cacheDC
.FillSolidRect(rect
, color
);
147 cacheDC
.FillSolidRect(rect
.left
, height
*nTopLine
/m_nLines
,
148 width
, (height
*nBottomLine
/m_nLines
)-(height
*nTopLine
/m_nLines
), RGB(180,180,255));
152 PaintView (cacheDC
, m_pMainFrm
->m_pwndLeftView
, m_arLeftIdent
, m_arLeftState
, rect
, 0);
153 PaintView (cacheDC
, m_pMainFrm
->m_pwndRightView
, m_arRightIdent
, m_arRightState
, rect
, 2);
154 PaintView (cacheDC
, m_pMainFrm
->m_pwndBottomView
, m_arBottomIdent
, m_arBottomState
, rect
, 1);
160 cacheDC
.FillSolidRect(rect
.left
, height
*nTopLine
/m_nLines
,
161 width
, 2, RGB(0,0,0));
162 cacheDC
.FillSolidRect(rect
.left
, height
*nBottomLine
/m_nLines
,
163 width
, 2, RGB(0,0,0));
164 //draw two vertical lines, so there are three rows visible indicating the three panes
165 cacheDC
.FillSolidRect(rect
.left
+ (width
/3), rect
.top
, 1, height
, RGB(0,0,0));
166 cacheDC
.FillSolidRect(rect
.left
+ (width
*2/3), rect
.top
, 1, height
, RGB(0,0,0));
169 DWORD pos
= GetMessagePos();
170 CRect screenRect
= rect
;
171 ClientToScreen(screenRect
);
173 pt
.x
= GET_X_LPARAM(pos
);
174 pt
.y
= GET_Y_LPARAM(pos
);
176 if ((screenRect
.PtInRect(pt
))&&(DWORD(m_regUseFishEye
)))
177 DrawFishEye (cacheDC
, rect
);
179 VERIFY(dc
.BitBlt(rect
.left
, rect
.top
, width
, height
, &cacheDC
, 0, 0, SRCCOPY
));
181 cacheDC
.SelectObject(pOldBitmap
);
185 void CLocatorBar::OnSize(UINT nType
, int cx
, int cy
)
187 CPaneDialog::OnSize(nType
, cx
, cy
);
189 if (m_pCacheBitmap
!= NULL
)
191 m_pCacheBitmap
->DeleteObject();
192 delete m_pCacheBitmap
;
193 m_pCacheBitmap
= NULL
;
198 BOOL
CLocatorBar::OnEraseBkgnd(CDC
* /*pDC*/)
203 void CLocatorBar::OnLButtonDown(UINT nFlags
, CPoint point
)
205 ScrollOnMouseMove(point
);
207 CPaneDialog::OnLButtonDown(nFlags
, point
);
210 void CLocatorBar::OnMouseMove(UINT nFlags
, CPoint point
)
214 if (nFlags
& MK_LBUTTON
)
217 ScrollOnMouseMove(point
);
221 Tme
.cbSize
= sizeof(TRACKMOUSEEVENT
);
222 Tme
.dwFlags
= TME_LEAVE
;
223 Tme
.hwndTrack
= m_hWnd
;
224 TrackMouseEvent(&Tme
);
230 LRESULT
CLocatorBar::OnMouseLeave(WPARAM
/*wParam*/, LPARAM
/*lParam*/)
236 void CLocatorBar::OnLButtonUp(UINT nFlags
, CPoint point
)
241 CPaneDialog::OnLButtonUp(nFlags
, point
);
244 void CLocatorBar::ScrollOnMouseMove(const CPoint
& point
)
252 int nLine
= point
.y
*m_nLines
/rect
.Height();
256 ScrollViewToLine(m_pMainFrm
->m_pwndBottomView
, nLine
);
257 ScrollViewToLine(m_pMainFrm
->m_pwndLeftView
, nLine
);
258 ScrollViewToLine(m_pMainFrm
->m_pwndRightView
, nLine
);
261 void CLocatorBar::ScrollViewToLine(CBaseView
* view
, int nLine
) const
264 view
->GoToLine(nLine
, FALSE
);
267 void CLocatorBar::PaintView(CDC
& cacheDC
, CBaseView
* view
, CDWordArray
& indents
,
268 CDWordArray
& states
, const CRect
& rect
, int stripeIndex
)
270 if (!view
->IsWindowVisible())
273 const long height
= rect
.Height();
274 const long width
= rect
.Width();
275 const long barwidth
= (width
/3);
277 for (long i
=0; i
<indents
.GetCount(); i
++)
279 COLORREF color
, color2
;
280 const long identcount
= indents
.GetAt(i
);
281 const DWORD state
= states
.GetAt(i
);
282 CDiffColors::GetInstance().GetColors((DiffStates
)state
, color
, color2
);
283 if ((DiffStates
)state
!= DIFFSTATE_NORMAL
)
285 cacheDC
.FillSolidRect(rect
.left
+ (width
*stripeIndex
/3), height
*linecount
/m_nLines
,
286 barwidth
, max(height
*identcount
/m_nLines
,1), color
);
288 linecount
+= identcount
;
290 if (view
->GetMarkedWord()[0])
292 COLORREF color
, color2
;
293 CDiffColors::GetInstance().GetColors(DIFFSTATE_NORMAL
, color
, color2
);
294 color
= CAppUtils::IntenseColor(200, color
);
295 for (size_t i
=0; i
<view
->m_arMarkedWordLines
.size(); ++i
)
297 if (view
->m_arMarkedWordLines
[i
])
299 cacheDC
.FillSolidRect(rect
.left
+ (width
*stripeIndex
/3), (int)(height
*i
/m_nLines
),
300 barwidth
, max(height
/m_nLines
,2), color
);
304 if (view
->GetFindString()[0])
306 COLORREF color
, color2
;
307 CDiffColors::GetInstance().GetColors(DIFFSTATE_NORMAL
, color
, color2
);
308 color
= CAppUtils::IntenseColor(30, color
);
309 for (size_t i
=0; i
<view
->m_arFindStringLines
.size(); ++i
)
311 if (view
->m_arFindStringLines
[i
])
313 cacheDC
.FillSolidRect(rect
.left
+ (width
*stripeIndex
/3), (int)(height
*i
/m_nLines
),
314 barwidth
, max(height
/m_nLines
,2), color
);
321 void CLocatorBar::DrawFishEye(CDC
& cacheDC
, const CRect
& rect
)
323 const long height
= rect
.Height();
324 const long width
= rect
.Width();
325 const int fishstart
= m_MousePos
.y
- height
/20;
326 const int fishheight
= height
/10;
327 cacheDC
.FillSolidRect(rect
.left
, fishstart
-1, width
, 1, RGB(0,0,100));
328 cacheDC
.FillSolidRect(rect
.left
, fishstart
+fishheight
+1, width
, 1, RGB(0,0,100));
329 VERIFY(cacheDC
.StretchBlt(rect
.left
, fishstart
, width
, fishheight
,
330 &cacheDC
, 0, fishstart
+ (3*fishheight
/8), width
, fishheight
/4, SRCCOPY
));
331 // draw the magnified area a little darker, so the
332 // user has a clear indication of the magnifier
333 for (int i
=rect
.left
; i
<(width
- rect
.left
); i
++)
335 for (int j
=fishstart
; j
<fishstart
+fishheight
; j
++)
337 const COLORREF color
= cacheDC
.GetPixel(i
, j
);
338 int r
= max(GetRValue(color
)-20, 0);
339 int g
= max(GetGValue(color
)-20, 0);
340 int b
= max(GetBValue(color
)-20, 0);
341 cacheDC
.SetPixel(i
, j
, RGB(r
,g
,b
));