5#include "Stroika/Foundation/StroikaPreComp.h"
9DISABLE_COMPILER_MSC_WARNING_START (5054)
11DISABLE_COMPILER_MSC_WARNING_END (5054)
20#include "LedItApplication.h"
21#include "LedItResources.h"
23#include "FormatToolbar.h"
27#if qStroika_Foundation_Common_Platform_Windows
29using LocalComboBox = FormatToolbar::LocalComboBox;
37BEGIN_MESSAGE_MAP (FormatToolbar, CToolBar)
40ON_CBN_DROPDOWN (IDC_FONTSIZE, OnFontSizeDropDown)
41ON_CBN_KILLFOCUS (IDC_FONTNAME, OnFontNameKillFocus)
42ON_CBN_KILLFOCUS (IDC_FONTSIZE, OnFontSizeKillFocus)
43ON_CBN_SETFOCUS (IDC_FONTNAME, OnComboSetFocus)
44ON_CBN_SETFOCUS (IDC_FONTSIZE, OnComboSetFocus)
45ON_CBN_CLOSEUP (IDC_FONTNAME, OnComboCloseUp)
46ON_CBN_CLOSEUP (IDC_FONTSIZE, OnComboCloseUp)
49static CSize GetBaseUnits (CFont* pFont)
51 ASSERT (pFont != NULL);
52 ASSERT (pFont->GetSafeHandle () != NULL);
53 CWindowDC screenDC (NULL);
54 pFont = screenDC.SelectObject (pFont);
56 VERIFY (screenDC.GetTextMetrics (&tm));
57 screenDC.SelectObject (pFont);
59 return CSize (tm.tmAveCharWidth, tm.tmHeight);
62FormatToolbar::FormatToolbar (FormatToolbarOwner& owner)
66 fnt.Attach (GetStockObject (DEFAULT_GUI_FONT));
67 m_szBaseUnits = GetBaseUnits (&fnt);
68 LocalComboBox::m_nFontHeight = m_szBaseUnits.cy;
71void FormatToolbar::OnUpdateCmdUI (CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
73 CToolBar::OnUpdateCmdUI (pTarget, bDisableIfNoHndler);
75 if (!m_comboFontName.HasFocus () && !m_comboFontSize.HasFocus ())
79void FormatToolbar::SyncToView ()
81 IncrementalFontSpecification fsp = fOwner.GetCurFont ();
82 if (fsp.GetFontNameSpecifier_Valid ()) {
83 m_comboFontName.MatchFont (fsp.GetFontName ().c_str ());
86 m_comboFontName.SetTheText (_T(
""));
91 m_comboFontSize.SetTwipSize (fsp.GetPointSize_Valid () ? fsp.GetPointSize () * 20 : -1);
94void FormatToolbar::OnFontSizeDropDown ()
97 m_comboFontName.GetTheText (str);
99 int nIndex = m_comboFontName.FindStringExact (-1, str);
100 if (nIndex != CB_ERR) {
101 m_comboFontName.GetLBText (nIndex, lpszName);
104 int nSize = m_comboFontSize.GetTwipSize ();
107 AfxMessageBox(IDS_INVALID_NUMBER, MB_OK | MB_ICONINFORMATION);
109 nSize = m_comboFontSize.m_nTwipsLast;
111 else if ((nSize >= 0 && nSize < 20) || nSize > 32760) {
113 AfxMessageBox(IDS_INVALID_FONTSIZE, MB_OK | MB_ICONINFORMATION);
115 nSize = m_comboFontSize.m_nTwipsLast;
118 CWindowDC screenDC (NULL);
119 m_comboFontSize.EnumFontSizes (screenDC, (lpszName.GetLength () == 0) ? NULL : LPCTSTR (lpszName));
120 m_comboFontSize.SetTwipSize (nSize);
123void FormatToolbar::OnComboCloseUp ()
125 NotifyOwner (NM_RETURN);
128void FormatToolbar::OnComboSetFocus ()
130 NotifyOwner (NM_SETFOCUS);
133void FormatToolbar::OnFontNameKillFocus ()
137 NotifyOwner (NM_KILLFOCUS);
143 m_comboFontName.GetTheText (str);
144 m_comboFontName.SetTheText (str);
145 m_comboFontName.GetTheText (str);
148 if (not str.IsEmpty ()) {
149 IncrementalFontSpecification fsp;
150 int nIndex = m_comboFontName.FindStringExact (-1, str);
151 if (nIndex != CB_ERR) {
153 m_comboFontName.GetLBText (nIndex, name);
154 fsp.SetFontName ((LPCTSTR)name);
159 fsp.SetFontName ((LPCTSTR)str);
161 fOwner.SetCurFont (fsp);
165void FormatToolbar::OnFontSizeKillFocus ()
167 NotifyOwner (NM_KILLFOCUS);
168 int nSize = m_comboFontSize.GetTwipSize ();
171 AfxMessageBox(IDS_INVALID_NUMBER, MB_OK | MB_ICONINFORMATION);
173 nSize = m_comboFontSize.m_nTwipsLast;
175 else if ((nSize >= 0 && nSize < 20) || nSize > 32760) {
177 AfxMessageBox(IDS_INVALID_FONTSIZE, MB_OK | MB_ICONINFORMATION);
179 nSize = m_comboFontSize.m_nTwipsLast;
181 else if (nSize > 0) {
184 cf.dwMask = CFM_SIZE;
188 IncrementalFontSpecification fsp;
189 fsp.SetPointSize (
static_cast<IncrementalFontSpecification::FontSize
> (nSize / 20));
190 fOwner.SetCurFont (fsp);
194int FormatToolbar::OnCreate (LPCREATESTRUCT lpCreateStruct)
196 if (CToolBar::OnCreate (lpCreateStruct) == -1)
199 CRect rect (0, 0, (3 * LF_FACESIZE * m_szBaseUnits.cx) / 2, 200);
200 if (!m_comboFontName.Create (WS_TABSTOP | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWN | CBS_SORT | CBS_AUTOHSCROLL | CBS_HASSTRINGS | CBS_OWNERDRAWFIXED,
201 rect,
this, IDC_FONTNAME)) {
202 TRACE0 (
"Failed to create fontname combo-box\n");
205 m_comboFontName.LimitText (LF_FACESIZE);
207 rect.SetRect (0, 0, 10 * m_szBaseUnits.cx, 200);
208 if (!m_comboFontSize.Create (WS_TABSTOP | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWN, rect,
this, IDC_FONTSIZE)) {
209 TRACE0 (
"Failed to create fontsize combo-box\n");
213 m_comboFontSize.LimitText (4);
214 m_comboFontName.EnumFontFamiliesEx ();
216 static UINT BASED_CODE format[] = {
221 ID_SEPARATOR, kFontStyleBoldCmd, kFontStyleItalicCmd, kFontStyleUnderlineCmd, ID_CHAR_COLOR,
222 ID_SEPARATOR, kJustifyLeftCmd, kJustifyCenterCmd, kJustifyRightCmd,
225 if (!LoadBitmap (IDB_FORMATBAR) || !SetButtons (format,
sizeof (format) /
sizeof (UINT))) {
226 TRACE0 (
"Failed to create FormatBar\n");
229 SetBarStyle (GetBarStyle () | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC | CBRS_HIDE_INPLACE);
230 SetSizes (CSize (23, 22), CSize (16, 16));
232 (void)str.LoadString (IDS_TITLE_FORMATBAR);
239void FormatToolbar::PositionCombos ()
244 m_comboFontName.SetItemHeight (-1, m_comboFontSize.GetItemHeight (-1));
246 m_comboFontName.GetWindowRect (&rect);
247 int nHeight = rect.Height ();
249 m_comboFontName.GetWindowRect (&rect);
250 SetButtonInfo (0, IDC_FONTNAME, TBBS_SEPARATOR, rect.Width ());
251 GetItemRect (0, &rect);
252 m_comboFontName.SetWindowPos (NULL, rect.left, ((rect.Height () - nHeight) / 2) + rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
254 m_comboFontSize.GetWindowRect (&rect);
255 SetButtonInfo (2, IDC_FONTSIZE, TBBS_SEPARATOR, rect.Width ());
256 GetItemRect (2, &rect);
257 m_comboFontSize.SetWindowPos (NULL, rect.left, ((rect.Height () - nHeight) / 2) + rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
260void FormatToolbar::NotifyOwner (UINT nCode)
263 nm.hwndFrom = m_hWnd;
264 nm.idFrom = GetDlgCtrlID ();
266 GetOwner ()->SendMessage (WM_NOTIFY, nm.idFrom, (LPARAM)&nm);
274using FontComboBox = FormatToolbar::FontComboBox;
279BEGIN_MESSAGE_MAP (FontComboBox, LocalComboBox)
282FontComboBox::FontComboBox ()
284 VERIFY (m_bmFontType.LoadBitmap (IDB_FONTTYPE));
287void FontComboBox::EnumFontFamiliesEx ()
292 vector<SDKString> fonts = LedItApplication::Get ().GetUsableFontNames ();
293 for (vector<SDKString>::const_iterator i = fonts.begin (); i != fonts.end (); ++i) {
294 AddString ((*i).c_str ());
299BOOL CALLBACK AFX_EXPORT FontComboBox::CheckIsTrueTypeEnumFamCallback (ENUMLOGFONTEX* , NEWTEXTMETRICEX* ,
int FontType, LPVOID pThis)
301 bool* bs = (
bool*)pThis;
302 if (FontType & TRUETYPE_FONTTYPE) {
308void FontComboBox::DrawItem (LPDRAWITEMSTRUCT lpDIS)
310 ASSERT (lpDIS->CtlType == ODT_COMBOBOX);
311 int id = (int)(WORD)lpDIS->itemID;
313 CDC* pDC = CDC::FromHandle (lpDIS->hDC);
314 CRect rc (lpDIS->rcItem);
315 if (lpDIS->itemState & ODS_FOCUS)
316 pDC->DrawFocusRect (rc);
317 int nIndexDC = pDC->SaveDC ();
320 if (lpDIS->itemState & ODS_SELECTED) {
321 brushFill.CreateSolidBrush (::GetSysColor (COLOR_HIGHLIGHT));
322 pDC->SetTextColor (::GetSysColor (COLOR_HIGHLIGHTTEXT));
325 brushFill.CreateSolidBrush (pDC->GetBkColor ());
326 pDC->SetBkMode (TRANSPARENT);
327 pDC->FillRect (rc, &brushFill);
330 GetLBText (
id, strText);
332 bool isTrueType =
false;
335 Characters::CString::Copy (lf.lfFaceName, Memory::NEltsOf (lf.lfFaceName),
static_cast<const TCHAR*
> (strText));
336 CWindowDC screenDC{
nullptr};
337 HDC hDC = screenDC.m_hDC;
338 ASSERT (hDC != NULL);
339 ::EnumFontFamiliesEx (hDC, &lf, (FONTENUMPROC)CheckIsTrueTypeEnumFamCallback, (LPARAM)&isTrueType, NULL);
343 dc.CreateCompatibleDC (pDC);
344 CBitmap* pBitmap = dc.SelectObject (&m_bmFontType);
345 pDC->BitBlt (rc.left, rc.top, BMW, BMH, &dc, BMW, 0, SRCAND);
346 dc.SelectObject (pBitmap);
350 pDC->TextOut (rc.left, rc.top, strText, strText.GetLength ());
352 pDC->RestoreDC (nIndexDC);
355void FontComboBox::MeasureItem (LPMEASUREITEMSTRUCT lpMIS)
357 ASSERT (lpMIS->CtlType == ODT_COMBOBOX);
358 ASSERT (m_nFontHeight > 0);
362 lpMIS->itemWidth = rc.Width ();
363 lpMIS->itemHeight = max (BMH, m_nFontHeight);
366int FontComboBox::CompareItem (LPCOMPAREITEMSTRUCT lpCIS)
368 ASSERT (lpCIS->CtlType == ODT_COMBOBOX);
369 int id1 = (int)(WORD)lpCIS->itemID1;
370 int id2 = (int)(WORD)lpCIS->itemID2;
376 GetLBText (id1, str1);
377 GetLBText (id2, str2);
378 return str1.Collate (str2);
382void FontComboBox::MatchFont (LPCTSTR lpszName)
384 int nFirstIndex = FindString (-1, lpszName);
385 if (nFirstIndex != CB_ERR) {
386 int nIndex = nFirstIndex;
389 GetLBText (nIndex, str);
390 if (lstrcmp (lpszName, str) == 0) {
392 if (GetCurSel () != nIndex)
396 nIndex = FindString (nIndex, lpszName);
397 }
while (nIndex != nFirstIndex);
401 SetTheText (lpszName, TRUE);
409using SizeComboBox = FormatToolbar::SizeComboBox;
411SizeComboBox::SizeComboBox ()
416void SizeComboBox::EnumFontSizes (CDC& dc, LPCTSTR pFontName)
419 if (pFontName == NULL)
421 if (pFontName[0] == NULL)
424 ASSERT (dc.m_hDC != NULL);
425 m_nLogVert = dc.GetDeviceCaps (LOGPIXELSY);
426 ::EnumFontFamilies (dc.m_hDC, pFontName, (FONTENUMPROC)EnumSizeCallBack, (LPARAM)
this);
429void SizeComboBox::TwipsToPointString (LPTSTR lpszBuf,
int nTwips)
431 ASSERT (lpszBuf != NULL);
435 nTwips = (nTwips + 5) / 10;
436 DISABLE_COMPILER_MSC_WARNING_START (4996)
437 if ((nTwips % 2) == 0)
438 _stprintf (lpszBuf, _T("%ld"), nTwips / 2);
440 _stprintf (lpszBuf, _T("%.1f"), (
float)nTwips / 2.F);
441 DISABLE_COMPILER_MSC_WARNING_END (4996)
445void SizeComboBox::SetTwipSize (
int nTwips)
447 if (nTwips != GetTwipSize ()) {
449 TwipsToPointString (buf, nTwips);
450 SetTheText (buf, TRUE);
452 m_nTwipsLast = nTwips;
455int SizeComboBox::GetTwipSize ()
463 LPCTSTR lpszText = str;
465 while (*lpszText ==
' ' || *lpszText ==
'\t')
468 if (lpszText[0] == NULL)
471 double d = _tcstod (lpszText, (LPTSTR*)&lpszText);
472 while (*lpszText ==
' ' || *lpszText ==
'\t')
475 if (*lpszText != NULL)
478 return (d < 0.) ? 0 : (int)(d * 20.);
481BOOL CALLBACK AFX_EXPORT SizeComboBox::EnumSizeCallBack (LOGFONT FAR* , LPNEWTEXTMETRIC lpntm,
int FontType, LPVOID lpv)
483 static int nFontSizes[] = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72};
485 SizeComboBox* pThis = (SizeComboBox*)lpv;
486 ASSERT (pThis != NULL);
488 if ((FontType & TRUETYPE_FONTTYPE) || !((FontType & TRUETYPE_FONTTYPE) || (FontType & RASTER_FONTTYPE))) {
490 if (pThis->GetCount () != 0)
491 pThis->ResetContent ();
493 for (
int i = 0; i < 16; ++i) {
494 wsprintf (buf, _T(
"%d"), nFontSizes[i]);
495 pThis->AddString (buf);
500 pThis->InsertSize (MulDiv (lpntm->tmHeight - lpntm->tmInternalLeading, 1440, pThis->m_nLogVert));
504void SizeComboBox::InsertSize (
int nSize)
507 DWORD dwSize = (DWORD)nSize;
509 TwipsToPointString (buf, nSize);
510 if (FindStringExact (-1, buf) == CB_ERR) {
514 while ((dw =
static_cast<DWORD
> (GetItemData (nPos))) != CB_ERR) {
521 nIndex = InsertString (nIndex, buf);
522 ASSERT (nIndex != CB_ERR);
523 if (nIndex != CB_ERR)
524 SetItemData (nIndex, dwSize);
533using LocalComboBox = FormatToolbar::LocalComboBox;
535int LocalComboBox::m_nFontHeight = 0;
537BEGIN_MESSAGE_MAP (LocalComboBox, CComboBox)
541void LocalComboBox::GetTheText (CString& str)
543 int nIndex = GetCurSel ();
544 if (nIndex == CB_ERR)
547 GetLBText (nIndex, str);
550void LocalComboBox::SetTheText (LPCTSTR lpszText, BOOL bMatchExact)
552 int idx = (bMatchExact) ? FindStringExact (-1, lpszText) : FindString (-1, lpszText);
553 SetCurSel ((idx == CB_ERR) ? -1 : idx);
555 SetWindowText (lpszText);
558BOOL LocalComboBox::LimitText (
int nMaxChars)
560 BOOL b = CComboBox::LimitText (nMaxChars);
562 m_nLimitText = nMaxChars;
566int LocalComboBox::OnCreate (LPCREATESTRUCT lpCreateStruct)
568 if (CComboBox::OnCreate (lpCreateStruct) == -1)
570 SendMessage (WM_SETFONT, (WPARAM)GetStockObject (DEFAULT_GUI_FONT));
574BOOL LocalComboBox::PreTranslateMessage (MSG* pMsg)
576 if (pMsg->message == WM_KEYDOWN) {
577 FormatToolbar* pBar = (FormatToolbar*)GetParent ();
578 switch (pMsg->wParam) {
581 pBar->NotifyOwner (NM_RETURN);
584 pBar->NotifyOwner (NM_RETURN);
587 pBar->GetNextDlgTabItem (
this)->SetFocus ();
591 if ((GetKeyState (VK_MENU) >= 0) && (GetKeyState (VK_CONTROL) >= 0) && !GetDroppedState ()) {
597 return CComboBox::PreTranslateMessage (pMsg);