Okay, it turns out most of the problem was because the picture window
wasn't masking out the slider when it redrew, so this problem also
existed before I replaced the slider, and that's why the toggle button
flickered. (That's my way of saying "Not my fault" >;) )
Anyway, all fixed now. The attached patch includes all the changes from
the last patch.
-Rick-
Index: src/TortoiseIDiff/AlphaControl.cpp
===================================================================
--- src/TortoiseIDiff/AlphaControl.cpp (revision 0)
+++ src/TortoiseIDiff/AlphaControl.cpp (revision 0)
@@ -0,0 +1,485 @@
+// TortoiseIDiff - an image diff viewer in TortoiseSVN
+
+// Copyright (C) 2007 - Stefan Kueng
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+
+#include "stdafx.h"
+#include "AlphaControl.h"
+#include <vector>
+#include "commctrl.h"
+
+CAlphaControl::CAlphaControl(HWND hwndControl)
+ : hwndControl(hwndControl)
+ , nBorder(8)
+ , nMin(0)
+ , nMax(255)
+ , nCurr(128)
+ , eTracking(TRACKING_NONE)
+ , nLeftMarker(nMax)
+ , nRightMarker(nMin)
+{
+ SetWindowLong(hwndControl, 0, (LONG)this);
+}
+
+void CAlphaControl::RegisterCustomControl()
+{
+ WNDCLASSEX wc;
+
+ wc.cbSize = sizeof(wc);
+ wc.lpszClassName = sCAlphaControl;
+ wc.hInstance = GetModuleHandle(0);
+ wc.lpfnWndProc = stMsgHandler;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hIcon = 0;
+ wc.lpszMenuName = 0;
+ wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
+ wc.style = 0;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = sizeof(CAlphaControl*);
+ wc.hIconSm = 0;
+
+ RegisterClassEx(&wc);
+}
+
+LRESULT CALLBACK CAlphaControl::stMsgHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ CAlphaControl* pSelf = (CAlphaControl*)GetWindowLong(hwnd, 0);
+
+ switch(msg)
+ {
+ // Allocate new class for this window.
+ case WM_NCCREATE:
+ pSelf = new CAlphaControl(hwnd);
+ return (pSelf != NULL); // This should always be true, since the new
+ // operator *should* throw if there's no memory,
+ // but I think it depends on your compiler settings.
+
+ // Destroy the class for this window.
+ case WM_NCDESTROY:
+ delete pSelf;
+ pSelf = NULL;
+ break;
+ };
+
+ if(pSelf)
+ return pSelf->MsgHandler(hwnd, msg, wParam, lParam);
+ else
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+LRESULT CAlphaControl::MsgHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_SIZE:
+ Size(LOWORD(lParam), HIWORD(lParam));
+ break; // We still want the defwindowproc to do its thing
+ case WM_PAINT:
+ return Paint();
+ case WM_ERASEBKGND:
+ return 1;
+ case WM_MOUSEMOVE:
+ return MouseMove(LOWORD(lParam), HIWORD(lParam));
+ case WM_LBUTTONDOWN:
+ return LButtonDown(LOWORD(lParam), HIWORD(lParam));
+ case WM_LBUTTONUP:
+ return LButtonUp(LOWORD(lParam), HIWORD(lParam));
+ case TBM_GETPOS:
+ return nCurr;
+ case TBM_SETPOS:
+ SetPos(lParam, wParam ? true : false);
+ return 0;
+ case ALPHA_GETLEFTPOS:
+ return nLeftMarker;
+ case ALPHA_GETRIGHTPOS:
+ return nRightMarker;
+ }
+
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+void CAlphaControl::Size(UINT x, UINT y)
+{
+ // Get rectangle for control
+ rectGuage.left = nBorder;
+ rectGuage.top = nBorder;
+ rectGuage.right = x - nBorder;
+ rectGuage.bottom = y - nBorder;
+
+ // Find the pixel value of the threshold
+ nThreshold = ValueToPixel(nCurr);
+
+ // Find the pixel values of the markers
+ nLeftMarkerPixel = ValueToPixel(nLeftMarker);
+ nRightMarkerPixel = ValueToPixel(nRightMarker);
+
+ // Get the size that we can fit markers in
+ nMarkerHalfSize = (rectGuage.right - rectGuage.left) / 2;
+ if(nMarkerHalfSize > nBorder) nMarkerHalfSize = nBorder;
+}
+
+void CAlphaControl::SetPos(LONG nVal, bool bRedraw)
+{
+ nCurr = nVal;
+ nThreshold = ValueToPixel(nCurr);
+
+ if(bRedraw)
+ {
+ RECT rectRedraw;
+ GetClientRect(hwndControl, &rectRedraw);
+ InvalidateRect(hwndControl, &rectRedraw, false);
+ }
+}
+
+int CAlphaControl::PixelToValue(int nPixel)
+{
+ return int(float(rectGuage.bottom - nPixel) / (rectGuage.bottom - rectGuage.top) * (nMax - nMin) + nMin);
+}
+
+int CAlphaControl::ValueToPixel(int nValue)
+{
+ return int(rectGuage.bottom - (rectGuage.bottom - rectGuage.top) * (float(nValue - nMin) / (nMax - nMin)));
+}
+
+void CAlphaControl::DrawMarker(HDC& hdc, bool bLeft, UINT nHeight)
+{
+ // Whether the marker is on the left or right, the vertices will be in this pattern:
+ // 2 +----+ 3
+ // | |
+ // 1 + + 4 // One of the vertices on this line will be extruded into a point
+ // | |
+ // 0,6 +----+ 5
+
+ std::vector<POINT> vPoints(7);
+
+ if(bLeft)
+ {
+ vPoints[0].x = rectGuage.left - nMarkerHalfSize;
+ vPoints[0].y = nHeight + nMarkerHalfSize;
+ vPoints[1].x = vPoints[0].x;
+ vPoints[1].y = nHeight;
+ vPoints[2].x = vPoints[0].x;
+ vPoints[2].y = nHeight - nMarkerHalfSize;
+ vPoints[3].x = rectGuage.left;
+ vPoints[3].y = vPoints[2].y;
+ vPoints[4].x = rectGuage.left + nMarkerHalfSize;
+ vPoints[4].y = nHeight;
+ vPoints[5].x = vPoints[3].x;
+ vPoints[5].y = vPoints[0].y;
+ }
+ else
+ {
+ vPoints[0].x = rectGuage.right;
+ vPoints[0].y = nHeight + nMarkerHalfSize;
+ vPoints[1].x = rectGuage.right - nMarkerHalfSize;
+ vPoints[1].y = nHeight;
+ vPoints[2].x = vPoints[0].x;
+ vPoints[2].y = nHeight - nMarkerHalfSize;
+ vPoints[3].x = rectGuage.right + nMarkerHalfSize;
+ vPoints[3].y = vPoints[2].y;
+ vPoints[4].x = vPoints[3].x;
+ vPoints[4].y = nHeight;
+ vPoints[5].x = vPoints[3].x;
+ vPoints[5].y = vPoints[0].y;
+ }
+
+ vPoints[6] = vPoints[0];
+
+ // Fill the marker
+ // This is always the face color, regardless of whether the marker is being tracked or not.
+ // This is because Windows doesn't appear to have an interface to get the checked brush it
+ // usually uses to paint tracked trackbar thumbs.
+ SelectObject(hdc, GetStockObject(DC_BRUSH));
+ SetDCBrushColor(hdc, GetSysColor(COLOR_3DFACE));
+ Polygon(hdc, &vPoints[0], 6);
+
+ // Draw the very light side
+ SelectObject(hdc, GetStockObject(DC_PEN));
+ SetDCPenColor(hdc, GetSysColor(COLOR_3DHIGHLIGHT));
+ Polyline(hdc, &vPoints[0], 4);
+
+ // Draw the very dark side
+ SetDCPenColor(hdc, GetSysColor(COLOR_3DDKSHADOW));
+ Polyline(hdc, &vPoints[3], 4);
+
+ // Inset the vertices by one pixel
+ vPoints[0].y--;
+ vPoints[1].x++;
+ vPoints[2].y++;
+ vPoints[3].y++;
+ vPoints[4].x--;
+ vPoints[5].y--;
+ if(bLeft)
+ {
+ vPoints[0].x++;
+ vPoints[2].x++;
+ }
+ else
+ {
+ vPoints[3].x--;
+ vPoints[5].x--;
+ }
+ vPoints[6] = vPoints[0];
+
+ // Draw the slightly light side
+ SetDCPenColor(hdc, GetSysColor(COLOR_3DLIGHT));
+ Polyline(hdc, &vPoints[0], 4);
+
+ // Draw the slightly dark side
+ SetDCPenColor(hdc, GetSysColor(COLOR_3DSHADOW));
+ Polyline(hdc, &vPoints[3], 4);
+}
+
+LRESULT CAlphaControl::Paint()
+{
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwndControl, &ps);
+
+ RECT rectClient;
+ GetClientRect(hwndControl, &rectClient);
+
+ // Draw background
+ {
+ RECT rectBackground;
+ rectBackground.left = rectBackground.top = 0;
+ rectBackground.right = rectClient.right;
+ rectBackground.bottom = rectGuage.top;
+ FillRect(hdc, &rectBackground, (HBRUSH) (COLOR_BTNFACE+1));
+ rectBackground.top = rectGuage.bottom;
+ rectBackground.bottom = rectClient.bottom;
+ FillRect(hdc, &rectBackground, (HBRUSH) (COLOR_BTNFACE+1));
+ rectBackground.top = rectGuage.top;
+ rectBackground.bottom = rectGuage.bottom;
+ rectBackground.right = rectGuage.left;
+ FillRect(hdc, &rectBackground, (HBRUSH) (COLOR_BTNFACE+1));
+ rectBackground.left = rectGuage.right;
+ rectBackground.right = rectClient.right;
+ FillRect(hdc, &rectBackground, (HBRUSH) (COLOR_BTNFACE+1));
+ }
+
+ // Draw outline
+ SelectObject(hdc, GetStockObject(BLACK_PEN));
+ SelectObject(hdc, GetStockObject(NULL_BRUSH));
+ Rectangle(hdc, rectGuage.left, rectGuage.top, rectGuage.right, rectGuage.bottom);
+
+ // Inset the rectangle by one pixel
+ rectGuage.left++;
+ rectGuage.top++;
+ rectGuage.right--;
+ rectGuage.bottom--;
+
+ {
+ // Draw percentage
+ LONG nOldTop = rectGuage.top, nOldBottom = rectGuage.bottom;
+ rectGuage.top = nThreshold;
+ FillRect(hdc, &rectGuage, (HBRUSH) (COLOR_HIGHLIGHT+1));
+
+ // Draw blank space
+ rectGuage.bottom = rectGuage.top;
+ rectGuage.top = nOldTop;
+ FillRect(hdc, &rectGuage, (HBRUSH) (COLOR_WINDOW+1));
+ rectGuage.bottom = nOldBottom;
+ }
+
+ // Restore the top and bottom sides of the rect
+ rectGuage.top--;
+ rectGuage.bottom++;
+
+ // Draw guage marks
+ {
+ LONG nOneThird = LONG((rectGuage.right - rectGuage.left) / 3.0f);
+ LONG nTwoThird = rectGuage.right - nOneThird;
+ nOneThird += rectGuage.left;
+ for(int nEights = 1; nEights < 8; nEights++)
+ {
+ UINT nHeight = UINT(ValueToPixel(int((nEights / 8.0f) * (nMax - nMin) + nMin)));
+
+ // Invert the pen depending on the percentage drawn
+ if(nHeight < nThreshold)
+ SelectObject(hdc, GetStockObject(BLACK_PEN));
+ else
+ SelectObject(hdc, GetStockObject(WHITE_PEN));
+
+ MoveToEx(hdc, rectGuage.left, nHeight, NULL);
+ if(nEights % 2 == 0) // Quarters, draw a solid line
+ {
+ LineTo(hdc, rectGuage.right, nHeight);
+ }
+ else // Eights, draw segmented line
+ {
+ LineTo(hdc, nOneThird, nHeight);
+ MoveToEx(hdc, nTwoThird, nHeight, NULL);
+ LineTo(hdc, rectGuage.right, nHeight);
+ }
+ }
+ }
+
+ // Restore the left and right sides of the rect
+ rectGuage.left--;
+ rectGuage.right++;
+
+ // Draw the markers
+ DrawMarker(hdc, true, nLeftMarkerPixel);
+ DrawMarker(hdc, false, nRightMarkerPixel);
+
+ SelectObject(hdc, GetStockObject(DC_BRUSH));
+
+ EndPaint(hwndControl, &ps);
+
+ return 0;
+}
+
+LRESULT CAlphaControl::MouseMove(UINT x, UINT y)
+{
+ if(eTracking == TRACKING_NONE)
+ {
+ // If the mouse is near the threshold, change it to a vertical-resize cursor
+ if(int(x) > rectGuage.left && int(x) < rectGuage.right && int(y) > nThreshold - 5 && int(y) < nThreshold + 5)
+ SetCursor(LoadCursor(NULL, IDC_SIZENS));
+ else
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+ else
+ {
+ // Do a little binary manipulation to get a negative value if necessary.
+ int nVert = y & 0x7fff;
+ if(y & 0x8000) nVert = -nVert;
+
+ // Calculate the value position of whatever we're dragging
+ if(nVert < rectGuage.top) nVert = rectGuage.top;
+ else if(nVert > rectGuage.bottom) nVert = rectGuage.bottom;
+ UINT nValuePos = PixelToValue(nVert);
+
+ RECT rectInvalidate;
+ rectInvalidate.left = rectGuage.left + 1;
+ rectInvalidate.right = rectGuage.right - 1;
+ rectInvalidate.top = rectInvalidate.bottom = nThreshold;
+
+ if(eTracking == TRACKING_LEFT)
+ {
+ if(nValuePos != nLeftMarker)
+ {
+ nLeftMarker = nValuePos;
+
+ // Find the area to invalidate, and calculate the new marker pos
+ rectInvalidate.left = rectGuage.left - nMarkerHalfSize - 1;
+ rectInvalidate.top = nLeftMarkerPixel;
+ nLeftMarkerPixel = ValueToPixel(nLeftMarker);
+ if(int(nLeftMarkerPixel) > rectInvalidate.top)
+ {
+ rectInvalidate.top -= nMarkerHalfSize;
+ rectInvalidate.bottom = nLeftMarkerPixel + nMarkerHalfSize + 1;
+ }
+ else
+ {
+ rectInvalidate.bottom = rectInvalidate.top + nMarkerHalfSize + 1;
+ rectInvalidate.top = nLeftMarkerPixel - nMarkerHalfSize;
+ }
+ }
+ }
+ else if(eTracking == TRACKING_RIGHT)
+ {
+ if(nValuePos != nRightMarker)
+ {
+ nRightMarker = nValuePos;
+
+ // Find the area to invalidate, and calculate the new marker pos
+ rectInvalidate.right = rectGuage.right + nMarkerHalfSize + 1;
+ rectInvalidate.top = nRightMarkerPixel;
+ nRightMarkerPixel = ValueToPixel(nRightMarker);
+ if(int(nRightMarkerPixel) > rectInvalidate.top)
+ {
+ rectInvalidate.top -= nMarkerHalfSize;
+ rectInvalidate.bottom = nRightMarkerPixel + nMarkerHalfSize + 1;
+ }
+ else
+ {
+ rectInvalidate.bottom = rectInvalidate.top + nMarkerHalfSize + 1;
+ rectInvalidate.top = nRightMarkerPixel - nMarkerHalfSize;
+ }
+ }
+ }
+
+ // Always update the guage, no matter what we're dragging
+ if(nValuePos != nCurr)
+ {
+ nCurr = nValuePos;
+ SetCursor(LoadCursor(NULL, IDC_SIZENS));
+
+ // Find the area to invalidate, and calculate the new threshold
+ UINT nTemp = ValueToPixel(nCurr);
+ if(nTemp > nThreshold)
+ {
+ if(int(nTemp) > rectInvalidate.bottom) rectInvalidate.bottom = nTemp;
+ if(int(nThreshold) < rectInvalidate.top) rectInvalidate.top = nThreshold;
+ }
+ else
+ {
+ if(int(nTemp) < rectInvalidate.top) rectInvalidate.top = nTemp;
+ if(int(nThreshold) > rectInvalidate.bottom) rectInvalidate.bottom = nThreshold;
+ }
+ nThreshold = nTemp;
+
+ // Send a message to the parent telling them we're moving the value
+ SendMessage(GetParent(hwndControl), WM_VSCROLL, MAKEWPARAM(TB_THUMBTRACK, nCurr), LPARAM(hwndControl));
+ }
+
+ InvalidateRect(hwndControl, &rectInvalidate, false);
+ }
+
+ return 0;
+}
+
+LRESULT CAlphaControl::LButtonDown(UINT x, UINT y)
+{
+ if(eTracking == TRACKING_NONE)
+ {
+ if(x > rectGuage.left - nMarkerHalfSize && x < rectGuage.left + nMarkerHalfSize &&
+ y > nLeftMarkerPixel - nMarkerHalfSize && y < nLeftMarkerPixel + nMarkerHalfSize)
+ {
+ eTracking = TRACKING_LEFT;
+ }
+ else if(x > rectGuage.right - nMarkerHalfSize && x < rectGuage.right + nMarkerHalfSize &&
+ y > nRightMarkerPixel - nMarkerHalfSize && y < nRightMarkerPixel + nMarkerHalfSize)
+ {
+ eTracking = TRACKING_RIGHT;
+ }
+ else if(int(x) > rectGuage.left && int(x) < rectGuage.right && int(y) > rectGuage.top && int(y) < rectGuage.bottom)
+ {
+ eTracking = TRACKING_VALUE;
+ }
+ else
+ return 0; // Exit early
+
+ MouseMove(x, y);
+ SetCapture(hwndControl);
+ }
+ return 0;
+}
+
+LRESULT CAlphaControl::LButtonUp(UINT x, UINT y)
+{
+ MouseMove(x, y);
+ if(eTracking != TRACKING_NONE)
+ {
+ // Send a message to the parent telling them we've moved the value
+ SendMessage(GetParent(hwndControl), WM_VSCROLL, MAKEWPARAM(TB_THUMBPOSITION, nCurr), LPARAM(hwndControl));
+ eTracking = TRACKING_NONE;
+ ReleaseCapture();
+ }
+ return 0;
+}
Index: src/TortoiseIDiff/AlphaControl.h
===================================================================
--- src/TortoiseIDiff/AlphaControl.h (revision 0)
+++ src/TortoiseIDiff/AlphaControl.h (revision 0)
@@ -0,0 +1,85 @@
+// TortoiseIDiff - an image diff viewer in TortoiseSVN
+
+// Copyright (C) 2007 - Stefan Kueng
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+#pragma once
+#include <windows.h>
+#include <tchar.h>
+
+#define ALPHA_GETLEFTPOS WM_USER+1
+#define ALPHA_GETRIGHTPOS WM_USER+2
+
+const TCHAR sCAlphaControl[] = _T("CAlphaControl");
+
+class CAlphaControl
+{
+public:
+ CAlphaControl(HWND hwndControl);
+
+ /// Registers the custom control with Windows. Call this once when the program starts.
+ static void RegisterCustomControl();
+ /// Static message handler to pass off to the non-static handler.
+ static LRESULT CALLBACK stMsgHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ /// Message handler
+ LRESULT MsgHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ /// Resize handler
+ void Size(UINT x, UINT y);
+
+ /// Position change handler
+ void SetPos(LONG nVal, bool bRedraw);
+
+ /// Paint handler
+ LRESULT Paint();
+
+ /// Mouse movement handler
+ LRESULT MouseMove(UINT x, UINT y);
+
+ /// Mouse click handlers
+ LRESULT LButtonDown(UINT x, UINT y);
+ LRESULT LButtonUp(UINT x, UINT y);
+
+private:
+ /// Convert a pixel height to the value the slider would be at that height
+ inline int PixelToValue(int nPixel);
+ /// Convert the value of the slider to the pixel height the threshold would be at
+ inline int ValueToPixel(int nValue);
+ /// Draw a marker
+ void DrawMarker(HDC& hdc, bool bLeft, UINT nHeight);
+
+ HWND hwndControl; ///< Handle to this control
+ UINT nBorder; ///< Size of border around the guage
+ UINT nMin; ///< Minimum value for slider
+ UINT nMax; ///< Maximum value for slider
+ UINT nCurr; ///< Current value for slider
+ RECT rectGuage; ///< Rectangle where the guage is drawn
+ UINT nThreshold; ///< The vertical height in the guage that shows the percentage
+ UINT nLeftMarker; ///< Vertical height of the left marker
+ UINT nLeftMarkerPixel; ///< Vertical pixel height of the left marker
+ UINT nRightMarker; ///< Vertical height of the right marker
+ UINT nRightMarkerPixel; ///< Vertical pixel height of the right marker
+ UINT nMarkerHalfSize; ///< Half the width/height of a marker
+
+ enum
+ {
+ TRACKING_NONE,
+ TRACKING_VALUE,
+ TRACKING_LEFT,
+ TRACKING_RIGHT
+ } eTracking; ///< Which, if any, elements are being tracked
+};
Index: src/TortoiseIDiff/MainWindow.cpp
===================================================================
--- src/TortoiseIDiff/MainWindow.cpp (revision 8641)
+++ src/TortoiseIDiff/MainWindow.cpp (working copy)
@@ -335,7 +335,7 @@
picWindow1.StopTimer();
picWindow2.StopTimer();
picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath);
- picWindow1.SetSecondPicAlpha(127, true);
+ picWindow1.SetSecondPicAlpha(127);
}
else
{
@@ -375,27 +375,16 @@
}
break;
case ID_VIEW_ALPHA0:
- picWindow1.SetSecondPicAlpha(0, true);
+ picWindow1.SetSecondPicAlpha(0);
break;
case ID_VIEW_ALPHA255:
- picWindow1.SetSecondPicAlpha(255, true);
+ picWindow1.SetSecondPicAlpha(255);
break;
case ID_VIEW_ALPHA127:
- picWindow1.SetSecondPicAlpha(127, true);
+ picWindow1.SetSecondPicAlpha(127);
break;
case ID_VIEW_ALPHATOGGLE:
- switch (picWindow1.GetSecondPicAlpha())
- {
- case 0:
- picWindow1.SetSecondPicAlpha(255, false);
- break;
- case 255:
- picWindow1.SetSecondPicAlpha(picWindow1.GetSecondPicAlphaLast(), false);
- break;
- default:
- picWindow1.SetSecondPicAlpha(0, false);
- break;
- }
+ picWindow1.ToggleAlpha();
break;
case ID_VIEW_FITIMAGESINWINDOW:
{
Index: src/TortoiseIDiff/PicWindow.cpp
===================================================================
--- src/TortoiseIDiff/PicWindow.cpp (revision 8641)
+++ src/TortoiseIDiff/PicWindow.cpp (working copy)
@@ -75,7 +75,7 @@
{
case WM_CREATE:
// create a slider control
- hwndAlphaSlider = CreateTrackbar(hwnd, 0, 255);
+ hwndAlphaSlider = CreateTrackbar(hwnd);
ShowWindow(hwndAlphaSlider, SW_HIDE);
break;
case WM_SETFOCUS:
@@ -100,7 +100,7 @@
::SetTimer(*this, TIMER_ALPHASLIDER, 50, NULL);
}
else
- SetSecondPicAlpha((BYTE)SendMessage(hwndAlphaSlider, TBM_GETPOS, 0, 0), true);
+ SetSecondPicAlpha((BYTE)SendMessage(hwndAlphaSlider, TBM_GETPOS, 0, 0));
}
else
{
@@ -229,18 +229,7 @@
break;
case ALPHATOGGLEBUTTON_ID:
{
- switch (GetSecondPicAlpha())
- {
- case 0:
- SetSecondPicAlpha(255, false);
- break;
- case 255:
- SetSecondPicAlpha(GetSecondPicAlphaLast(), false);
- break;
- default:
- SetSecondPicAlpha(0, false);
- break;
- }
+ ToggleAlpha();
return 0;
}
break;
@@ -264,7 +253,7 @@
break;
case TIMER_ALPHASLIDER:
{
- SetSecondPicAlpha((BYTE)SendMessage(hwndAlphaSlider, TBM_GETPOS, 0, 0), false);
+ SetSecondPicAlpha((BYTE)SendMessage(hwndAlphaSlider, TBM_GETPOS, 0, 0));
KillTimer(*this, TIMER_ALPHASLIDER);
}
break;
@@ -606,7 +595,7 @@
alphalive = 255;
if (overflow < 0)
alphalive = 0;
- SetSecondPicAlpha(alphalive, true);
+ SetSecondPicAlpha(alphalive);
}
else if (fwKeys & MK_SHIFT)
{
@@ -779,9 +768,14 @@
HDC hdc;
RECT rect, fullrect;
+
::GetClientRect(*this, &fullrect);
hdc = BeginPaint(hwnd, &ps);
{
+ // Exclude the alpha control and button
+ if(pSecondPic)
+ ExcludeClipRect(hdc, 0, m_inforect.top-4, SLIDER_WIDTH, m_inforect.bottom+4);
+
CMemDC memDC(hdc);
GetClientRect(&rect);
@@ -1037,13 +1031,13 @@
return (((nDimensions > 1)||(nFrames > 1))&&(pSecondPic == NULL));
}
-HWND CPicWindow::CreateTrackbar(HWND hwndParent, UINT iMin, UINT iMax)
+HWND CPicWindow::CreateTrackbar(HWND hwndParent)
{
HWND hwndTrack = CreateWindowEx(
0, // no extended styles
- TRACKBAR_CLASS, // class name
+ sCAlphaControl, // class name
_T("Trackbar Control"), // title (caption)
- WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_TOOLTIPS | TBS_NOTICKS, // style
+ WS_CHILD | WS_VISIBLE, // style
10, 10, // position
200, 30, // size
hwndParent, // parent window
@@ -1052,12 +1046,5 @@
NULL // no WM_CREATE parameter
);
- SendMessage(hwndTrack, TBM_SETRANGE,
- (WPARAM) TRUE, // redraw flag
- (LPARAM) MAKELONG(iMin, iMax)); // min. & max. positions
- SendMessage(hwndTrack, TBM_SETTIPSIDE,
- (WPARAM) TBTS_TOP, // redraw flag
- (LPARAM) 0); // min. & max. positions
-
return hwndTrack;
}
Index: src/TortoiseIDiff/PicWindow.h
===================================================================
--- src/TortoiseIDiff/PicWindow.h (revision 8641)
+++ src/TortoiseIDiff/PicWindow.h (working copy)
@@ -21,6 +21,7 @@
#include "BaseWindow.h"
#include "TortoiseIDiff.h"
#include "Picture.h"
+#include "AlphaControl.h"
#define HEADER_HEIGHT 30
@@ -60,7 +61,6 @@
, picscale(1.0)
, pSecondPic(NULL)
, alphalive(0)
- , alphalast(0)
, bShowInfo(true)
, nDimensions(0)
, nCurrentDimension(1)
@@ -93,20 +93,23 @@
void StopTimer() {KillTimer(*this, ID_ANIMATIONTIMER);}
/// Returns the currently used alpha blending value (0-255)
BYTE GetSecondPicAlpha() {return alphalive;}
- /// Returns the last alpha blending value (0-255)
- BYTE GetSecondPicAlphaLast() {return alphalast;}
/// Sets the alpha blending value
- void SetSecondPicAlpha(BYTE a, bool saveundo)
+ void SetSecondPicAlpha(BYTE a)
{
alphalive = a;
if (hwndAlphaSlider)
SendMessage(hwndAlphaSlider, TBM_SETPOS, (WPARAM)1, (LPARAM)a);
- if (saveundo)
- {
- alphalast = a;
- }
InvalidateRect(*this, NULL, FALSE);
}
+ /// Toggle the alpha between the two markers in the alpha slider control
+ void ToggleAlpha()
+ {
+ UINT nLeft = (BYTE)SendMessage(hwndAlphaSlider, ALPHA_GETLEFTPOS, 0, 0);
+ if(nLeft != GetSecondPicAlpha())
+ SetSecondPicAlpha(nLeft);
+ else
+ SetSecondPicAlpha((BYTE)SendMessage(hwndAlphaSlider, ALPHA_GETRIGHTPOS, 0, 0));
+ }
/// Resizes the image to fit into the window. Small images are not enlarged.
void FitImageInWindow();
/// Sets the zoom factor of the image
@@ -154,7 +157,7 @@
/// starts/stops the animation
void Animate(bool bStart);
/// Creates the trackbar (the alpha blending slider control)
- HWND CreateTrackbar(HWND hwndParent, UINT iMin, UINT iMax);
+ HWND CreateTrackbar(HWND hwndParent);
/// Moves the alpha slider trackbar to the correct position
void PositionTrackBar();
@@ -170,7 +173,6 @@
stdstring pictitle2; ///< the title of the second picture
stdstring picpath2; ///< the path of the second picture
BYTE alphalive; ///< the alpha value for the transparency live-preview of the second picture
- BYTE alphalast; ///< the alpha value previously used for the transparency of the second picture that the user can undo to
bool bShowInfo; ///< true if the info rectangle of the image should be shown
// scrollbar info
int nVScrollPos; ///< vertical scroll position
@@ -198,3 +200,4 @@
};
+
Index: src/TortoiseIDiff/TortoiseIDiff.cpp
===================================================================
--- src/TortoiseIDiff/TortoiseIDiff.cpp (revision 8641)
+++ src/TortoiseIDiff/TortoiseIDiff.cpp (working copy)
@@ -22,6 +22,7 @@
#include "registry.h"
#include "LangDll.h"
#include "TortoiseIDiff.h"
+#include "AlphaControl.h"
#ifndef WIN64
# pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'\"")
@@ -72,6 +73,7 @@
ICC_STANDARD_CLASSES | ICC_BAR_CLASSES
};
InitCommonControlsEx(&used);
+ CAlphaControl::RegisterCustomControl();
// load the cursors we need
curHand = (HCURSOR)LoadImage(hInst, MAKEINTRESOURCE(IDC_PANCUR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
@@ -111,3 +113,4 @@
+
Index: src/TortoiseIDiff/TortoiseIDiff.vcproj
===================================================================
--- src/TortoiseIDiff/TortoiseIDiff.vcproj (revision 8641)
+++ src/TortoiseIDiff/TortoiseIDiff.vcproj (working copy)
@@ -353,6 +353,10 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
+ RelativePath=".\AlphaControl.cpp"
+ >
+ </File>
+ <File
RelativePath=".\BaseWindow.cpp"
>
</File>
@@ -427,6 +431,10 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
+ RelativePath=".\AlphaControl.h"
+ >
+ </File>
+ <File
RelativePath=".\BaseWindow.h"
>
</File>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tortoisesvn.tigris.org
For additional commands, e-mail: dev-help@tortoisesvn.tigris.org
Received on Tue Feb 6 18:40:41 2007