renamed ITEMIS_SUBMODULE to ITEMIS_SUBMODULECONTAINER
[TortoiseGit.git] / src / TortoiseMerge / LocatorBar.cpp
blob1d74b5a5238423c344145073f0b49a75d9d55c9b
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()
32 m_pMainFrm = NULL;
33 m_pCacheBitmap = NULL;
34 m_bMouseWithin = FALSE;
37 CLocatorBar::~CLocatorBar()
39 if (m_pCacheBitmap)
41 m_pCacheBitmap->DeleteObject();
42 delete m_pCacheBitmap;
43 m_pCacheBitmap = NULL;
47 BEGIN_MESSAGE_MAP(CLocatorBar, CPaneDialog)
48 ON_WM_PAINT()
49 ON_WM_SIZE()
50 ON_WM_ERASEBKGND()
51 ON_WM_LBUTTONDOWN()
52 ON_WM_MOUSEMOVE()
53 ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
54 END_MESSAGE_MAP()
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;
66 long identcount = 1;
67 m_nLines = 0;
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))
76 identcount++;
78 else
80 m_arLeftIdent.Add(identcount);
81 m_arLeftState.Add(state);
82 state = m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(i);
83 identcount = 1;
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);
94 identcount = 1;
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))
99 identcount++;
101 else
103 m_arRightIdent.Add(identcount);
104 m_arRightState.Add(state);
105 state = m_pMainFrm->m_pwndRightView->m_pViewData->GetState(i);
106 identcount = 1;
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);
117 identcount = 1;
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))
122 identcount++;
124 else
126 m_arBottomIdent.Add(identcount);
127 m_arBottomState.Add(state);
128 state = m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(i);
129 identcount = 1;
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());
141 else
142 m_nLines = 0;
143 m_nLines++;
144 Invalidate();
147 void CLocatorBar::OnPaint()
149 CPaintDC dc(this); // device context for painting
150 CRect rect;
151 GetClientRect(rect);
152 long height = rect.Height();
153 long width = rect.Width();
154 long nTopLine = 0;
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();
161 CDC cacheDC;
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);
178 DWORD state = 0;
179 long identcount = 0;
180 long linecount = 0;
182 if (m_nLines)
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;
198 state = 0;
199 identcount = 0;
200 linecount = 0;
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;
215 state = 0;
216 identcount = 0;
217 linecount = 0;
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;
232 if (m_nLines == 0)
233 m_nLines = 1;
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));
242 // draw the fish eye
243 if (m_bMouseWithin)
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);
258 int r,g,b;
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);
269 cacheDC.DeleteDC();
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;
282 Invalidate();
285 BOOL CLocatorBar::OnEraseBkgnd(CDC* /*pDC*/)
287 return TRUE;
290 void CLocatorBar::OnLButtonDown(UINT nFlags, CPoint point)
292 CRect rect;
293 GetClientRect(rect);
294 int nLine = point.y*m_nLines/rect.Height();
296 if (nLine < 0)
297 nLine = 0;
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);
304 Invalidate();
305 CPaneDialog::OnLButtonDown(nFlags, point);
308 void CLocatorBar::OnMouseMove(UINT nFlags, CPoint point)
310 m_MousePos = point;
311 if (!m_bMouseWithin)
313 m_bMouseWithin = TRUE;
314 TRACKMOUSEEVENT tme;
315 tme.cbSize = sizeof(TRACKMOUSEEVENT);
316 tme.dwFlags = TME_LEAVE;
317 tme.hwndTrack = m_hWnd;
318 _TrackMouseEvent(&tme);
321 if (nFlags & MK_LBUTTON)
323 CRect rect;
324 GetClientRect(rect);
325 int nLine = point.y*m_nLines/rect.Height();
327 if (nLine < 0)
328 nLine = 0;
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);
336 Invalidate();
339 LRESULT CLocatorBar::OnMouseLeave(WPARAM, LPARAM)
341 m_bMouseWithin = FALSE;
342 Invalidate();
343 return 0;