OSDN Git Service

Merge pull request #5 from WinMerge/master
[winmerge-jp/winmerge-jp.git] / Src / EditorFilepathBar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 //    WinMerge:  an interactive diff/merge utility
3 //    Copyright (C) 1997-2000  Thingamahoochie Software
4 //    Author: Dean Grimm
5 //    SPDX-License-Identifier: GPL-2.0-or-later
6 /////////////////////////////////////////////////////////////////////////////
7 /** 
8  * @file  EditorFilepathBar.cpp
9  *
10  * @brief Implementation file for CEditorFilepathBar class
11  */
12
13 #include "stdafx.h"
14 #include "EditorFilepathBar.h"
15
16 #ifdef _DEBUG
17 #define new DEBUG_NEW
18 #endif
19
20
21 BEGIN_MESSAGE_MAP(CEditorFilePathBar, CDialogBar)
22         ON_NOTIFY_EX (TTN_NEEDTEXT, 0, OnToolTipNotify)
23         ON_CONTROL_RANGE (EN_SETFOCUS, IDC_STATIC_TITLE_PANE0, IDC_STATIC_TITLE_PANE2, OnSetFocusEdit)
24 END_MESSAGE_MAP()
25
26
27 /**
28  * @brief Constructor.
29  */
30 CEditorFilePathBar::CEditorFilePathBar()
31 : m_nPanes(2)
32 {
33 }
34
35 /**
36  * @brief Destructor.
37  */
38 CEditorFilePathBar::~CEditorFilePathBar()
39 {
40 }
41
42 /**
43  * @brief Create the window.
44  * This function subclasses the edit controls.
45  * @param [in] pParentWnd Parent window for edit controls.
46  * @return TRUE if succeeded, FALSE otherwise.
47  */
48 BOOL CEditorFilePathBar::Create(CWnd* pParentWnd)
49 {
50         if (! CDialogBar::Create(pParentWnd, CEditorFilePathBar::IDD, 
51                         CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY, CEditorFilePathBar::IDD))
52                 return FALSE;
53
54         NONCLIENTMETRICS ncm = { sizeof NONCLIENTMETRICS };
55         if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof NONCLIENTMETRICS, &ncm, 0))
56                 m_font.CreateFontIndirect(&ncm.lfStatusFont);
57
58         // subclass the two custom edit boxes
59         for (int pane = 0; pane < static_cast<int>(std::size(m_Edit)); pane++)
60         {
61                 m_Edit[pane].SubClassEdit(IDC_STATIC_TITLE_PANE0 + pane, this);
62                 m_Edit[pane].SetFont(&m_font);
63                 m_Edit[pane].SetMargins(4, 4);
64         }
65         return TRUE;
66 };
67
68 CSize CEditorFilePathBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
69 {
70         TEXTMETRIC tm;
71         CClientDC dc(this);
72         CFont *pOldFont = dc.SelectObject(&m_font);
73         dc.GetTextMetrics(&tm);
74         dc.SelectObject(pOldFont);
75         return CSize(SHRT_MAX, tm.tmHeight + 6);
76 }
77
78 /** 
79  * @brief Resize both controls to an equal size.
80  */
81 void CEditorFilePathBar::Resize()
82 {
83         if (m_hWnd == nullptr)
84                 return;
85
86         WINDOWPLACEMENT infoBar;
87         GetWindowPlacement(&infoBar);
88
89         int widths[3];
90         for (int pane = 0; pane < m_nPanes; pane++)
91                 widths[pane] = (infoBar.rcNormalPosition.right / m_nPanes);
92         Resize(widths);
93 }
94
95 /** 
96  * @brief Set widths.
97  * This function resizes both controls to given size. The width is usually
98  * same as the splitter view width.
99  * @param [in] leftWidth Left-side control width.
100  * @param [in] rightWidth Right-side control width.
101  */
102 void CEditorFilePathBar::Resize(int widths[])
103 {
104         if (m_hWnd == nullptr)
105                 return;
106
107         // resize left filename
108         CRect rc;
109         int x = 0;
110         GetClientRect(&rc);
111         for (int pane = 0; pane < m_nPanes; pane++)
112         {
113                 CRect rcOld;
114                 m_Edit[pane].GetClientRect(&rcOld);
115                 rc.left = x;
116                 rc.right = x + widths[pane] + (pane == 0 ? 5 : 7);
117                 x = rc.right;
118                 if (rcOld.Width() != rc.Width())
119                 {
120                         m_Edit[pane].MoveWindow(&rc);
121                         m_Edit[pane].RefreshDisplayText();
122                 }
123         }
124 }
125
126 /**
127  * @brief Called when tooltip is about to be shown.
128  * In this function we set the tooltip text shown.
129  */
130 BOOL CEditorFilePathBar::OnToolTipNotify(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
131 {
132         if (m_hWnd == nullptr)
133                 return FALSE;
134
135         TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;
136         if (pTTT->uFlags & TTF_IDISHWND)
137         {
138                 // idFrom is actually the HWND of the CEdit 
139                 int nID = ::GetDlgCtrlID((HWND)pTTTStruct->idFrom);
140                 if(nID == IDC_STATIC_TITLE_PANE0 || nID == IDC_STATIC_TITLE_PANE1 || nID == IDC_STATIC_TITLE_PANE2)
141                 {
142                         // compute max width : 97% of application width or 80% or full screen width
143                         CRect rect;
144                         GetWindowRect(rect);
145                         int maxWidth = (int)(rect.Width() * .97);
146                         CRect rectScreen; 
147                         SystemParametersInfo(SPI_GETWORKAREA, 0, rectScreen, 0);
148                         if (rectScreen.Width() * .8 > maxWidth)
149                                 maxWidth = (int)(rectScreen.Width() * .8);
150
151                         // use the tooltip font
152                         HANDLE hFont = (HANDLE) ::SendMessage(pTTTStruct->hwndFrom, WM_GETFONT, 0, 0);
153                         CClientDC tempDC(this);
154                         HANDLE hOldFont = ::SelectObject(tempDC.GetSafeHdc(),hFont);
155
156                         // fill in the returned structure
157                         CFilepathEdit * pItem = static_cast<CFilepathEdit*>(GetDlgItem(nID));
158                         pTTT->lpszText = const_cast<TCHAR *>(pItem->GetUpdatedTipText(&tempDC, maxWidth).c_str());
159
160                         // set old font back
161                         if (hOldFont != nullptr)
162                                 ::SelectObject(tempDC.GetSafeHdc(),hOldFont);
163
164                         // we must set TTM_SETMAXTIPWIDTH to use \n in tooltips
165                         // just to do the first time, but how to access the tooltip during init ?
166                         ::SendMessage(pTTTStruct->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 5000);
167
168                         return TRUE;
169                 }
170         }
171         return FALSE;
172 }
173
174 void CEditorFilePathBar::OnSetFocusEdit(UINT id)
175 {
176         if (m_callbackfunc)
177                 m_callbackfunc(id - IDC_STATIC_TITLE_PANE0);
178 }
179
180 /** 
181  * @brief Get the path for one side
182  *
183  * @param [in] pane Index (0-based) of pane to update.
184  */
185 String CEditorFilePathBar::GetText(int pane) const
186 {
187         ASSERT (pane >= 0 && pane < static_cast<int>(std::size(m_Edit)));
188
189         // Check for `nullptr` since window may be closing..
190         if (m_hWnd == nullptr)
191                 return _T("");
192
193         CString str;
194         m_Edit[pane].GetWindowText(str);
195         return String(str);
196 }
197
198 /** 
199  * @brief Set the path for one side
200  *
201  * @param [in] pane Index (0-based) of pane to update.
202  * @param [in] lpszString New text for pane.
203  */
204 void CEditorFilePathBar::SetText(int pane, const String& sString)
205 {
206         ASSERT (pane >= 0 && pane < static_cast<int>(std::size(m_Edit)));
207
208         // Check for `nullptr` since window may be closing..
209         if (m_hWnd == nullptr)
210                 return;
211
212         m_Edit[pane].SetOriginalText(sString);
213 }
214
215 /** 
216  * @brief Set the active status for one status (change the appearance)
217  *
218  * @param [in] pane Index (0-based) of pane to update.
219  * @param [in] bActive If `true` activates pane, `false` deactivates.
220  */
221 void CEditorFilePathBar::SetActive(int pane, bool bActive)
222 {
223         ASSERT (pane >= 0 && pane < static_cast<int>(std::size(m_Edit)));
224
225         // Check for `nullptr` since window may be closing..
226         if (m_hWnd == nullptr)
227                 return;
228
229         m_Edit[pane].SetActive(bActive);
230 }