OSDN Git Service

883c0b42b79c7d35c29195895966df5d70eb9b7e
[tortoisegit/TortoiseGitJp.git] / src / TortoiseMerge / LocatorBar.cpp
1 // TortoiseMerge - a Diff/Patch program\r
2 \r
3 // Copyright (C) 2006-2008 - TortoiseSVN\r
4 \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
9 \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
14 \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
18 //\r
19 #include "stdafx.h"\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
27 \r
28 \r
29 IMPLEMENT_DYNAMIC(CLocatorBar, CPaneDialog)\r
30 CLocatorBar::CLocatorBar() : CPaneDialog()\r
31 {\r
32         m_pMainFrm = NULL;\r
33         m_pCacheBitmap = NULL;\r
34         m_bMouseWithin = FALSE;\r
35 }\r
36 \r
37 CLocatorBar::~CLocatorBar()\r
38 {\r
39         if (m_pCacheBitmap)\r
40         {\r
41                 m_pCacheBitmap->DeleteObject();\r
42                 delete m_pCacheBitmap;\r
43                 m_pCacheBitmap = NULL;\r
44         }\r
45 }\r
46 \r
47 BEGIN_MESSAGE_MAP(CLocatorBar, CPaneDialog)\r
48         ON_WM_PAINT()\r
49         ON_WM_SIZE()\r
50         ON_WM_ERASEBKGND()\r
51         ON_WM_LBUTTONDOWN()\r
52         ON_WM_MOUSEMOVE()\r
53         ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)\r
54 END_MESSAGE_MAP()\r
55 \r
56 void CLocatorBar::DocumentUpdated()\r
57 {\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
67         m_nLines = 0;\r
68         if (m_pMainFrm->m_pwndLeftView->m_pViewData)\r
69         {\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
73                 {\r
74                         if (state == m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(i))\r
75                         {\r
76                                 identcount++;\r
77                         }\r
78                         else\r
79                         {\r
80                                 m_arLeftIdent.Add(identcount);\r
81                                 m_arLeftState.Add(state);\r
82                                 state = m_pMainFrm->m_pwndLeftView->m_pViewData->GetState(i);\r
83                                 identcount = 1;\r
84                         } \r
85                 }\r
86                 m_arLeftIdent.Add(identcount);\r
87                 m_arLeftState.Add(state);\r
88         }\r
89 \r
90         if (m_pMainFrm->m_pwndRightView->m_pViewData)\r
91         {\r
92                 if (m_pMainFrm->m_pwndRightView->m_pViewData->GetCount())\r
93                         state = m_pMainFrm->m_pwndRightView->m_pViewData->GetState(0);\r
94                 identcount = 1;\r
95                 for (int i=0; i<m_pMainFrm->m_pwndRightView->m_pViewData->GetCount(); i++)\r
96                 {\r
97                         if (state == m_pMainFrm->m_pwndRightView->m_pViewData->GetState(i))\r
98                         {\r
99                                 identcount++;\r
100                         }\r
101                         else\r
102                         {\r
103                                 m_arRightIdent.Add(identcount);\r
104                                 m_arRightState.Add(state);\r
105                                 state = m_pMainFrm->m_pwndRightView->m_pViewData->GetState(i);\r
106                                 identcount = 1;\r
107                         }\r
108                 }\r
109                 m_arRightIdent.Add(identcount);\r
110                 m_arRightState.Add(state);\r
111         }\r
112 \r
113         if (m_pMainFrm->m_pwndBottomView->m_pViewData)\r
114         {\r
115                 if (m_pMainFrm->m_pwndBottomView->m_pViewData->GetCount())\r
116                         state = m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(0);\r
117                 identcount = 1;\r
118                 for (int i=0; i<m_pMainFrm->m_pwndBottomView->m_pViewData->GetCount(); i++)\r
119                 {\r
120                         if (state == m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(i))\r
121                         {\r
122                                 identcount++;\r
123                         }\r
124                         else\r
125                         {\r
126                                 m_arBottomIdent.Add(identcount);\r
127                                 m_arBottomState.Add(state);\r
128                                 state = m_pMainFrm->m_pwndBottomView->m_pViewData->GetState(i);\r
129                                 identcount = 1;\r
130                         }\r
131                 }\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
135         }\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
138 \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
141         else\r
142                 m_nLines = 0;\r
143         m_nLines++;\r
144         Invalidate();\r
145 }\r
146 \r
147 void CLocatorBar::OnPaint()\r
148 {\r
149         CPaintDC dc(this); // device context for painting\r
150         CRect rect;\r
151         GetClientRect(rect);\r
152         long height = rect.Height();\r
153         long width = rect.Width();\r
154         long nTopLine = 0;\r
155         long nBottomLine = 0;\r
156         if ((m_pMainFrm)&&(m_pMainFrm->m_pwndLeftView))\r
157         {\r
158                 nTopLine = m_pMainFrm->m_pwndLeftView->m_nTopLine;\r
159                 nBottomLine = nTopLine + m_pMainFrm->m_pwndLeftView->GetScreenLines();\r
160         }\r
161         CDC cacheDC;\r
162         VERIFY(cacheDC.CreateCompatibleDC(&dc));\r
163 \r
164         if (m_pCacheBitmap == NULL)\r
165         {\r
166                 m_pCacheBitmap = new CBitmap;\r
167                 VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(&dc, width, height));\r
168         }\r
169         CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);\r
170 \r
171 \r
172         COLORREF color, color2;\r
173         \r
174         CDiffColors::GetInstance().GetColors(DIFFSTATE_UNKNOWN, color, color2);\r
175         cacheDC.FillSolidRect(rect, color);\r
176         \r
177         long barwidth = (width/3);\r
178         DWORD state = 0;\r
179         long identcount = 0;\r
180         long linecount = 0;\r
181         \r
182         if (m_nLines)\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
186         {\r
187                 for (long i=0; i<m_arLeftIdent.GetCount(); i++)\r
188                 {\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
197                 }\r
198         }\r
199         state = 0;\r
200         identcount = 0;\r
201         linecount = 0;\r
202 \r
203         if (m_pMainFrm->m_pwndRightView->IsWindowVisible())\r
204         {\r
205                 for (long i=0; i<m_arRightIdent.GetCount(); i++)\r
206                 {\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
215                 }\r
216         }\r
217         state = 0;\r
218         identcount = 0;\r
219         linecount = 0;\r
220         if (m_pMainFrm->m_pwndBottomView->IsWindowVisible())\r
221         {\r
222                 for (long i=0; i<m_arBottomIdent.GetCount(); i++)\r
223                 {\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
232                 }\r
233         }\r
234 \r
235         if (m_nLines == 0)\r
236                 m_nLines = 1;\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
244 \r
245         // draw the fish eye\r
246         if (m_bMouseWithin)\r
247         {\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
257                 {\r
258                         for (int j=fishstart; j<fishstart+fishheight; j++)\r
259                         {\r
260                                 COLORREF color = cacheDC.GetPixel(i, j);\r
261                                 int r,g,b;\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
266                         }\r
267                 }\r
268         }\r
269         VERIFY(dc.BitBlt(rect.left, rect.top, width, height, &cacheDC, 0, 0, SRCCOPY));\r
270         \r
271         cacheDC.SelectObject(pOldBitmap);\r
272         cacheDC.DeleteDC();\r
273 }\r
274 \r
275 void CLocatorBar::OnSize(UINT nType, int cx, int cy)\r
276 {\r
277         CPaneDialog::OnSize(nType, cx, cy);\r
278 \r
279         if (m_pCacheBitmap != NULL)\r
280         {\r
281                 m_pCacheBitmap->DeleteObject();\r
282                 delete m_pCacheBitmap;\r
283                 m_pCacheBitmap = NULL;\r
284         }\r
285         Invalidate();\r
286 }\r
287 \r
288 BOOL CLocatorBar::OnEraseBkgnd(CDC* /*pDC*/)\r
289 {\r
290         return TRUE;\r
291 }\r
292 \r
293 void CLocatorBar::OnLButtonDown(UINT nFlags, CPoint point)\r
294 {\r
295         CRect rect;\r
296         GetClientRect(rect); \r
297         int nLine = point.y*m_nLines/rect.Height();\r
298 \r
299         if (nLine < 0)\r
300                 nLine = 0;\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
307         Invalidate();\r
308         CPaneDialog::OnLButtonDown(nFlags, point);\r
309 }\r
310 \r
311 void CLocatorBar::OnMouseMove(UINT nFlags, CPoint point)\r
312 {\r
313         m_MousePos = point;\r
314         if (!m_bMouseWithin)\r
315         { \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
322         }\r
323 \r
324         if (nFlags & MK_LBUTTON)\r
325         {\r
326                 CRect rect;\r
327                 GetClientRect(rect); \r
328                 int nLine = point.y*m_nLines/rect.Height();\r
329 \r
330                 if (nLine < 0)\r
331                         nLine = 0;\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
338         }\r
339         Invalidate();\r
340 }\r
341 \r
342 LRESULT CLocatorBar::OnMouseLeave(WPARAM, LPARAM)\r
343 {\r
344         m_bMouseWithin = FALSE;\r
345         Invalidate();\r
346         return 0;\r
347\r
348 \r
349 \r
350 \r