1 // TortoiseMerge - a Diff/Patch program
\r
3 // Copyright (C) 2006-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include "TortoiseMerge.h"
\r
21 #include "MainFrm.h"
\r
22 #include "LocatorBar.h"
\r
23 #include "LeftView.h"
\r
24 #include "RightView.h"
\r
25 #include "BottomView.h"
\r
26 #include "DiffColors.h"
\r
29 IMPLEMENT_DYNAMIC(CLocatorBar, CPaneDialog)
\r
30 CLocatorBar::CLocatorBar() : CPaneDialog()
\r
33 m_pCacheBitmap = NULL;
\r
34 m_bMouseWithin = FALSE;
\r
37 CLocatorBar::~CLocatorBar()
\r
41 m_pCacheBitmap->DeleteObject();
\r
42 delete m_pCacheBitmap;
\r
43 m_pCacheBitmap = NULL;
\r
47 BEGIN_MESSAGE_MAP(CLocatorBar, CPaneDialog)
\r
53 ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
\r
56 void CLocatorBar::DocumentUpdated()
\r
58 m_pMainFrm = (CMainFrame *)this->GetParentFrame();
\r
59 m_arLeftIdent.RemoveAll();
\r
60 m_arLeftState.RemoveAll();
\r
61 m_arRightIdent.RemoveAll();
\r
62 m_arRightState.RemoveAll();
\r
63 m_arBottomIdent.RemoveAll();
\r
64 m_arBottomState.RemoveAll();
\r
65 DiffStates state = DIFFSTATE_UNKNOWN;
\r
66 long identcount = 1;
\r
68 if (m_pMainFrm->m_pwndLeftView->m_pViewData)
\r
70 if (m_pMainFrm->m_pwndLeftView->m_pViewData->GetCount())
\r
71 state = m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(0);
\r
72 for (int i=0; i<m_pMainFrm->m_pwndLeftView->m_pViewData->GetCount(); i++)
\r
74 if (state == m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(i))
\r
80 m_arLeftIdent.Add(identcount);
\r
81 m_arLeftState.Add(state);
\r
82 state = m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(i);
\r
86 m_arLeftIdent.Add(identcount);
\r
87 m_arLeftState.Add(state);
\r
90 if (m_pMainFrm->m_pwndRightView->m_pViewData)
\r
92 if (m_pMainFrm->m_pwndRightView->m_pViewData->GetCount())
\r
93 state = m_pMainFrm->m_pwndRightView->m_pViewData->GetState(0);
\r
95 for (int i=0; i<m_pMainFrm->m_pwndRightView->m_pViewData->GetCount(); i++)
\r
97 if (state == m_pMainFrm->m_pwndRightView->m_pViewData->GetState(i))
\r
103 m_arRightIdent.Add(identcount);
\r
104 m_arRightState.Add(state);
\r
105 state = m_pMainFrm->m_pwndRightView->m_pViewData->GetState(i);
\r
109 m_arRightIdent.Add(identcount);
\r
110 m_arRightState.Add(state);
\r
113 if (m_pMainFrm->m_pwndBottomView->m_pViewData)
\r
115 if (m_pMainFrm->m_pwndBottomView->m_pViewData->GetCount())
\r
116 state = m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(0);
\r
118 for (int i=0; i<m_pMainFrm->m_pwndBottomView->m_pViewData->GetCount(); i++)
\r
120 if (state == m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(i))
\r
126 m_arBottomIdent.Add(identcount);
\r
127 m_arBottomState.Add(state);
\r
128 state = m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(i);
\r
132 m_arBottomIdent.Add(identcount);
\r
133 m_arBottomState.Add(state);
\r
134 m_nLines = (int)max(m_pMainFrm->m_pwndBottomView->m_pViewData->GetCount(), m_pMainFrm->m_pwndRightView->m_pViewData->GetCount());
\r
136 else if (m_pMainFrm->m_pwndRightView->m_pViewData)
\r
137 m_nLines = (int)max(0, m_pMainFrm->m_pwndRightView->m_pViewData->GetCount());
\r
139 if (m_pMainFrm->m_pwndLeftView->m_pViewData)
\r
140 m_nLines = (int)max(m_nLines, m_pMainFrm->m_pwndLeftView->m_pViewData->GetCount());
\r
147 void CLocatorBar::OnPaint()
\r
149 CPaintDC dc(this); // device context for painting
\r
151 GetClientRect(rect);
\r
152 long height = rect.Height();
\r
153 long width = rect.Width();
\r
155 long nBottomLine = 0;
\r
156 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndLeftView))
\r
158 nTopLine = m_pMainFrm->m_pwndLeftView->m_nTopLine;
\r
159 nBottomLine = nTopLine + m_pMainFrm->m_pwndLeftView->GetScreenLines();
\r
162 VERIFY(cacheDC.CreateCompatibleDC(&dc));
\r
164 if (m_pCacheBitmap == NULL)
\r
166 m_pCacheBitmap = new CBitmap;
\r
167 VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(&dc, width, height));
\r
169 CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);
\r
172 COLORREF color, color2;
\r
174 CDiffColors::GetInstance().GetColors(DIFFSTATE_UNKNOWN, color, color2);
\r
175 cacheDC.FillSolidRect(rect, color);
\r
177 long barwidth = (width/3);
\r
179 long identcount = 0;
\r
180 long linecount = 0;
\r
183 cacheDC.FillSolidRect(rect.left, height*nTopLine/m_nLines,
\r
184 rect.Width(), (height*nBottomLine/m_nLines)-(height*nTopLine/m_nLines), RGB(180,180,255));
\r
185 if (m_pMainFrm->m_pwndLeftView->IsWindowVisible())
\r
187 for (long i=0; i<m_arLeftIdent.GetCount(); i++)
\r
189 identcount = m_arLeftIdent.GetAt(i);
\r
190 state = m_arLeftState.GetAt(i);
\r
191 COLORREF color, color2;
\r
192 CDiffColors::GetInstance().GetColors((DiffStates)state, color, color2);
\r
193 if ((DiffStates)state != DIFFSTATE_NORMAL)
\r
194 cacheDC.FillSolidRect(rect.left, height*linecount/m_nLines,
\r
195 barwidth, max(height*identcount/m_nLines,1), color);
\r
196 linecount += identcount;
\r
203 if (m_pMainFrm->m_pwndRightView->IsWindowVisible())
\r
205 for (long i=0; i<m_arRightIdent.GetCount(); i++)
\r
207 identcount = m_arRightIdent.GetAt(i);
\r
208 state = m_arRightState.GetAt(i);
\r
209 COLORREF color, color2;
\r
210 CDiffColors::GetInstance().GetColors((DiffStates)state, color, color2);
\r
211 if ((DiffStates)state != DIFFSTATE_NORMAL)
\r
212 cacheDC.FillSolidRect(rect.left + (width*2/3), height*linecount/m_nLines,
\r
213 barwidth, max(height*identcount/m_nLines,1), color);
\r
214 linecount += identcount;
\r
220 if (m_pMainFrm->m_pwndBottomView->IsWindowVisible())
\r
222 for (long i=0; i<m_arBottomIdent.GetCount(); i++)
\r
224 identcount = m_arBottomIdent.GetAt(i);
\r
225 state = m_arBottomState.GetAt(i);
\r
226 COLORREF color, color2;
\r
227 CDiffColors::GetInstance().GetColors((DiffStates)state, color, color2);
\r
228 if ((DiffStates)state != DIFFSTATE_NORMAL)
\r
229 cacheDC.FillSolidRect(rect.left + (width/3), height*linecount/m_nLines,
\r
230 barwidth, max(height*identcount/m_nLines,1), color);
\r
231 linecount += identcount;
\r
237 cacheDC.FillSolidRect(rect.left, height*nTopLine/m_nLines,
\r
238 rect.Width(), 2, RGB(0,0,0));
\r
239 cacheDC.FillSolidRect(rect.left, height*nBottomLine/m_nLines,
\r
240 rect.Width(), 2, RGB(0,0,0));
\r
241 //draw two vertical lines, so there are three rows visible indicating the three panes
\r
242 cacheDC.FillSolidRect(rect.left + (width/3), rect.top, 1, height, RGB(0,0,0));
\r
243 cacheDC.FillSolidRect(rect.left + (width*2/3), rect.top, 1, height, RGB(0,0,0));
\r
245 // draw the fish eye
\r
246 if (m_bMouseWithin)
\r
248 int fishstart = m_MousePos.y - height/20;
\r
249 int fishheight = height/10;
\r
250 cacheDC.FillSolidRect(rect.left, fishstart-1, width, 1, RGB(0,0,100));
\r
251 cacheDC.FillSolidRect(rect.left, fishstart+fishheight+1, width, 1, RGB(0,0,100));
\r
252 VERIFY(cacheDC.StretchBlt(rect.left, fishstart, width, fishheight,
\r
253 &cacheDC, 0, fishstart + (3*fishheight/8), width, fishheight/4, SRCCOPY));
\r
254 // draw the magnified area a little darker, so the
\r
255 // user has a clear indication of the magnifier
\r
256 for (int i=rect.left; i<(width - rect.left); i++)
\r
258 for (int j=fishstart; j<fishstart+fishheight; j++)
\r
260 COLORREF color = cacheDC.GetPixel(i, j);
\r
262 r = max(GetRValue(color)-20, 0);
\r
263 g = max(GetGValue(color)-20, 0);
\r
264 b = max(GetBValue(color)-20, 0);
\r
265 cacheDC.SetPixel(i, j, RGB(r,g,b));
\r
269 VERIFY(dc.BitBlt(rect.left, rect.top, width, height, &cacheDC, 0, 0, SRCCOPY));
\r
271 cacheDC.SelectObject(pOldBitmap);
\r
272 cacheDC.DeleteDC();
\r
275 void CLocatorBar::OnSize(UINT nType, int cx, int cy)
\r
277 CPaneDialog::OnSize(nType, cx, cy);
\r
279 if (m_pCacheBitmap != NULL)
\r
281 m_pCacheBitmap->DeleteObject();
\r
282 delete m_pCacheBitmap;
\r
283 m_pCacheBitmap = NULL;
\r
288 BOOL CLocatorBar::OnEraseBkgnd(CDC* /*pDC*/)
\r
293 void CLocatorBar::OnLButtonDown(UINT nFlags, CPoint point)
\r
296 GetClientRect(rect);
\r
297 int nLine = point.y*m_nLines/rect.Height();
\r
301 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndBottomView))
\r
302 m_pMainFrm->m_pwndBottomView->GoToLine(nLine, FALSE);
\r
303 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndLeftView))
\r
304 m_pMainFrm->m_pwndLeftView->GoToLine(nLine, FALSE);
\r
305 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndRightView))
\r
306 m_pMainFrm->m_pwndRightView->GoToLine(nLine, FALSE);
\r
308 CPaneDialog::OnLButtonDown(nFlags, point);
\r
311 void CLocatorBar::OnMouseMove(UINT nFlags, CPoint point)
\r
313 m_MousePos = point;
\r
314 if (!m_bMouseWithin)
\r
316 m_bMouseWithin = TRUE;
\r
317 TRACKMOUSEEVENT tme;
\r
318 tme.cbSize = sizeof(TRACKMOUSEEVENT);
\r
319 tme.dwFlags = TME_LEAVE;
\r
320 tme.hwndTrack = m_hWnd;
\r
321 _TrackMouseEvent(&tme);
\r
324 if (nFlags & MK_LBUTTON)
\r
327 GetClientRect(rect);
\r
328 int nLine = point.y*m_nLines/rect.Height();
\r
332 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndBottomView))
\r
333 m_pMainFrm->m_pwndBottomView->GoToLine(nLine, FALSE);
\r
334 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndLeftView))
\r
335 m_pMainFrm->m_pwndLeftView->GoToLine(nLine, FALSE);
\r
336 if ((m_pMainFrm)&&(m_pMainFrm->m_pwndRightView))
\r
337 m_pMainFrm->m_pwndRightView->GoToLine(nLine, FALSE);
\r
342 LRESULT CLocatorBar::OnMouseLeave(WPARAM, LPARAM)
\r
344 m_bMouseWithin = FALSE;
\r