[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: TortoiseIDiff alpha undo/toggle

From: Rick Yorgason <rick_at_firefang.com>
Date: 2007-02-06 18:40:46 CET

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

This is an archived mail posted to the TortoiseSVN Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.