libui/windows/fontdialog.cpp

173 lines
5.1 KiB
C++
Raw Normal View History

// 14 april 2016
#include "uipriv_windows.h"
struct fontDialog {
HWND hwnd;
HWND familyCombobox;
HWND styleCombobox;
HWND sizeCombobox;
HWND smallCapsCheckbox;
// TODO desc;
fontCollection *fc;
2016-04-14 21:25:32 -05:00
IDWriteFontFamily **families;
UINT32 nFamilies;
};
2016-04-14 21:25:32 -05:00
static LRESULT cbAddString(HWND cb, WCHAR *str)
{
LRESULT lr;
lr = SendMessageW(cb, CB_ADDSTRING, 0, (LPARAM) str);
if (lr == (LRESULT) CB_ERR || lr == (LRESULT) CB_ERRSPACE)
logLastError("error adding item to combobox in cbAddString()");
return lr;
}
static LRESULT cbInsertStringAtTop(HWND cb, WCHAR *str)
{
LRESULT lr;
lr = SendMessageW(cb, CB_INSERTSTRING, 0, (LPARAM) str);
if (lr == (LRESULT) CB_ERR || lr == (LRESULT) CB_ERRSPACE)
logLastError("error inserting item to combobox in cbInsertStringAtTop()");
return lr;
}
static struct fontDialog *beginFontDialog(HWND hwnd, LPARAM lParam)
{
struct fontDialog *f;
2016-04-14 21:25:32 -05:00
UINT32 i;
WCHAR *wname;
LRESULT ten;
HRESULT hr;
f = uiNew(struct fontDialog);
f->hwnd = hwnd;
f->familyCombobox = GetDlgItem(f->hwnd, rcFontFamilyCombobox);
if (f->familyCombobox == NULL)
logLastError("error getting font family combobox handle in beginFontDialog()");
f->styleCombobox = GetDlgItem(f->hwnd, rcFontStyleCombobox);
if (f->styleCombobox == NULL)
logLastError("error getting font style combobox handle in beginFontDialog()");
f->sizeCombobox = GetDlgItem(f->hwnd, rcFontSizeCombobox);
if (f->sizeCombobox == NULL)
logLastError("error getting font size combobox handle in beginFontDialog()");
f->smallCapsCheckbox = GetDlgItem(f->hwnd, rcFontSmallCapsCheckbox);
if (f->smallCapsCheckbox == NULL)
logLastError("error getting small caps checkbox handle in beginFontDialog()");
2016-04-14 21:25:32 -05:00
f->fc = loadFontCollection();
f->nFamilies = f->fc->fonts->GetFontFamilyCount();
f->families = new IDWriteFontFamily *[f->nFamilies];
for (i = 0; i < f->nFamilies; i++) {
hr = f->fc->fonts->GetFontFamily(i, &(f->families[i]));
if (hr != S_OK)
logHRESULT("error getting font family in beginFontDialog()", hr);
wname = fontCollectionFamilyName(f->fc, f->families[i]);
cbAddString(f->familyCombobox, wname);
uiFree(wname);
}
// TODO all comboboxes should select on type; these already scroll on type but not select
// TODO behavior for the real thing:
// - if prior size is in list, select and scroll to it
// - if not, select nothing and don't scroll list at all (keep at top)
// we do 8 and 9 later
ten = cbAddString(f->sizeCombobox, L"10");
cbAddString(f->sizeCombobox, L"11");
cbAddString(f->sizeCombobox, L"12");
cbAddString(f->sizeCombobox, L"14");
cbAddString(f->sizeCombobox, L"16");
cbAddString(f->sizeCombobox, L"18");
cbAddString(f->sizeCombobox, L"20");
cbAddString(f->sizeCombobox, L"22");
cbAddString(f->sizeCombobox, L"24");
cbAddString(f->sizeCombobox, L"26");
cbAddString(f->sizeCombobox, L"28");
cbAddString(f->sizeCombobox, L"36");
cbAddString(f->sizeCombobox, L"48");
cbAddString(f->sizeCombobox, L"72");
if (SendMessageW(f->sizeCombobox, CB_SETCURSEL, (WPARAM) ten, 0) != ten)
logLastError("error selecting 10 in the size combobox in beginFontDialog()");
// if we just use CB_ADDSTRING 8 and 9 will appear at the bottom of the list due to lexicographical sorting
// if we use CB_INSERTSTRING instead it won't
cbInsertStringAtTop(f->sizeCombobox, L"9");
cbInsertStringAtTop(f->sizeCombobox, L"8");
// 10 moved because of the above; figure out where it is now
// we selected it earlier; getting the selection is easiest
ten = SendMessageW(f->sizeCombobox, CB_GETCURSEL, 0, 0);
// and finally put 10 at the top to imitate ChooseFont()
if (SendMessageW(f->sizeCombobox, CB_SETTOPINDEX, (WPARAM) ten, 0) != 0)
logLastError("error making 10 visible in the size combobox in beginFontDialog()");
// TODO use GetComboBoxInfo() to add ES_NUMBER to the size combobox's edit box
return f;
}
static void endFontDialog(struct fontDialog *f, INT_PTR code)
{
2016-04-14 21:25:32 -05:00
UINT32 i;
for (i = 0; i < f->nFamilies; i++)
f->families[i]->Release();
delete[] f->families;
fontCollectionFree(f->fc);
if (EndDialog(f->hwnd, code) == 0)
logLastError("error ending font dialog in endFontDialog()");
uiFree(f);
}
static INT_PTR tryFinishDialog(struct fontDialog *f, WPARAM wParam)
{
// cancelling
if (LOWORD(wParam) != IDOK) {
endFontDialog(f, 1);
return TRUE;
}
// TODO
endFontDialog(f, 2);
return TRUE;
}
static INT_PTR CALLBACK fontDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
struct fontDialog *f;
f = (struct fontDialog *) GetWindowLongPtrW(hwnd, DWLP_USER);
if (f == NULL) {
if (uMsg == WM_INITDIALOG) {
f = beginFontDialog(hwnd, lParam);
SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR) f);
return TRUE;
}
return FALSE;
}
switch (uMsg) {
case WM_COMMAND:
if (HIWORD(wParam) != BN_CLICKED)
return FALSE;
return tryFinishDialog(f, wParam);
}
return FALSE;
}
void showFontDialog(HWND parent)
{
switch (DialogBoxParamW(hInstance, MAKEINTRESOURCE(rcFontDialog), parent, fontDialogDlgProc, (LPARAM) NULL)) {
case 1:
// TODO cancel
break;
case 2:
// TODO OK
break;
default:
logLastError("error running font dialog in showFontDialog()");
}
}