1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997-2000 Thingamahoochie Software
5 // SPDX-License-Identifier: GPL-2.0-or-later
6 /////////////////////////////////////////////////////////////////////////////
8 * @file EditorFilepathBar.cpp
10 * @brief Implementation file for CEditorFilepathBar class
14 #include "EditorFilepathBar.h"
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)
30 CEditorFilePathBar::CEditorFilePathBar()
38 CEditorFilePathBar::~CEditorFilePathBar()
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.
48 BOOL CEditorFilePathBar::Create(CWnd* pParentWnd)
50 if (! CDialogBar::Create(pParentWnd, CEditorFilePathBar::IDD,
51 CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY, CEditorFilePathBar::IDD))
54 NONCLIENTMETRICS ncm = { sizeof NONCLIENTMETRICS };
55 if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof NONCLIENTMETRICS, &ncm, 0))
56 m_font.CreateFontIndirect(&ncm.lfStatusFont);
58 // subclass the two custom edit boxes
59 for (int pane = 0; pane < static_cast<int>(std::size(m_Edit)); pane++)
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);
68 CSize CEditorFilePathBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
72 CFont *pOldFont = dc.SelectObject(&m_font);
73 dc.GetTextMetrics(&tm);
74 dc.SelectObject(pOldFont);
75 return CSize(SHRT_MAX, tm.tmHeight + 6);
79 * @brief Resize both controls to an equal size.
81 void CEditorFilePathBar::Resize()
83 if (m_hWnd == nullptr)
86 WINDOWPLACEMENT infoBar;
87 GetWindowPlacement(&infoBar);
90 for (int pane = 0; pane < m_nPanes; pane++)
91 widths[pane] = (infoBar.rcNormalPosition.right / m_nPanes);
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.
102 void CEditorFilePathBar::Resize(int widths[])
104 if (m_hWnd == nullptr)
107 // resize left filename
111 for (int pane = 0; pane < m_nPanes; pane++)
114 m_Edit[pane].GetClientRect(&rcOld);
116 rc.right = x + widths[pane] + (pane == 0 ? 5 : 7);
118 if (rcOld.Width() != rc.Width())
120 m_Edit[pane].MoveWindow(&rc);
121 m_Edit[pane].RefreshDisplayText();
127 * @brief Called when tooltip is about to be shown.
128 * In this function we set the tooltip text shown.
130 BOOL CEditorFilePathBar::OnToolTipNotify(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
132 if (m_hWnd == nullptr)
135 TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;
136 if (pTTT->uFlags & TTF_IDISHWND)
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)
142 // compute max width : 97% of application width or 80% or full screen width
145 int maxWidth = (int)(rect.Width() * .97);
147 SystemParametersInfo(SPI_GETWORKAREA, 0, rectScreen, 0);
148 if (rectScreen.Width() * .8 > maxWidth)
149 maxWidth = (int)(rectScreen.Width() * .8);
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);
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());
161 if (hOldFont != nullptr)
162 ::SelectObject(tempDC.GetSafeHdc(),hOldFont);
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);
174 void CEditorFilePathBar::OnSetFocusEdit(UINT id)
177 m_callbackfunc(id - IDC_STATIC_TITLE_PANE0);
181 * @brief Get the path for one side
183 * @param [in] pane Index (0-based) of pane to update.
185 String CEditorFilePathBar::GetText(int pane) const
187 ASSERT (pane >= 0 && pane < static_cast<int>(std::size(m_Edit)));
189 // Check for `nullptr` since window may be closing..
190 if (m_hWnd == nullptr)
194 m_Edit[pane].GetWindowText(str);
199 * @brief Set the path for one side
201 * @param [in] pane Index (0-based) of pane to update.
202 * @param [in] lpszString New text for pane.
204 void CEditorFilePathBar::SetText(int pane, const String& sString)
206 ASSERT (pane >= 0 && pane < static_cast<int>(std::size(m_Edit)));
208 // Check for `nullptr` since window may be closing..
209 if (m_hWnd == nullptr)
212 m_Edit[pane].SetOriginalText(sString);
216 * @brief Set the active status for one status (change the appearance)
218 * @param [in] pane Index (0-based) of pane to update.
219 * @param [in] bActive If `true` activates pane, `false` deactivates.
221 void CEditorFilePathBar::SetActive(int pane, bool bActive)
223 ASSERT (pane >= 0 && pane < static_cast<int>(std::size(m_Edit)));
225 // Check for `nullptr` since window may be closing..
226 if (m_hWnd == nullptr)
229 m_Edit[pane].SetActive(bActive);