Upgrade libgit2
[TortoiseGit.git] / src / TortoiseIDiff / NiceTrackbar.cpp
blobd5d3b5ef3e138215fbe440d7a75b0a0f391d65e1
1 // TortoiseIDiff - an image diff viewer in TortoiseSVN
3 // Copyright (C) 2006-2008, 2011 - 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 "NiceTrackbar.h"
21 #include <CommCtrl.h>
22 #include <WindowsX.h>
25 LRESULT CALLBACK CNiceTrackbar::NiceTrackbarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
27 auto self = reinterpret_cast<CNiceTrackbar*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
29 switch (message) {
30 case WM_LBUTTONDOWN:
31 self->m_Dragging = true;
32 self->m_DragChanged = false;
33 SetCapture(hwnd);
34 //SetFocus(hwnd);
35 if (self->SetThumb(lParam)) {
36 self->m_DragChanged = true;
37 self->PostMessageToParent(TB_THUMBTRACK);
39 return 0;
40 case WM_MOUSEMOVE:
41 if (self->m_Dragging)
43 if (self->SetThumb(lParam))
45 self->m_DragChanged = true;
46 self->PostMessageToParent(TB_THUMBTRACK);
48 return 0;
50 break;
51 case WM_LBUTTONUP:
52 if (self->m_Dragging)
54 self->m_Dragging = false;
55 ReleaseCapture();
56 if (self->SetThumb(lParam))
58 self->PostMessageToParent(TB_ENDTRACK);
59 self->m_DragChanged = true;
61 if (self->m_DragChanged)
63 self->PostMessageToParent(TB_THUMBPOSITION);
64 self->m_DragChanged = false;
66 return 0;
68 break;
69 case WM_CAPTURECHANGED:
70 if (self->m_Dragging)
72 self->m_Dragging = false;
73 return 0;
75 break;
76 case WM_DESTROY:
77 SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(self->m_OrigProc));
78 break;
80 return CallWindowProc (self->m_OrigProc, hwnd, message, wParam, lParam);
84 void CNiceTrackbar::ConvertTrackbarToNice( HWND window )
86 m_Window = window;
88 // setup this pointer
89 SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
91 // subclass it
92 m_OrigProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(NiceTrackbarProc)));
96 bool CNiceTrackbar::SetThumb (LPARAM lparamPoint)
98 POINT point = { GET_X_LPARAM(lparamPoint), GET_Y_LPARAM(lparamPoint) };
99 const int nMin = static_cast<int>(SendMessage(m_Window, TBM_GETRANGEMIN, 0, 0l));
100 const int nMax = static_cast<int>(SendMessage(m_Window, TBM_GETRANGEMAX, 0, 0l));
101 RECT rc;
102 SendMessage(m_Window, TBM_GETCHANNELRECT, 0, reinterpret_cast<LPARAM>(&rc));
103 double ratio;
104 if (GetWindowLong(m_Window, GWL_STYLE) & TBS_VERT)
106 // note: for vertical trackbar, it still returns the rectangle as if it was horizontal
107 ratio = static_cast<double>(point.y - rc.left)/(rc.right - rc.left);
109 else
111 ratio = static_cast<double>(point.x - rc.left)/(rc.right - rc.left);
114 int nNewPos = static_cast<int>(nMin + (nMax-nMin) * ratio + 0.5); // round the result to go to the nearest tick mark
116 const bool changed = (nNewPos != static_cast<int>(SendMessage(m_Window, TBM_GETPOS, 0, 0)));
117 if (changed)
119 SendMessage(m_Window, TBM_SETPOS, TRUE, nNewPos);
121 return changed;
125 void CNiceTrackbar::PostMessageToParent (int tbCode) const
127 HWND parent = GetParent(m_Window);
128 if (parent)
130 int pos = static_cast<int>(SendMessage(m_Window, TBM_GETPOS, 0, 0));
131 bool vert = (GetWindowLong(m_Window, GWL_STYLE) & TBS_VERT) != 0;
132 PostMessage( parent, vert ? WM_VSCROLL : WM_HSCROLL, ((pos << 16) | tbCode), reinterpret_cast<LPARAM>(m_Window) );