[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-04 21:56:19 CET

Okay, I've created a custom control like the one you had described, with
two 'markers' to set the min and max alpha values. The alpha value can
also still be dragged without adjusting these two markers.

It's a fair bit of code added in the AlphaControl.cpp/h files, but I
kept the interface similar to the old slider control, so the rest of the
files haven't changed much.

Let me know what you think.

-Rick-

Index: AlphaControl.cpp
===================================================================
--- AlphaControl.cpp (revision 0)
+++ AlphaControl.cpp (revision 0)
@@ -0,0 +1,455 @@
+// 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_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);
+
+ // Draw outline
+ SelectObject(hdc, GetStockObject(BLACK_PEN));
+ 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 nOld = rectGuage.top;
+ rectGuage.top = nThreshold;
+ FillRect(hdc, &rectGuage, (HBRUSH) (COLOR_HIGHLIGHT+1));
+ rectGuage.top = nOld;
+ }
+
+ // 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, true);
+ }
+
+ 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;
+}
\ No newline at end of file
Index: AlphaControl.h
===================================================================
--- AlphaControl.h (revision 0)
+++ 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
+};
\ No newline at end of file
Index: MainWindow.cpp
===================================================================
--- MainWindow.cpp (revision 8642)
+++ 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: PicWindow.cpp
===================================================================
--- PicWindow.cpp (revision 8642)
+++ 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)
         {
@@ -1037,13 +1026,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 +1041,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: PicWindow.h
===================================================================
--- PicWindow.h (revision 8642)
+++ 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
Index: TortoiseIDiff.cpp
===================================================================
--- TortoiseIDiff.cpp (revision 8642)
+++ 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);
Index: TortoiseIDiff.vcproj
===================================================================
--- TortoiseIDiff.vcproj (revision 8642)
+++ 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 Sun Feb 4 21:56:38 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.