Properly implemented the size combobox. We're so close!
This commit is contained in:
parent
39ea7e269f
commit
0e75a6f950
|
@ -30,7 +30,7 @@ struct fontDialog {
|
||||||
DWRITE_FONT_STRETCH stretch;
|
DWRITE_FONT_STRETCH stretch;
|
||||||
};
|
};
|
||||||
|
|
||||||
static LRESULT cbAddString(HWND cb, WCHAR *str)
|
static LRESULT cbAddString(HWND cb, const WCHAR *str)
|
||||||
{
|
{
|
||||||
LRESULT lr;
|
LRESULT lr;
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ static LRESULT cbAddString(HWND cb, WCHAR *str)
|
||||||
return lr;
|
return lr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT cbInsertStringAtTop(HWND cb, WCHAR *str)
|
static LRESULT cbInsertString(HWND cb, const WCHAR *str, WPARAM pos)
|
||||||
{
|
{
|
||||||
LRESULT lr;
|
LRESULT lr;
|
||||||
|
|
||||||
lr = SendMessageW(cb, CB_INSERTSTRING, 0, (LPARAM) str);
|
lr = SendMessageW(cb, CB_INSERTSTRING, pos, (LPARAM) str);
|
||||||
if (lr == (LRESULT) CB_ERR || lr == (LRESULT) CB_ERRSPACE)
|
if (lr != (LRESULT) pos)
|
||||||
logLastError("error inserting item to combobox in cbInsertStringAtTop()");
|
logLastError("error inserting item to combobox in cbInsertString()");
|
||||||
return lr;
|
return lr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ static WCHAR *cbGetItemText(HWND cb, WPARAM item)
|
||||||
text = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR), "WCHAR[]");
|
text = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR), "WCHAR[]");
|
||||||
if (SendMessageW(cb, CB_GETLBTEXT, item, (LPARAM) text) != len)
|
if (SendMessageW(cb, CB_GETLBTEXT, item, (LPARAM) text) != len)
|
||||||
logLastError("error getting item text from combobox in cbGetItemText()");
|
logLastError("error getting item text from combobox in cbGetItemText()");
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL cbTypeToSelect(HWND cb, LRESULT *posOut, BOOL restoreAfter)
|
static BOOL cbTypeToSelect(HWND cb, LRESULT *posOut, BOOL restoreAfter)
|
||||||
|
@ -157,7 +158,6 @@ static void wipeStylesBox(struct fontDialog *f)
|
||||||
static WCHAR *fontStyleName(struct fontDialog *f, IDWriteFont *font)
|
static WCHAR *fontStyleName(struct fontDialog *f, IDWriteFont *font)
|
||||||
{
|
{
|
||||||
IDWriteLocalizedStrings *str;
|
IDWriteLocalizedStrings *str;
|
||||||
BOOL exists;
|
|
||||||
WCHAR *wstr;
|
WCHAR *wstr;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -270,6 +270,61 @@ static void familyEdited(struct fontDialog *f)
|
||||||
familyChanged(f);
|
familyChanged(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const WCHAR *text;
|
||||||
|
double value;
|
||||||
|
} defaultSizes[] = {
|
||||||
|
{ L"8", 8 },
|
||||||
|
{ L"9", 9 },
|
||||||
|
{ L"10", 10 },
|
||||||
|
{ L"11", 11 },
|
||||||
|
{ L"12", 12 },
|
||||||
|
{ L"14", 14 },
|
||||||
|
{ L"16", 16 },
|
||||||
|
{ L"18", 18 },
|
||||||
|
{ L"20", 20 },
|
||||||
|
{ L"22", 22 },
|
||||||
|
{ L"24", 24 },
|
||||||
|
{ L"26", 26 },
|
||||||
|
{ L"28", 28 },
|
||||||
|
{ L"36", 36 },
|
||||||
|
{ L"48", 48 },
|
||||||
|
{ L"72", 72 },
|
||||||
|
{ NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void sizeChanged(struct fontDialog *f)
|
||||||
|
{
|
||||||
|
LRESULT pos;
|
||||||
|
BOOL selected;
|
||||||
|
|
||||||
|
selected = cbGetCurSel(f->sizeCombobox, &pos);
|
||||||
|
if (!selected) // on deselect, do nothing
|
||||||
|
return;
|
||||||
|
f->curSize = defaultSizes[pos].value;
|
||||||
|
queueRedrawSampleText(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sizeEdited(struct fontDialog *f)
|
||||||
|
{
|
||||||
|
WCHAR *wsize;
|
||||||
|
double size;
|
||||||
|
|
||||||
|
// handle type-to-selection
|
||||||
|
if (cbTypeToSelect(f->sizeCombobox, NULL, FALSE)) {
|
||||||
|
sizeChanged(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// selection not chosen, try to parse the typing
|
||||||
|
wsize = windowText(f->sizeCombobox);
|
||||||
|
// this is what the Choose Font dialog does; it swallows errors while the real ChooseFont() is not lenient (and only checks on OK)
|
||||||
|
size = wcstod(wsize, NULL);
|
||||||
|
if (size <= 0) // don't change on invalid size
|
||||||
|
return;
|
||||||
|
f->curSize = size;
|
||||||
|
queueRedrawSampleText(f);
|
||||||
|
}
|
||||||
|
|
||||||
static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt)
|
static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt)
|
||||||
{
|
{
|
||||||
D2D1_COLOR_F color;
|
D2D1_COLOR_F color;
|
||||||
|
@ -279,8 +334,7 @@ static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt
|
||||||
IDWriteLocalizedStrings *sampleStrings;
|
IDWriteLocalizedStrings *sampleStrings;
|
||||||
BOOL exists;
|
BOOL exists;
|
||||||
WCHAR *sample;
|
WCHAR *sample;
|
||||||
WCHAR *family, *wsize;
|
WCHAR *family;
|
||||||
double size;
|
|
||||||
IDWriteTextFormat *format;
|
IDWriteTextFormat *format;
|
||||||
D2D1_RECT_F rect;
|
D2D1_RECT_F rect;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -310,14 +364,9 @@ static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt
|
||||||
sampleStrings->Release();
|
sampleStrings->Release();
|
||||||
} else
|
} else
|
||||||
sample = L"The quick brown fox jumps over the lazy dog.";
|
sample = L"The quick brown fox jumps over the lazy dog.";
|
||||||
// TODO get this from the currently selected item
|
|
||||||
family = windowText(f->familyCombobox);
|
|
||||||
// TODO but NOT this
|
|
||||||
wsize = windowText(f->sizeCombobox);
|
|
||||||
// TODO error check?
|
|
||||||
size = _wtof(wsize);
|
|
||||||
uiFree(wsize);
|
|
||||||
|
|
||||||
|
// DirectWrite doesn't allow creating a text format from a font; we need to get this ourselves
|
||||||
|
family = cbGetItemText(f->familyCombobox, f->curFamily);
|
||||||
hr = dwfactory->CreateTextFormat(family,
|
hr = dwfactory->CreateTextFormat(family,
|
||||||
NULL,
|
NULL,
|
||||||
font->GetWeight(),
|
font->GetWeight(),
|
||||||
|
@ -325,7 +374,7 @@ static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt
|
||||||
font->GetStretch(),
|
font->GetStretch(),
|
||||||
// typographic points are 1/72 inch; this parameter is 1/96 inch
|
// typographic points are 1/72 inch; this parameter is 1/96 inch
|
||||||
// fortunately Microsoft does this too, in https://msdn.microsoft.com/en-us/library/windows/desktop/dd371554%28v=vs.85%29.aspx
|
// fortunately Microsoft does this too, in https://msdn.microsoft.com/en-us/library/windows/desktop/dd371554%28v=vs.85%29.aspx
|
||||||
size * (96.0 / 72.0),
|
f->curSize * (96.0 / 72.0),
|
||||||
// see http://stackoverflow.com/questions/28397971/idwritefactorycreatetextformat-failing and https://msdn.microsoft.com/en-us/library/windows/desktop/dd368203.aspx
|
// see http://stackoverflow.com/questions/28397971/idwritefactorycreatetextformat-failing and https://msdn.microsoft.com/en-us/library/windows/desktop/dd368203.aspx
|
||||||
// TODO use the current locale again?
|
// TODO use the current locale again?
|
||||||
L"",
|
L"",
|
||||||
|
@ -377,7 +426,7 @@ static struct fontDialog *beginFontDialog(HWND hwnd, LPARAM lParam)
|
||||||
UINT32 i, nFamilies;
|
UINT32 i, nFamilies;
|
||||||
IDWriteFontFamily *family;
|
IDWriteFontFamily *family;
|
||||||
WCHAR *wname;
|
WCHAR *wname;
|
||||||
LRESULT pos, ten;
|
LRESULT pos;
|
||||||
HWND samplePlacement;
|
HWND samplePlacement;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -406,38 +455,16 @@ static struct fontDialog *beginFontDialog(HWND hwnd, LPARAM lParam)
|
||||||
cbSetItemData(f->familyCombobox, (WPARAM) pos, (LPARAM) family);
|
cbSetItemData(f->familyCombobox, (WPARAM) pos, (LPARAM) family);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO all comboboxes should select on type; these already scroll on type but not select
|
for (i = 0; defaultSizes[i].text != NULL; i++)
|
||||||
|
cbInsertString(f->sizeCombobox, defaultSizes[i].text, (WPARAM) i);
|
||||||
|
// TODO make this proper
|
||||||
|
cbSetCurSel(f->sizeCombobox, 2);
|
||||||
|
sizeChanged(f);
|
||||||
|
|
||||||
// TODO behavior for the real thing:
|
/*TODO // and finally put 10 at the top to imitate ChooseFont()
|
||||||
// - 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)
|
if (SendMessageW(f->sizeCombobox, CB_SETTOPINDEX, (WPARAM) ten, 0) != 0)
|
||||||
logLastError("error making 10 visible in the size combobox in beginFontDialog()");
|
logLastError("error making 10 visible in the size combobox in beginFontDialog()");
|
||||||
|
*/
|
||||||
|
|
||||||
// note: we can't add ES_NUMBER to the combobox entry (it seems to disable the entry instead?!), so we must do validation when the box is dmissed; TODO
|
// note: we can't add ES_NUMBER to the combobox entry (it seems to disable the entry instead?!), so we must do validation when the box is dmissed; TODO
|
||||||
|
|
||||||
|
@ -531,14 +558,16 @@ static INT_PTR CALLBACK fontDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case rcFontSizeCombobox:
|
case rcFontSizeCombobox:
|
||||||
if (HIWORD(wParam) != CBN_SELCHANGE)
|
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||||
return FALSE;
|
sizeChanged(f);
|
||||||
// TODO really do the job
|
|
||||||
cbGetCurSel(f->styleCombobox, &(f->curStyle));
|
|
||||||
// TODO error check; refine
|
|
||||||
InvalidateRect(f->sampleBox, NULL, TRUE);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
if (HIWORD(wParam) == CBN_EDITCHANGE) {
|
||||||
|
sizeEdited(f);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue