1
// TortoiseIDiff - an image diff viewer in TortoiseSVN
3 // Copyright (C) 2020 - 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) {}
64 CPicWindow(HINSTANCE hInstance
, const WNDCLASSEX
* wcx
= nullptr) : CWindow(hInstance
, wcx
)
69 , transparentColor(::GetSysColor(COLOR_WINDOW
))
74 , nCurrentDimension(1)
78 , pTheOtherPic(nullptr)
79 , bLinkedPositions(true)
83 , m_blend(BLEND_ALPHA
)
86 , nVSecondScrollPos(0)
87 , nHSecondScrollPos(0)
90 , startVSecondScrollPos(0)
91 , startHSecondScrollPos(0)
98 , hwndAlphaToggleBtn(0)
107 , bSelectionMode(false)
108 , m_themeCallbackId(0)
110 SetWindowTitle(L
"Picture Window");
118 m_inforect
.right
= 0;
119 m_inforect
.bottom
= 0;
128 /// Registers the window class and creates the window
129 bool RegisterAndCreateWindow(HWND hParent
);
131 /// Sets the image path and title to show
132 void SetPic(const std::wstring
& path
, const std::wstring
& title
, bool bFirst
);
133 /// Returns the CPicture image object. Used to get an already loaded image
134 /// object without having to load it again.
135 CPicture
* GetPic() {return &picture
;}
136 /// Sets the path and title of the second image which is alpha blended over the original
137 void SetSecondPic(CPicture
* pPicture
= nullptr, const std::wstring
& sectit
= L
"", const std::wstring
& secpath
= L
"", int hpos
= 0, int vpos
= 0)
139 pSecondPic
= pPicture
;
142 nVSecondScrollPos
= vpos
;
143 nHSecondScrollPos
= hpos
;
146 void StopTimer() {KillTimer(*this, ID_ANIMATIONTIMER
);}
148 /// Returns the currently used alpha blending value (0.0-1.0)
149 float GetBlendAlpha() const { return blendAlpha
; }
150 /// Sets the alpha blending value
151 void SetBlendAlpha(BlendType type
, float a
)
155 if (m_AlphaSlider
.IsValid())
156 SendMessage(m_AlphaSlider
.GetWindow(), TBM_SETPOS
, 1, static_cast<LPARAM
>(a
* 16.0f
));
158 InvalidateRect(*this, nullptr, FALSE
);
160 /// Toggle the alpha blending value
163 if( 0.0f
!= GetBlendAlpha() )
164 SetBlendAlpha(m_blend
, 0.0f
);
166 SetBlendAlpha(m_blend
, 1.0f
);
169 /// Set the color that this PicWindow will display behind transparent images.
170 void SetTransparentColor(COLORREF back
) { transparentColor
= back
; InvalidateRect(*this, nullptr, false); }
172 /// Resizes the image to fit into the window. Small images are not enlarged.
173 void FitImageInWindow();
174 /// center the image in the view
176 /// forces the widths of the images to be the same
177 void FitWidths(bool bFit
);
178 /// forces the heights of the images to be the same
179 void FitHeights(bool bFit
);
180 /// Sets the zoom factor of the image
181 void SetZoom(int Zoom
, bool centermouse
, bool inzoom
= false);
182 /// Returns the currently used zoom factor in which the image is shown.
183 int GetZoom() const { return picscale
; }
184 /// Zooms in (true) or out (false) in nice steps
185 void Zoom(bool in
, bool centermouse
);
186 /// Sets the 'Other' pic window
187 void SetOtherPicWindow(CPicWindow
* pWnd
) {pTheOtherPic
= pWnd
;}
188 /// Links/Unlinks the two pic windows
189 void LinkPositions(bool bLink
) {bLinkedPositions
= bLink
;}
190 /// Sets the overlay mode info
191 void SetOverlapMode(bool b
) {bOverlap
= b
;}
193 void ShowInfo(bool bShow
= true) { bShowInfo
= bShow
; InvalidateRect(*this, nullptr, false); }
194 /// Sets up the scrollbars as needed
195 void SetupScrollBars();
197 bool HasMultipleImages();
199 int GetHPos() const { return nHScrollPos
; }
200 int GetVPos() const { return nVScrollPos
; }
201 void SetZoomValue(int z
) { picscale
= z
; InvalidateRect(*this, nullptr, FALSE
); }
203 void SetSelectionMode(bool bSelect
= true) { bSelectionMode
= bSelect
; }
204 /// Handles the mouse wheel
205 void OnMouseWheel(short fwKeys
, short zDelta
);
207 /// the message handler for this window
208 LRESULT CALLBACK
WinMsgHandler(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
) override
;
209 /// Draws the view title bar
210 void DrawViewTitle(HDC hDC
, RECT
* rect
);
211 /// Creates the image buttons
212 bool CreateButtons();
213 /// Handles vertical scrolling
214 void OnVScroll(UINT nSBCode
, UINT nPos
);
215 /// Handles horizontal scrolling
216 void OnHScroll(UINT nSBCode
, UINT nPos
);
217 /// Returns the client rectangle, without the scrollbars and the view title.
218 /// Basically the rectangle the image can use.
219 void GetClientRect(RECT
* pRect
);
220 /// Returns the client rectangle, without the view title but with the scrollbars
221 void GetClientRectWithScrollbars(RECT
* pRect
);
222 /// the WM_PAINT function
223 void Paint(HWND hwnd
);
224 /// Draw pic to hdc, with a border, scaled by scale.
225 void ShowPicWithBorder(HDC hdc
, const RECT
&bounds
, CPicture
&pic
, int scale
);
226 /// Positions the buttons
227 void PositionChildren();
228 /// advance to the next image in the file
230 /// go back to the previous image in the file
232 /// starts/stops the animation
233 void Animate(bool bStart
);
234 /// Creates the trackbar (the alpha blending slider control)
235 void CreateTrackbar(HWND hwndParent
);
236 /// Moves the alpha slider trackbar to the correct position
237 void PositionTrackBar();
238 /// creates the info string used in the info box and the tooltips
239 void BuildInfoString(wchar_t* buf
, int size
, bool bTooltip
);
240 /// adjusts the zoom to fit the specified width
241 void SetZoomToWidth(long width
);
242 /// adjusts the zoom to fit the specified height
243 void SetZoomToHeight(long height
);
244 /// sets the dark mode
245 void SetTheme(bool bDark
);
246 /// returns the transparent color, adjusted for theme
247 COLORREF
GetTransparentThemedColor();
249 std::wstring picpath
; ///< the path to the image we show
250 std::wstring pictitle
; ///< the string to show in the image view as a title
251 CPicture picture
; ///< the picture object of the image
252 bool bValid
; ///< true if the picture object is valid, i.e. if the image could be loaded and can be shown
253 int picscale
; ///< the scale factor of the image in percent
254 COLORREF transparentColor
; ///< the color to draw under the images
255 bool bFirstpaint
; ///< true if the image is painted the first time. Used to initialize some stuff when the window is valid for sure.
256 CPicture
* pSecondPic
; ///< if set, this is the picture to draw transparently above the original
257 CPicWindow
* pTheOtherPic
; ///< pointer to the other picture window. Used for "linking" the two windows when scrolling/zooming/...
258 bool bMainPic
; ///< if true, this is the first image
259 bool bLinkedPositions
; ///< if true, the two image windows are linked together for scrolling/zooming/...
260 bool bFitWidths
; ///< if true, the two image windows are shown with the same width
261 bool bFitHeights
; ///< if true, the two image windows are shown with the same height
262 bool bOverlap
; ///< true if the overlay mode is active
263 bool bDragging
; ///< indicates an ongoing dragging operation
264 BlendType m_blend
; ///< type of blending to use
265 std::wstring pictitle2
; ///< the title of the second picture
266 std::wstring picpath2
; ///< the path of the second picture
267 float blendAlpha
; ///<the alpha value for transparency blending
268 bool bShowInfo
; ///< true if the info rectangle of the image should be shown
269 wchar_t m_wszTip
[8192];
274 bool bSelectionMode
; ///< true if TortoiseIDiff is in selection mode, used to resolve conflicts
275 int m_themeCallbackId
;
277 int nVScrollPos
; ///< vertical scroll position
278 int nHScrollPos
; ///< horizontal scroll position
279 int nVSecondScrollPos
; ///< vertical scroll position of second pic at the moment of enabling overlap mode
280 int nHSecondScrollPos
; ///< horizontal scroll position of second pic at the moment of enabling overlap mode
281 POINT ptPanStart
; ///< the point of the last mouse click
282 int startVScrollPos
; ///< the vertical scroll position when panning starts
283 int startHScrollPos
; ///< the horizontal scroll position when panning starts
284 int startVSecondScrollPos
; ///< the vertical scroll position of the second pic when panning starts
285 int startHSecondScrollPos
; ///< the horizontal scroll position of the second pic when panning starts
286 // image frames/dimensions
288 UINT nCurrentDimension
;
297 CNiceTrackbar m_AlphaSlider
;
298 HWND hwndAlphaToggleBtn
;
303 CAutoIcon hAlphaToggle
;
307 // linked image sizes/positions