Fixed issue #1507: Submodule Diff Dialog should show dirty state only on working...
[TortoiseGit.git] / src / TortoiseMerge / LocatorBar.cpp
blob1d18c8a58ac269d4cbf17970f57372919f0ca4ec
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.
19 #include "stdafx.h"
20 #include "TortoiseMerge.h"
21 #include "MainFrm.h"
22 #include "LocatorBar.h"
23 #include "LeftView.h"
24 #include "RightView.h"
25 #include "BottomView.h"
26 #include "DiffColors.h"
29 IMPLEMENT_DYNAMIC(CLocatorBar, CPaneDialog)
30 CLocatorBar::CLocatorBar() : CPaneDialog()
31 , m_pMainFrm(NULL)
32 , m_pCacheBitmap(NULL)
33 , m_bMouseWithin(FALSE)
34 , m_nLines(-1)
38 CLocatorBar::~CLocatorBar()
40 if (m_pCacheBitmap)
42 m_pCacheBitmap->DeleteObject();
43 delete m_pCacheBitmap;
44 m_pCacheBitmap = NULL;
48 BEGIN_MESSAGE_MAP(CLocatorBar, CPaneDialog)
49 ON_WM_PAINT()
50 ON_WM_SIZE()
51 ON_WM_ERASEBKGND()
52 ON_WM_LBUTTONDOWN()
53 ON_WM_MOUSEMOVE()
54 ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
55 END_MESSAGE_MAP()
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;
67 long identcount = 1;
68 m_nLines = 0;
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))
77 identcount++;
79 else
81 m_arLeftIdent.Add(identcount);
82 m_arLeftState.Add(state);
83 state = m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(i);
84 identcount = 1;
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);
95 identcount = 1;
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))
100 identcount++;
102 else
104 m_arRightIdent.Add(identcount);
105 m_arRightState.Add(state);
106 state = m_pMainFrm->m_pwndRightView->m_pViewData->GetState(i);
107 identcount = 1;
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);
118 identcount = 1;
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))
123 identcount++;
125 else
127 m_arBottomIdent.Add(identcount);
128 m_arBottomState.Add(state);
129 state = m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(i);
130 identcount = 1;
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());
142 else
143 m_nLines = 0;
144 m_nLines++;
145 Invalidate();
148 void CLocatorBar::OnPaint()
150 CPaintDC dc(this); // device context for painting
151 CRect rect;
152 GetClientRect(rect);
153 long height = rect.Height();
154 long width = rect.Width();
155 long nTopLine = 0;
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();
162 CDC cacheDC;
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);
179 DWORD state = 0;
180 long identcount = 0;
181 long linecount = 0;
183 if (m_nLines)
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;
199 state = 0;
200 identcount = 0;
201 linecount = 0;
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;
216 state = 0;
217 identcount = 0;
218 linecount = 0;
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;
233 if (m_nLines == 0)
234 m_nLines = 1;
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));
243 // draw the fish eye
244 if (m_bMouseWithin)
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);
259 int r,g,b;
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);
270 cacheDC.DeleteDC();
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;
283 Invalidate();
286 BOOL CLocatorBar::OnEraseBkgnd(CDC* /*pDC*/)
288 return TRUE;
291 void CLocatorBar::OnLButtonDown(UINT nFlags, CPoint point)
293 CRect rect;
294 GetClientRect(rect);
295 int nLine = point.y*m_nLines/rect.Height();
297 if (nLine < 0)
298 nLine = 0;
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);
305 Invalidate();
306 CPaneDialog::OnLButtonDown(nFlags, point);
309 void CLocatorBar::OnMouseMove(UINT nFlags, CPoint point)
311 m_MousePos = point;
312 if (!m_bMouseWithin)
314 m_bMouseWithin = TRUE;
315 TRACKMOUSEEVENT tme;
316 tme.cbSize = sizeof(TRACKMOUSEEVENT);
317 tme.dwFlags = TME_LEAVE;
318 tme.hwndTrack = m_hWnd;
319 _TrackMouseEvent(&tme);
322 if (nFlags & MK_LBUTTON)
324 CRect rect;
325 GetClientRect(rect);
326 int nLine = point.y*m_nLines/rect.Height();
328 if (nLine < 0)
329 nLine = 0;
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);
337 Invalidate();
340 LRESULT CLocatorBar::OnMouseLeave(WPARAM, LPARAM)
342 m_bMouseWithin = FALSE;
343 Invalidate();
344 return 0;