Fixed issue #3770: TortoiseGitMerge can't apply NonANSI (e.g., UTF-8) patch
[TortoiseGit.git] / src / TortoiseIDiff / PicWindow.h
blobe86b14434276f6ba0231847da35e43937d79de13
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.
20 #pragma once
21 #include <CommCtrl.h>
22 #include "BaseWindow.h"
23 #include "TortoiseIDiff.h"
24 #include "Picture.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
46 #ifndef GET_X_LPARAM
47 #define GET_X_LPARAM(lp) static_cast<int>(static_cast<short>(LOWORD(lp)))
48 #endif
49 #ifndef GET_Y_LPARAM
50 #define GET_Y_LPARAM(lp) static_cast<int>(static_cast<short>(HIWORD(lp)))
51 #endif
53 /**
54 * \ingroup TortoiseIDiff
55 * The image view window.
56 * Shows an image and provides methods to scale the image or alpha blend it
57 * over another image.
59 class CPicWindow : public CWindow
61 private:
62 CPicWindow() : CWindow(nullptr) {}
63 public:
64 CPicWindow(HINSTANCE hInstance, const WNDCLASSEX* wcx = nullptr) : CWindow(hInstance, wcx)
65 , bValid(false)
66 , nHScrollPos(0)
67 , nVScrollPos(0)
68 , picscale(100)
69 , transparentColor(::GetSysColor(COLOR_WINDOW))
70 , pSecondPic(nullptr)
71 , blendAlpha(0.5f)
72 , bShowInfo(false)
73 , nDimensions(0)
74 , nCurrentDimension(1)
75 , nFrames(0)
76 , nCurrentFrame(1)
77 , bPlaying(false)
78 , pTheOtherPic(nullptr)
79 , bLinkedPositions(true)
80 , bFitWidths(false)
81 , bFitHeights(false)
82 , bOverlap(false)
83 , m_blend(BLEND_ALPHA)
84 , bMainPic(false)
85 , bFirstpaint(false)
86 , nVSecondScrollPos(0)
87 , nHSecondScrollPos(0)
88 , startVScrollPos(0)
89 , startHScrollPos(0)
90 , startVSecondScrollPos(0)
91 , startHSecondScrollPos(0)
92 , hwndTT(0)
93 , hwndTrack(0)
94 , hwndLeftBtn(0)
95 , hwndRightBtn(0)
96 , hwndPlayBtn(0)
97 , hwndSelectBtn(0)
98 , hwndAlphaToggleBtn(0)
99 , hLeft(0)
100 , hRight(0)
101 , hPlay(0)
102 , hStop(0)
103 , hAlphaToggle(0)
104 , m_linkedWidth(0)
105 , m_linkedHeight(0)
106 , bDragging(false)
107 , bSelectionMode(false)
108 , m_themeCallbackId(0)
110 SetWindowTitle(L"Picture Window");
111 m_lastTTPos.x = 0;
112 m_lastTTPos.y = 0;
113 m_wszTip[0] = 0;
114 m_szTip[0] = 0;
115 ptPanStart.x = -1;
116 ptPanStart.y = -1;
117 m_inforect.left = 0;
118 m_inforect.right = 0;
119 m_inforect.bottom = 0;
120 m_inforect.top = 0;
123 enum BlendType
125 BLEND_ALPHA,
126 BLEND_XOR,
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;
140 pictitle2 = sectit;
141 picpath2 = secpath;
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)
153 m_blend = type;
154 blendAlpha = a;
155 if (m_AlphaSlider.IsValid())
156 SendMessage(m_AlphaSlider.GetWindow(), TBM_SETPOS, 1, static_cast<LPARAM>(a * 16.0f));
157 PositionTrackBar();
158 InvalidateRect(*this, nullptr, FALSE);
160 /// Toggle the alpha blending value
161 void ToggleAlpha()
163 if( 0.0f != GetBlendAlpha() )
164 SetBlendAlpha(m_blend, 0.0f);
165 else
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
175 void CenterImage();
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);
206 protected:
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
229 void NextImage();
230 /// go back to the previous image in the file
231 void PrevImage();
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];
270 char m_szTip[8192];
271 POINT m_lastTTPos;
272 HWND hwndTT;
273 HWND hwndTrack;
274 bool bSelectionMode; ///< true if TortoiseIDiff is in selection mode, used to resolve conflicts
275 int m_themeCallbackId;
276 // scrollbar info
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
287 UINT nDimensions;
288 UINT nCurrentDimension;
289 UINT nFrames;
290 UINT nCurrentFrame;
292 // controls
293 HWND hwndLeftBtn;
294 HWND hwndRightBtn;
295 HWND hwndPlayBtn;
296 HWND hwndSelectBtn;
297 CNiceTrackbar m_AlphaSlider;
298 HWND hwndAlphaToggleBtn;
299 CAutoIcon hLeft;
300 CAutoIcon hRight;
301 CAutoIcon hPlay;
302 CAutoIcon hStop;
303 CAutoIcon hAlphaToggle;
304 bool bPlaying;
305 RECT m_inforect;
307 // linked image sizes/positions
308 long m_linkedWidth;
309 long m_linkedHeight;