1
// TortoiseIDiff - an image diff viewer in TortoiseSVN
3 // Copyright (C) 2020, 2023 - TortoiseGit
4 // Copyright (C) 2006-2010, 2012-2016, 2020 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "BaseWindow.h"
23 #include "TortoiseIDiff.h"
25 #include "NiceTrackbar.h"
27 #define HEADER_HEIGHT 30
29 #define ID_ANIMATIONTIMER 100
30 #define TIMER_ALPHASLIDER 101
31 #define ID_ALPHATOGGLETIMER 102
33 #define LEFTBUTTON_ID 101
34 #define RIGHTBUTTON_ID 102
35 #define PLAYBUTTON_ID 103
36 #define ALPHATOGGLEBUTTON_ID 104
37 #define BLENDALPHA_ID 105
38 #define BLENDXOR_ID 106
39 #define SELECTBUTTON_ID 107
41 #define TRACKBAR_ID 101
42 #define SLIDER_HEIGHT 30
43 #define SLIDER_WIDTH 30
47 #define GET_X_LPARAM(lp) static_cast<int>(static_cast<short>(LOWORD(lp)))
50 #define GET_Y_LPARAM(lp) static_cast<int>(static_cast<short>(HIWORD(lp)))
54 * \ingroup TortoiseIDiff
55 * The image view window.
56 * Shows an image and provides methods to scale the image or alpha blend it
59 class CPicWindow
: public CWindow
62 CPicWindow() : CWindow(nullptr)
63 , transparentColor(::GetSysColor(COLOR_WINDOW
))
69 CPicWindow(HINSTANCE hInstance
, const WNDCLASSEX
* wcx
= nullptr) : CWindow(hInstance
, wcx
)
70 , transparentColor(::GetSysColor(COLOR_WINDOW
))
72 SetWindowTitle(L
"Picture Window");
82 /// Registers the window class and creates the window
83 bool RegisterAndCreateWindow(HWND hParent
);
85 /// Sets the image path and title to show
86 void SetPic(const std::wstring
& path
, const std::wstring
& title
, bool bFirst
);
87 /// Returns the CPicture image object. Used to get an already loaded image
88 /// object without having to load it again.
89 CPicture
* GetPic() {return &picture
;}
90 /// Sets the path and title of the second image which is alpha blended over the original
91 void SetSecondPic(CPicture
* pPicture
= nullptr, const std::wstring
& sectit
= L
"", const std::wstring
& secpath
= L
"", int hpos
= 0, int vpos
= 0)
93 pSecondPic
= pPicture
;
96 nVSecondScrollPos
= vpos
;
97 nHSecondScrollPos
= hpos
;
100 void StopTimer() {KillTimer(*this, ID_ANIMATIONTIMER
);}
102 /// Returns the currently used alpha blending value (0.0-1.0)
103 float GetBlendAlpha() const { return blendAlpha
; }
104 /// Sets the alpha blending value
105 void SetBlendAlpha(BlendType type
, float a
)
109 if (m_AlphaSlider
.IsValid())
110 SendMessage(m_AlphaSlider
.GetWindow(), TBM_SETPOS
, 1, static_cast<LPARAM
>(a
* 16.0f
));
112 InvalidateRect(*this, nullptr, FALSE
);
114 /// Toggle the alpha blending value
117 if( 0.0f
!= GetBlendAlpha() )
118 SetBlendAlpha(m_blend
, 0.0f
);
120 SetBlendAlpha(m_blend
, 1.0f
);
123 /// Set the color that this PicWindow will display behind transparent images.
124 void SetTransparentColor(COLORREF back
) { transparentColor
= back
; InvalidateRect(*this, nullptr, false); }
126 /// Resizes the image to fit into the window. Small images are not enlarged.
127 void FitImageInWindow();
128 /// center the image in the view
130 /// forces the widths of the images to be the same
131 void FitWidths(bool bFit
);
132 /// forces the heights of the images to be the same
133 void FitHeights(bool bFit
);
134 /// Sets the zoom factor of the image
135 void SetZoom(int Zoom
, bool centermouse
, bool inzoom
= false);
136 /// Returns the currently used zoom factor in which the image is shown.
137 int GetZoom() const { return picscale
; }
138 /// Zooms in (true) or out (false) in nice steps
139 void Zoom(bool in
, bool centermouse
);
140 /// Sets the 'Other' pic window
141 void SetOtherPicWindow(CPicWindow
* pWnd
) {pTheOtherPic
= pWnd
;}
142 /// Links/Unlinks the two pic windows
143 void LinkPositions(bool bLink
) {bLinkedPositions
= bLink
;}
144 /// Sets the overlay mode info
145 void SetOverlapMode(bool b
) {bOverlap
= b
;}
147 void ShowInfo(bool bShow
= true) { bShowInfo
= bShow
; InvalidateRect(*this, nullptr, false); }
148 /// Sets up the scrollbars as needed
149 void SetupScrollBars();
151 bool HasMultipleImages();
153 int GetHPos() const { return nHScrollPos
; }
154 int GetVPos() const { return nVScrollPos
; }
155 void SetZoomValue(int z
) { picscale
= z
; InvalidateRect(*this, nullptr, FALSE
); }
157 void SetSelectionMode(bool bSelect
= true) { bSelectionMode
= bSelect
; }
158 /// Handles the mouse wheel
159 void OnMouseWheel(short fwKeys
, short zDelta
);
161 /// the message handler for this window
162 LRESULT CALLBACK
WinMsgHandler(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
) override
;
163 /// Draws the view title bar
164 void DrawViewTitle(HDC hDC
, RECT
* rect
);
165 /// Creates the image buttons
166 bool CreateButtons();
167 /// Handles vertical scrolling
168 void OnVScroll(UINT nSBCode
, UINT nPos
);
169 /// Handles horizontal scrolling
170 void OnHScroll(UINT nSBCode
, UINT nPos
);
171 /// Returns the client rectangle, without the scrollbars and the view title.
172 /// Basically the rectangle the image can use.
173 void GetClientRect(RECT
* pRect
);
174 /// Returns the client rectangle, without the view title but with the scrollbars
175 void GetClientRectWithScrollbars(RECT
* pRect
);
176 /// the WM_PAINT function
177 void Paint(HWND hwnd
);
178 /// Draw pic to hdc, with a border, scaled by scale.
179 void ShowPicWithBorder(HDC hdc
, const RECT
&bounds
, CPicture
&pic
, int scale
);
180 /// Positions the buttons
181 void PositionChildren();
182 /// advance to the next image in the file
184 /// go back to the previous image in the file
186 /// starts/stops the animation
187 void Animate(bool bStart
);
188 /// Creates the trackbar (the alpha blending slider control)
189 void CreateTrackbar(HWND hwndParent
);
190 /// Moves the alpha slider trackbar to the correct position
191 void PositionTrackBar();
192 /// creates the info string used in the info box and the tooltips
193 void BuildInfoString(wchar_t* buf
, int size
, bool bTooltip
);
194 /// adjusts the zoom to fit the specified width
195 void SetZoomToWidth(long width
);
196 /// adjusts the zoom to fit the specified height
197 void SetZoomToHeight(long height
);
198 /// sets the dark mode
199 void SetTheme(bool bDark
);
200 /// returns the transparent color, adjusted for theme
201 COLORREF
GetTransparentThemedColor();
203 std::wstring picpath
; ///< the path to the image we show
204 std::wstring pictitle
; ///< the string to show in the image view as a title
205 CPicture picture
; ///< the picture object of the image
206 bool bValid
= false; ///< true if the picture object is valid, i.e. if the image could be loaded and can be shown
207 int picscale
= 100; ///< the scale factor of the image in percent
208 COLORREF transparentColor
; ///< the color to draw under the images
209 bool bFirstpaint
= false; ///< true if the image is painted the first time. Used to initialize some stuff when the window is valid for sure.
210 CPicture
* pSecondPic
= nullptr; ///< if set, this is the picture to draw transparently above the original
211 CPicWindow
* pTheOtherPic
= nullptr; ///< pointer to the other picture window. Used for "linking" the two windows when scrolling/zooming/...
212 bool bMainPic
= false; ///< if true, this is the first image
213 bool bLinkedPositions
= true; ///< if true, the two image windows are linked together for scrolling/zooming/...
214 bool bFitWidths
= false; ///< if true, the two image windows are shown with the same width
215 bool bFitHeights
= false; ///< if true, the two image windows are shown with the same height
216 bool bOverlap
= false; ///< true if the overlay mode is active
217 bool bDragging
= false; ///< indicates an ongoing dragging operation
218 BlendType m_blend
= BlendType::Alpha
; ///< type of blending to use
219 std::wstring pictitle2
; ///< the title of the second picture
220 std::wstring picpath2
; ///< the path of the second picture
221 float blendAlpha
= 0.5f
; ///<the alpha value for transparency blending
222 bool bShowInfo
= false; ///< true if the info rectangle of the image should be shown
223 wchar_t m_wszTip
[8192];
226 HWND hwndTT
= nullptr;
227 HWND hwndTrack
= nullptr;
228 bool bSelectionMode
= false; ///< true if TortoiseIDiff is in selection mode, used to resolve conflicts
229 int m_themeCallbackId
= 0;
231 int nVScrollPos
= 0; ///< vertical scroll position
232 int nHScrollPos
= 0; ///< horizontal scroll position
233 int nVSecondScrollPos
= 0; ///< vertical scroll position of second pic at the moment of enabling overlap mode
234 int nHSecondScrollPos
= 0; ///< horizontal scroll position of second pic at the moment of enabling overlap mode
235 POINT ptPanStart
{ -1, -1 }; ///< the point of the last mouse click
236 int startVScrollPos
= 0; ///< the vertical scroll position when panning starts
237 int startHScrollPos
= 0; ///< the horizontal scroll position when panning starts
238 int startVSecondScrollPos
= 0; ///< the vertical scroll position of the second pic when panning starts
239 int startHSecondScrollPos
= 0; ///< the horizontal scroll position of the second pic when panning starts
240 // image frames/dimensions
241 UINT nDimensions
= 0;
242 UINT nCurrentDimension
= 1;
244 UINT nCurrentFrame
= 1;
247 HWND hwndLeftBtn
= nullptr;
248 HWND hwndRightBtn
= nullptr;
249 HWND hwndPlayBtn
= nullptr;
250 HWND hwndSelectBtn
= nullptr;
251 CNiceTrackbar m_AlphaSlider
;
252 HWND hwndAlphaToggleBtn
= nullptr;
257 CAutoIcon hAlphaToggle
;
258 bool bPlaying
= false;
261 // linked image sizes/positions
262 long m_linkedWidth
= 0;
263 long m_linkedHeight
= 0;