OSDN Git Service

EditorFilepathBar.*: Fix text cut off when changing hint font size in Windows control...
[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 //
6 //    This program is free software; you can redistribute it and/or modify
7 //    it under the terms of the GNU General Public License as published by
8 //    the Free Software Foundation; either version 2 of the License, or
9 //    (at your option) any later version.
10 //
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.
15 //
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
18 //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //
20 /////////////////////////////////////////////////////////////////////////////
21 /** 
22  * @file  EditorFilepathBar.cpp
23  *
24  * @brief Implementation file for CEditorFilepathBar class
25  */
26
27 #include "stdafx.h"
28 #include "EditorFilepathBar.h"
29
30 #ifdef _DEBUG
31 #define new DEBUG_NEW
32 #undef THIS_FILE
33 static char THIS_FILE[] = __FILE__;
34 #endif
35
36
37 BEGIN_MESSAGE_MAP(CEditorFilePathBar, CDialogBar)
38         ON_NOTIFY_EX (TTN_NEEDTEXT, 0, OnToolTipNotify)
39 END_MESSAGE_MAP()
40
41
42 /**
43  * @brief Constructor.
44  */
45 CEditorFilePathBar::CEditorFilePathBar()
46 : m_pFont(nullptr), m_nPanes(2)
47 {
48 }
49
50 /**
51  * @brief Destructor.
52  */
53 CEditorFilePathBar::~CEditorFilePathBar()
54 {
55 }
56
57 /**
58  * @brief Create the window.
59  * This function subclasses the edit controls.
60  * @param [in] pParentWnd Parent window for edit controls.
61  * @return TRUE if succeeded, FALSE otherwise.
62  */
63 BOOL CEditorFilePathBar::Create(CWnd* pParentWnd)
64 {
65         if (! CDialogBar::Create(pParentWnd, CEditorFilePathBar::IDD, 
66                         CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY, CEditorFilePathBar::IDD))
67                 return FALSE;
68
69         // subclass the two custom edit boxes
70         for (int pane = 0; pane < countof(m_Edit); pane++)
71                 m_Edit[pane].SubClassEdit(IDC_STATIC_TITLE_PANE0 + pane, this);
72
73         return TRUE;
74 };
75
76 CSize CEditorFilePathBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
77 {
78         TEXTMETRIC tm;
79         CDC *pdc = GetDC();
80         CFont *pOldFont = pdc->SelectObject(m_pFont.get());
81         pdc->GetTextMetrics(&tm);
82         pdc->SelectObject(pOldFont);
83         ReleaseDC(pdc);
84         return CSize(SHRT_MAX, tm.tmHeight + 6);
85 }
86
87 void CEditorFilePathBar::SetPaneCount(int nPanes)
88 {
89         m_nPanes = nPanes;
90 }
91
92 /**
93  * @brief Set look of headerbars similar to other window.
94  *
95  * @param [in] pWnd Pointer to window we want to imitate
96  * @return TRUE if parent must recompute layout
97  */
98 BOOL CEditorFilePathBar::LookLikeThisWnd(const CWnd * pWnd)
99 {
100         // Update font. Note that we must delete previous font
101         // before creating a new one.
102         CFont * pFont = pWnd->GetFont();
103         if (pFont)
104         {
105                 m_pFont.reset(new CFont);
106                 if (m_pFont != NULL)
107                 {
108                         LOGFONT lfFont = {0};
109                         if (pFont->GetLogFont(&lfFont))
110                         {
111                                 m_pFont->CreateFontIndirect(&lfFont);
112                                 for (int pane = 0; pane < m_nPanes; pane++)
113                                 {
114                                         m_Edit[pane].SetFont(m_pFont.get());
115                                         m_Edit[pane].SetMargins(4, 4);
116                                 }
117                         }
118                 }
119         }
120
121         // Set same dimensions (than window we imitate)
122         CRect rectNew;
123         pWnd->GetWindowRect(rectNew);
124         CRect rectCurrent;
125         GetWindowRect(rectCurrent);
126         if (rectNew != rectCurrent)
127         {
128                 SetWindowPos(NULL,0,0,rectNew.Width(), rectNew.Height(),
129                         SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE);     
130                 return TRUE;
131         }
132         return FALSE;
133 }
134
135 /** 
136  * @brief Resize both controls to an equal size.
137  */
138 void CEditorFilePathBar::Resize()
139 {
140         if (m_hWnd == NULL)
141                 return;
142
143         WINDOWPLACEMENT infoBar;
144         GetWindowPlacement(&infoBar);
145
146         int widths[3];
147         for (int pane = 0; pane < m_nPanes; pane++)
148                 widths[pane] = (infoBar.rcNormalPosition.right / m_nPanes) - 6;
149         Resize(widths);
150 }
151 /** 
152  * @brief Set widths.
153  * This function resizes both controls to given size. The width is usually
154  * same as the splitter view width.
155  * @param [in] leftWidth Left-side control width.
156  * @param [in] rightWidth Right-side control width.
157  */
158 void CEditorFilePathBar::Resize(int widths[])
159 {
160         if (m_hWnd == NULL)
161                 return;
162
163         // resize left filename
164         CRect rc;
165         int x = 0;
166         GetClientRect(&rc);
167         for (int pane = 0; pane < m_nPanes; pane++)
168         {
169                 CRect rcOld;
170                 m_Edit[pane].GetClientRect(&rcOld);
171                 rc.left = x;
172                 rc.right = x + widths[pane] + 4;
173                 x += widths[pane] + 7;
174                 if (rcOld.Width() != rc.Width())
175                 {
176                         m_Edit[pane].MoveWindow(&rc);
177                         m_Edit[pane].RefreshDisplayText();
178                 }
179         }
180 }
181
182 /**
183  * @brief Called when tooltip is about to be shown.
184  * In this function we set the tooltip text shown.
185  */
186 BOOL CEditorFilePathBar::OnToolTipNotify(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
187 {
188         if (m_hWnd == NULL)
189                 return FALSE;
190
191         TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;
192         if (pTTT->uFlags & TTF_IDISHWND)
193         {
194                 // idFrom is actually the HWND of the CEdit 
195                 int nID = ::GetDlgCtrlID((HWND)pTTTStruct->idFrom);
196                 if(nID == IDC_STATIC_TITLE_PANE0 || nID == IDC_STATIC_TITLE_PANE1 || nID == IDC_STATIC_TITLE_PANE2)
197                 {
198                         // compute max width : 97% of application width or 80% or full screen width
199                         CRect rect;
200                         GetWindowRect(rect);
201                         int maxWidth = (int)(rect.Width() * .97);
202                         CRect rectScreen; 
203                         SystemParametersInfo(SPI_GETWORKAREA, 0, rectScreen, 0);
204                         if (rectScreen.Width() * .8 > maxWidth)
205                                 maxWidth = (int)(rectScreen.Width() * .8);
206
207                         // use the tooltip font
208                         HANDLE hFont = (HANDLE) ::SendMessage(pTTTStruct->hwndFrom, WM_GETFONT, 0, 0);
209                         CClientDC tempDC(this);
210                         HANDLE hOldFont = ::SelectObject(tempDC.GetSafeHdc(),hFont);
211
212                         // fill in the returned structure
213                         CFilepathEdit * pItem = static_cast<CFilepathEdit*>(GetDlgItem(nID));
214                         pTTT->lpszText = const_cast<TCHAR *>(pItem->GetUpdatedTipText(&tempDC, maxWidth).c_str());
215
216                         // set old font back
217                         if (hOldFont)
218                                 ::SelectObject(tempDC.GetSafeHdc(),hOldFont);
219
220                         // we must set TTM_SETMAXTIPWIDTH to use \n in tooltips
221                         // just to do the first time, but how to access the tooltip during init ?
222                         ::SendMessage(pTTTStruct->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 5000);
223
224                         return(TRUE);
225                 }
226         }
227         return(FALSE);
228 }
229
230 /** 
231  * @brief Set the path for one side
232  *
233  * @param [in] pane Index (0-based) of pane to update.
234  * @param [in] lpszString New text for pane.
235  */
236 void CEditorFilePathBar::SetText(int pane, const String& sString)
237 {
238         ASSERT (pane >= 0 && pane < countof(m_Edit));
239
240         // Check for NULL since window may be closing..
241         if (m_hWnd == NULL)
242                 return;
243
244         m_Edit[pane].SetOriginalText(sString);
245 }
246
247 /** 
248  * @brief Set the active status for one status (change the appearance)
249  *
250  * @param [in] pane Index (0-based) of pane to update.
251  * @param [in] bActive If TRUE activates pane, FALSE deactivates.
252  */
253 void CEditorFilePathBar::SetActive(int pane, bool bActive)
254 {
255         ASSERT (pane >= 0 && pane < countof(m_Edit));
256
257         // Check for NULL since window may be closing..
258         if (m_hWnd == NULL)
259                 return;
260
261         m_Edit[pane].SetActive(bActive);
262 }