mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
(libui) Update comments
This commit is contained in:
parent
1521a8dd38
commit
760fee18dd
100
deps/libui/win32/parent.cpp
vendored
100
deps/libui/win32/parent.cpp
vendored
@ -1,26 +1,26 @@
|
|||||||
// 26 april 2015
|
/* 26 april 2015 */
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// This contains code used by all uiControls that contain other controls.
|
/* This contains code used by all uiControls that contain other controls.
|
||||||
// It also contains the code to draw the background of a container.c container, as that is a variant of the WM_CTLCOLORxxx handler code.
|
* It also contains the code to draw the background of a container.c container, as that is a variant of the WM_CTLCOLORxxx handler code. */
|
||||||
|
|
||||||
static HBRUSH parentBrush = NULL;
|
static HBRUSH parentBrush = NULL;
|
||||||
|
|
||||||
static HWND parentWithBackground(HWND hwnd)
|
static HWND parentWithBackground(HWND hwnd)
|
||||||
{
|
{
|
||||||
HWND parent;
|
int cls;
|
||||||
int cls;
|
HWND parent = hwnd;
|
||||||
|
|
||||||
parent = hwnd;
|
for (;;)
|
||||||
for (;;) {
|
{
|
||||||
parent = parentOf(parent);
|
parent = parentOf(parent);
|
||||||
// skip groupboxes; they're (supposed to be) transparent
|
/* skip groupboxes; they're (supposed to be) transparent
|
||||||
// skip uiContainers; they don't draw anything
|
* skip uiContainers; they don't draw anything */
|
||||||
cls = windowClassOf(parent, L"button", containerClass, NULL);
|
cls = windowClassOf(parent, L"button", containerClass, NULL);
|
||||||
if (cls != 0 && cls != 1)
|
if (cls != 0 && cls != 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct parentDraw {
|
struct parentDraw {
|
||||||
@ -49,7 +49,7 @@ static HRESULT parentDraw(HDC dc, HWND parent, struct parentDraw *pd)
|
|||||||
|
|
||||||
static void endParentDraw(struct parentDraw *pd)
|
static void endParentDraw(struct parentDraw *pd)
|
||||||
{
|
{
|
||||||
// continue in case of any error
|
/* continue in case of any error */
|
||||||
if (pd->prevbitmap != NULL)
|
if (pd->prevbitmap != NULL)
|
||||||
if (((HBITMAP) SelectObject(pd->cdc, pd->prevbitmap)) != pd->bitmap)
|
if (((HBITMAP) SelectObject(pd->cdc, pd->prevbitmap)) != pd->bitmap)
|
||||||
logLastError(L"error selecting previous bitmap back into compatible DC");
|
logLastError(L"error selecting previous bitmap back into compatible DC");
|
||||||
@ -61,7 +61,7 @@ static void endParentDraw(struct parentDraw *pd)
|
|||||||
logLastError(L"error deleting compatible DC");
|
logLastError(L"error deleting compatible DC");
|
||||||
}
|
}
|
||||||
|
|
||||||
// see http://www.codeproject.com/Articles/5978/Correctly-drawn-themed-dialogs-in-WinXP
|
/* see http://www.codeproject.com/Articles/5978/Correctly-drawn-themed-dialogs-in-WinXP */
|
||||||
static HBRUSH getControlBackgroundBrush(HWND hwnd, HDC dc)
|
static HBRUSH getControlBackgroundBrush(HWND hwnd, HDC dc)
|
||||||
{
|
{
|
||||||
HWND parent;
|
HWND parent;
|
||||||
@ -83,10 +83,11 @@ static HBRUSH getControlBackgroundBrush(HWND hwnd, HDC dc)
|
|||||||
}
|
}
|
||||||
endParentDraw(&pd);
|
endParentDraw(&pd);
|
||||||
|
|
||||||
// now figure out where the control is relative to the parent so we can align the brush properly
|
/* now figure out where the control is relative to the parent
|
||||||
// if anything fails, give up and return the brush as-is
|
* so we can align the brush properly
|
||||||
|
* if anything fails, give up and return the brush as-is */
|
||||||
uiWindowsEnsureGetWindowRect(hwnd, &hwndScreenRect);
|
uiWindowsEnsureGetWindowRect(hwnd, &hwndScreenRect);
|
||||||
// this will be in screen coordinates; convert to parent coordinates
|
/* this will be in screen coordinates; convert to parent coordinates */
|
||||||
mapWindowRect(NULL, parent, &hwndScreenRect);
|
mapWindowRect(NULL, parent, &hwndScreenRect);
|
||||||
if (SetBrushOrgEx(dc, -hwndScreenRect.left, -hwndScreenRect.top, NULL) == 0)
|
if (SetBrushOrgEx(dc, -hwndScreenRect.left, -hwndScreenRect.top, NULL) == 0)
|
||||||
logLastError(L"error setting brush origin");
|
logLastError(L"error setting brush origin");
|
||||||
@ -96,19 +97,18 @@ static HBRUSH getControlBackgroundBrush(HWND hwnd, HDC dc)
|
|||||||
|
|
||||||
void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect)
|
void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect)
|
||||||
{
|
{
|
||||||
HWND parent;
|
|
||||||
RECT paintRectParent;
|
RECT paintRectParent;
|
||||||
struct parentDraw pd;
|
struct parentDraw pd;
|
||||||
HRESULT hr;
|
HWND parent = parentWithBackground(hwnd);
|
||||||
|
HRESULT hr = parentDraw(dc, parent, &pd);
|
||||||
|
|
||||||
parent = parentWithBackground(hwnd);
|
if (hr != S_OK) /* we couldn't get it; draw nothing */
|
||||||
hr = parentDraw(dc, parent, &pd);
|
|
||||||
if (hr != S_OK) // we couldn't get it; draw nothing
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
paintRectParent = *paintRect;
|
paintRectParent = *paintRect;
|
||||||
mapWindowRect(hwnd, parent, &paintRectParent);
|
mapWindowRect(hwnd, parent, &paintRectParent);
|
||||||
if (BitBlt(dc, paintRect->left, paintRect->top, paintRect->right - paintRect->left, paintRect->bottom - paintRect->top,
|
if (BitBlt(dc, paintRect->left, paintRect->top,
|
||||||
|
paintRect->right - paintRect->left, paintRect->bottom - paintRect->top,
|
||||||
pd.cdc, paintRectParent.left, paintRectParent.top,
|
pd.cdc, paintRectParent.left, paintRectParent.top,
|
||||||
SRCCOPY) == 0)
|
SRCCOPY) == 0)
|
||||||
logLastError(L"error drawing parent background over uiContainer");
|
logLastError(L"error drawing parent background over uiContainer");
|
||||||
@ -116,29 +116,31 @@ void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect)
|
|||||||
endParentDraw(&pd);
|
endParentDraw(&pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make this public if we want custom containers
|
/* TODO make this public if we want custom containers
|
||||||
// why have this to begin with? http://blogs.msdn.com/b/oldnewthing/archive/2010/03/16/9979112.aspx
|
* why have this to begin with? http://blogs.msdn.com/b/oldnewthing/archive/2010/03/16/9979112.aspx */
|
||||||
BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
|
BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
|
||||||
{
|
{
|
||||||
switch (uMsg) {
|
switch (uMsg)
|
||||||
case WM_COMMAND:
|
{
|
||||||
return runWM_COMMAND(wParam, lParam, lResult);
|
case WM_COMMAND:
|
||||||
case WM_NOTIFY:
|
return runWM_COMMAND(wParam, lParam, lResult);
|
||||||
return runWM_NOTIFY(wParam, lParam, lResult);
|
case WM_NOTIFY:
|
||||||
case WM_HSCROLL:
|
return runWM_NOTIFY(wParam, lParam, lResult);
|
||||||
return runWM_HSCROLL(wParam, lParam, lResult);
|
case WM_HSCROLL:
|
||||||
case WM_CTLCOLORSTATIC:
|
return runWM_HSCROLL(wParam, lParam, lResult);
|
||||||
case WM_CTLCOLORBTN:
|
case WM_CTLCOLORSTATIC:
|
||||||
if (parentBrush != NULL)
|
case WM_CTLCOLORBTN:
|
||||||
if (DeleteObject(parentBrush) == 0)
|
if (parentBrush != NULL)
|
||||||
logLastError(L"error deleting old background brush()"); // but continue anyway; we will leak a brush but whatever
|
if (DeleteObject(parentBrush) == 0)
|
||||||
if (SetBkMode((HDC) wParam, TRANSPARENT) == 0)
|
logLastError(L"error deleting old background brush()"); /* but continue anyway; we will leak a brush but whatever */
|
||||||
logLastError(L"error setting transparent background mode to controls"); // but continue anyway; text will be wrong
|
if (SetBkMode((HDC) wParam, TRANSPARENT) == 0)
|
||||||
parentBrush = getControlBackgroundBrush((HWND) lParam, (HDC) wParam);
|
logLastError(L"error setting transparent background mode to controls"); /* but continue anyway; text will be wrong */
|
||||||
if (parentBrush == NULL) // failed; just do default behavior
|
parentBrush = getControlBackgroundBrush((HWND) lParam, (HDC) wParam);
|
||||||
return FALSE;
|
if (parentBrush == NULL) /* failed; just do default behavior */
|
||||||
*lResult = (LRESULT) parentBrush;
|
return FALSE;
|
||||||
return TRUE;
|
*lResult = (LRESULT) parentBrush;
|
||||||
}
|
return TRUE;
|
||||||
return FALSE;
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
108
deps/libui/win32/tab.cpp
vendored
108
deps/libui/win32/tab.cpp
vendored
@ -1,18 +1,18 @@
|
|||||||
// 16 may 2015
|
/* 16 may 2015 */
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// You don't add controls directly to a tab control on Windows; instead you make them siblings and swap between them on a TCN_SELCHANGING/TCN_SELCHANGE notification pair.
|
/* You don't add controls directly to a tab control on Windows; instead you make them siblings and swap between them on a TCN_SELCHANGING/TCN_SELCHANGE notification pair.
|
||||||
// In addition, you use dialogs because they can be textured properly; other controls cannot. (Things will look wrong if the tab background in the current theme is fancy if you just use the tab background by itself; see http://stackoverflow.com/questions/30087540/why-are-my-programss-tab-controls-rendering-their-background-in-a-blocky-way-b.)
|
* In addition, you use dialogs because they can be textured properly; other controls cannot. (Things will look wrong if the tab background in the current theme is fancy if you just use the tab background by itself; see http://stackoverflow.com/questions/30087540/why-are-my-programss-tab-controls-rendering-their-background-in-a-blocky-way-b.) */
|
||||||
|
|
||||||
struct uiTab {
|
struct uiTab {
|
||||||
uiWindowsControl c;
|
uiWindowsControl c;
|
||||||
HWND hwnd; // of the outer container
|
HWND hwnd; /* of the outer container */
|
||||||
HWND tabHWND; // of the tab control itself
|
HWND tabHWND; /* of the tab control itself */
|
||||||
std::vector<struct tabPage *> *pages;
|
std::vector<struct tabPage *> *pages;
|
||||||
HWND parent;
|
HWND parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
// utility functions
|
/* utility functions */
|
||||||
|
|
||||||
static LRESULT curpage(uiTab *t)
|
static LRESULT curpage(uiTab *t)
|
||||||
{
|
{
|
||||||
@ -26,11 +26,14 @@ static struct tabPage *tabPage(uiTab *t, int i)
|
|||||||
|
|
||||||
static void tabPageRect(uiTab *t, RECT *r)
|
static void tabPageRect(uiTab *t, RECT *r)
|
||||||
{
|
{
|
||||||
// this rect needs to be in parent window coordinates, but TCM_ADJUSTRECT wants a window rect, which is screen coordinates
|
/* this rect needs to be in parent window coordinates, but TCM_ADJUSTRECT
|
||||||
// because we have each page as a sibling of the tab, use the tab's own rect as the input rect
|
* wants a window rect, which is screen coordinates
|
||||||
|
* because we have each page as a sibling of the tab, use the tab's
|
||||||
|
* own rect as the input rect */
|
||||||
uiWindowsEnsureGetWindowRect(t->tabHWND, r);
|
uiWindowsEnsureGetWindowRect(t->tabHWND, r);
|
||||||
SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) FALSE, (LPARAM) r);
|
SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) FALSE, (LPARAM) r);
|
||||||
// and get it in terms of the container instead of the screen
|
|
||||||
|
/* and get it in terms of the container instead of the screen */
|
||||||
mapWindowRect(NULL, t->hwnd, r);
|
mapWindowRect(NULL, t->hwnd, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,11 +42,11 @@ static void tabRelayout(uiTab *t)
|
|||||||
struct tabPage *page;
|
struct tabPage *page;
|
||||||
RECT r;
|
RECT r;
|
||||||
|
|
||||||
// first move the tab control itself
|
/* first move the tab control itself */
|
||||||
uiWindowsEnsureGetClientRect(t->hwnd, &r);
|
uiWindowsEnsureGetClientRect(t->hwnd, &r);
|
||||||
uiWindowsEnsureMoveWindowDuringResize(t->tabHWND, r.left, r.top, r.right - r.left, r.bottom - r.top);
|
uiWindowsEnsureMoveWindowDuringResize(t->tabHWND, r.left, r.top, r.right - r.left, r.bottom - r.top);
|
||||||
|
|
||||||
// then the current page
|
/* then the current page */
|
||||||
if (t->pages->size() == 0)
|
if (t->pages->size() == 0)
|
||||||
return;
|
return;
|
||||||
page = tabPage(t, curpage(t));
|
page = tabPage(t, curpage(t));
|
||||||
@ -53,21 +56,22 @@ static void tabRelayout(uiTab *t)
|
|||||||
|
|
||||||
static void showHidePage(uiTab *t, LRESULT which, int hide)
|
static void showHidePage(uiTab *t, LRESULT which, int hide)
|
||||||
{
|
{
|
||||||
struct tabPage *page;
|
struct tabPage *page = NULL;
|
||||||
|
|
||||||
if (which == (LRESULT) (-1))
|
if (which == (LRESULT) (-1))
|
||||||
return;
|
return;
|
||||||
page = tabPage(t, which);
|
page = tabPage(t, which);
|
||||||
if (hide)
|
if (hide)
|
||||||
ShowWindow(page->hwnd, SW_HIDE);
|
ShowWindow(page->hwnd, SW_HIDE);
|
||||||
else {
|
else
|
||||||
ShowWindow(page->hwnd, SW_SHOW);
|
{
|
||||||
// we only resize the current page, so we have to resize it; before we can do that, we need to make sure we are of the right size
|
ShowWindow(page->hwnd, SW_SHOW);
|
||||||
uiWindowsControlMinimumSizeChanged(uiWindowsControl(t));
|
/* we only resize the current page, so we have to resize it; before we can do that, we need to make sure we are of the right size */
|
||||||
}
|
uiWindowsControlMinimumSizeChanged(uiWindowsControl(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// control implementation
|
/* control implementation */
|
||||||
|
|
||||||
static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nm, LRESULT *lResult)
|
static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nm, LRESULT *lResult)
|
||||||
{
|
{
|
||||||
@ -129,22 +133,23 @@ uiWindowsControlDefaultSetParentHWND(uiTab)
|
|||||||
|
|
||||||
static void uiTabMinimumSize(uiWindowsControl *c, int *width, int *height)
|
static void uiTabMinimumSize(uiWindowsControl *c, int *width, int *height)
|
||||||
{
|
{
|
||||||
uiTab *t = uiTab(c);
|
|
||||||
int pagewid, pageht;
|
|
||||||
struct tabPage *page;
|
|
||||||
RECT r;
|
RECT r;
|
||||||
|
struct tabPage *page = NULL;
|
||||||
|
uiTab *t = uiTab(c);
|
||||||
|
|
||||||
// only consider the current page
|
/* only consider the current page */
|
||||||
pagewid = 0;
|
int pagewid = 0;
|
||||||
pageht = 0;
|
int pageht = 0;
|
||||||
if (t->pages->size() != 0) {
|
|
||||||
|
if (t->pages->size() != 0)
|
||||||
|
{
|
||||||
page = tabPage(t, curpage(t));
|
page = tabPage(t, curpage(t));
|
||||||
tabPageMinimumSize(page, &pagewid, &pageht);
|
tabPageMinimumSize(page, &pagewid, &pageht);
|
||||||
}
|
}
|
||||||
|
|
||||||
r.left = 0;
|
r.left = 0;
|
||||||
r.top = 0;
|
r.top = 0;
|
||||||
r.right = pagewid;
|
r.right = pagewid;
|
||||||
r.bottom = pageht;
|
r.bottom = pageht;
|
||||||
// this also includes the tabs themselves
|
// this also includes the tabs themselves
|
||||||
SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) TRUE, (LPARAM) (&r));
|
SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) TRUE, (LPARAM) (&r));
|
||||||
@ -154,13 +159,14 @@ static void uiTabMinimumSize(uiWindowsControl *c, int *width, int *height)
|
|||||||
|
|
||||||
static void uiTabMinimumSizeChanged(uiWindowsControl *c)
|
static void uiTabMinimumSizeChanged(uiWindowsControl *c)
|
||||||
{
|
{
|
||||||
uiTab *t = uiTab(c);
|
uiTab *t = uiTab(c);
|
||||||
|
|
||||||
if (uiWindowsControlTooSmall(uiWindowsControl(t))) {
|
if (uiWindowsControlTooSmall(uiWindowsControl(t)))
|
||||||
uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(t));
|
{
|
||||||
return;
|
uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(t));
|
||||||
}
|
return;
|
||||||
tabRelayout(t);
|
}
|
||||||
|
tabRelayout(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
uiWindowsControlDefaultLayoutRect(uiTab)
|
uiWindowsControlDefaultLayoutRect(uiTab)
|
||||||
@ -168,16 +174,16 @@ uiWindowsControlDefaultAssignControlIDZOrder(uiTab)
|
|||||||
|
|
||||||
static void uiTabChildVisibilityChanged(uiWindowsControl *c)
|
static void uiTabChildVisibilityChanged(uiWindowsControl *c)
|
||||||
{
|
{
|
||||||
// TODO eliminate the redundancy
|
/* TODO eliminate the redundancy */
|
||||||
uiWindowsControlMinimumSizeChanged(c);
|
uiWindowsControlMinimumSizeChanged(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tabArrangePages(uiTab *t)
|
static void tabArrangePages(uiTab *t)
|
||||||
{
|
{
|
||||||
LONG_PTR controlID = 100;
|
LONG_PTR controlID = 100;
|
||||||
HWND insertAfter = NULL;
|
HWND insertAfter = NULL;
|
||||||
|
|
||||||
// TODO is this first or last?
|
/* TODO is this first or last? */
|
||||||
uiWindowsEnsureAssignControlIDZOrder(t->tabHWND, &controlID, &insertAfter);
|
uiWindowsEnsureAssignControlIDZOrder(t->tabHWND, &controlID, &insertAfter);
|
||||||
for (struct tabPage *&page : *(t->pages))
|
for (struct tabPage *&page : *(t->pages))
|
||||||
uiWindowsEnsureAssignControlIDZOrder(page->hwnd, &controlID, &insertAfter);
|
uiWindowsEnsureAssignControlIDZOrder(page->hwnd, &controlID, &insertAfter);
|
||||||
@ -191,12 +197,11 @@ void uiTabAppend(uiTab *t, const char *name, uiControl *child)
|
|||||||
void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child)
|
void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child)
|
||||||
{
|
{
|
||||||
struct tabPage *page;
|
struct tabPage *page;
|
||||||
LRESULT hide, show;
|
LRESULT show;
|
||||||
TCITEMW item;
|
TCITEMW item;
|
||||||
WCHAR *wname;
|
WCHAR *wname;
|
||||||
|
/* see below */
|
||||||
// see below
|
LRESULT hide = curpage(t);
|
||||||
hide = curpage(t);
|
|
||||||
|
|
||||||
if (child != NULL)
|
if (child != NULL)
|
||||||
uiControlSetParent(child, uiControl(t));
|
uiControlSetParent(child, uiControl(t));
|
||||||
@ -214,9 +219,12 @@ void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child)
|
|||||||
logLastError(L"error adding tab to uiTab");
|
logLastError(L"error adding tab to uiTab");
|
||||||
uiFree(wname);
|
uiFree(wname);
|
||||||
|
|
||||||
// we need to do this because adding the first tab doesn't send a TCN_SELCHANGE; it just shows the page
|
/* we need to do this because adding the first tab
|
||||||
|
* doesn't send a TCN_SELCHANGE; it just shows the page */
|
||||||
show = curpage(t);
|
show = curpage(t);
|
||||||
if (show != hide) {
|
|
||||||
|
if (show != hide)
|
||||||
|
{
|
||||||
showHidePage(t, hide, 1);
|
showHidePage(t, hide, 1);
|
||||||
showHidePage(t, show, 0);
|
showHidePage(t, show, 0);
|
||||||
}
|
}
|
||||||
@ -226,12 +234,12 @@ void uiTabDelete(uiTab *t, int n)
|
|||||||
{
|
{
|
||||||
struct tabPage *page;
|
struct tabPage *page;
|
||||||
|
|
||||||
// first delete the tab from the tab control
|
/* first delete the tab from the tab control
|
||||||
// if this is the current tab, no tab will be selected, which is good
|
* if this is the current tab, no tab will be selected, which is good */
|
||||||
if (SendMessageW(t->tabHWND, TCM_DELETEITEM, (WPARAM) n, 0) == FALSE)
|
if (SendMessageW(t->tabHWND, TCM_DELETEITEM, (WPARAM) n, 0) == FALSE)
|
||||||
logLastError(L"error deleting uiTab tab");
|
logLastError(L"error deleting uiTab tab");
|
||||||
|
|
||||||
// now delete the page itself
|
/* now delete the page itself */
|
||||||
page = tabPage(t, n);
|
page = tabPage(t, n);
|
||||||
if (page->child != NULL)
|
if (page->child != NULL)
|
||||||
uiControlSetParent(page->child, NULL);
|
uiControlSetParent(page->child, NULL);
|
||||||
@ -251,11 +259,13 @@ int uiTabMargined(uiTab *t, int n)
|
|||||||
|
|
||||||
void uiTabSetMargined(uiTab *t, int n, int margined)
|
void uiTabSetMargined(uiTab *t, int n, int margined)
|
||||||
{
|
{
|
||||||
struct tabPage *page;
|
struct tabPage *page = tabPage(t, n);
|
||||||
|
|
||||||
page = tabPage(t, n);
|
|
||||||
page->margined = margined;
|
page->margined = margined;
|
||||||
// even if the page doesn't have a child it might still have a new minimum size with margins; this is the easiest way to verify it
|
|
||||||
|
/* even if the page doesn't have a child it might still
|
||||||
|
* have a new minimum size with margins; this is the
|
||||||
|
* easiest way to verify it */
|
||||||
uiWindowsControlMinimumSizeChanged(uiWindowsControl(t));
|
uiWindowsControlMinimumSizeChanged(uiWindowsControl(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
130
deps/libui/win32/text.cpp
vendored
130
deps/libui/win32/text.cpp
vendored
@ -1,36 +1,37 @@
|
|||||||
// 9 april 2015
|
/* 9 april 2015 */
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len)
|
WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len)
|
||||||
{
|
{
|
||||||
LRESULT n;
|
WCHAR *text = NULL;
|
||||||
WCHAR *text;
|
LRESULT n = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||||
|
|
||||||
n = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
|
if (len != NULL)
|
||||||
if (len != NULL)
|
*len = n;
|
||||||
*len = n;
|
/* WM_GETTEXTLENGTH does not include the null terminator */
|
||||||
// WM_GETTEXTLENGTH does not include the null terminator
|
text = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
|
||||||
text = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
|
/* note the comparison: the size includes the
|
||||||
// note the comparison: the size includes the null terminator, but the return does not
|
* null terminator, but the return does not */
|
||||||
if (GetWindowTextW(hwnd, text, n + 1) != n) {
|
if (GetWindowTextW(hwnd, text, n + 1) != n)
|
||||||
logLastError(L"error getting window text");
|
{
|
||||||
// on error, return an empty string to be safe
|
logLastError(L"error getting window text");
|
||||||
*text = L'\0';
|
/* on error, return an empty string to be safe */
|
||||||
if (len != NULL)
|
*text = L'\0';
|
||||||
*len = 0;
|
if (len != NULL)
|
||||||
}
|
*len = 0;
|
||||||
return text;
|
}
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
WCHAR *windowText(HWND hwnd)
|
WCHAR *windowText(HWND hwnd)
|
||||||
{
|
{
|
||||||
return windowTextAndLen(hwnd, NULL);
|
return windowTextAndLen(hwnd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowText(HWND hwnd, WCHAR *wtext)
|
void setWindowText(HWND hwnd, WCHAR *wtext)
|
||||||
{
|
{
|
||||||
if (SetWindowTextW(hwnd, wtext) == 0)
|
if (SetWindowTextW(hwnd, wtext) == 0)
|
||||||
logLastError(L"error setting window text");
|
logLastError(L"error setting window text");
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiFreeText(char *text)
|
void uiFreeText(char *text)
|
||||||
@ -40,68 +41,65 @@ void uiFreeText(char *text)
|
|||||||
|
|
||||||
int uiWindowsWindowTextWidth(HWND hwnd)
|
int uiWindowsWindowTextWidth(HWND hwnd)
|
||||||
{
|
{
|
||||||
LRESULT len;
|
LRESULT len;
|
||||||
WCHAR *text;
|
HDC dc;
|
||||||
HDC dc;
|
HFONT prevfont;
|
||||||
HFONT prevfont;
|
SIZE size;
|
||||||
SIZE size;
|
WCHAR *text = windowTextAndLen(hwnd, &len);
|
||||||
|
|
||||||
size.cx = 0;
|
size.cx = 0;
|
||||||
size.cy = 0;
|
size.cy = 0;
|
||||||
|
|
||||||
text = windowTextAndLen(hwnd, &len);
|
if (len == 0) /* no text; nothing to do */
|
||||||
if (len == 0) // no text; nothing to do
|
goto noTextOrError;
|
||||||
goto noTextOrError;
|
|
||||||
|
|
||||||
// now we can do the calculations
|
/* now we can do the calculations */
|
||||||
dc = GetDC(hwnd);
|
dc = GetDC(hwnd);
|
||||||
if (dc == NULL) {
|
if (dc == NULL)
|
||||||
logLastError(L"error getting DC");
|
{
|
||||||
// on any error, assume no text
|
logLastError(L"error getting DC");
|
||||||
goto noTextOrError;
|
/* on any error, assume no text */
|
||||||
}
|
goto noTextOrError;
|
||||||
prevfont = (HFONT) SelectObject(dc, hMessageFont);
|
}
|
||||||
if (prevfont == NULL) {
|
prevfont = (HFONT) SelectObject(dc, hMessageFont);
|
||||||
logLastError(L"error loading control font into device context");
|
if (prevfont == NULL)
|
||||||
ReleaseDC(hwnd, dc);
|
{
|
||||||
goto noTextOrError;
|
logLastError(L"error loading control font into device context");
|
||||||
}
|
ReleaseDC(hwnd, dc);
|
||||||
if (GetTextExtentPoint32W(dc, text, len, &size) == 0) {
|
goto noTextOrError;
|
||||||
logLastError(L"error getting text extent point");
|
}
|
||||||
// continue anyway, assuming size is 0
|
if (GetTextExtentPoint32W(dc, text, len, &size) == 0)
|
||||||
size.cx = 0;
|
{
|
||||||
size.cy = 0;
|
logLastError(L"error getting text extent point");
|
||||||
}
|
/* continue anyway, assuming size is 0 */
|
||||||
// continue on errors; we got what we want
|
size.cx = 0;
|
||||||
if (SelectObject(dc, prevfont) != hMessageFont)
|
size.cy = 0;
|
||||||
logLastError(L"error restoring previous font into device context");
|
}
|
||||||
if (ReleaseDC(hwnd, dc) == 0)
|
/* continue on errors; we got what we want */
|
||||||
logLastError(L"error releasing DC");
|
if (SelectObject(dc, prevfont) != hMessageFont)
|
||||||
|
logLastError(L"error restoring previous font into device context");
|
||||||
|
if (ReleaseDC(hwnd, dc) == 0)
|
||||||
|
logLastError(L"error releasing DC");
|
||||||
|
|
||||||
uiFree(text);
|
uiFree(text);
|
||||||
return size.cx;
|
return size.cx;
|
||||||
|
|
||||||
noTextOrError:
|
noTextOrError:
|
||||||
uiFree(text);
|
uiFree(text);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *uiWindowsWindowText(HWND hwnd)
|
char *uiWindowsWindowText(HWND hwnd)
|
||||||
{
|
{
|
||||||
WCHAR *wtext;
|
WCHAR *wtext = windowText(hwnd);
|
||||||
char *text;
|
char *text = toUTF8(wtext);
|
||||||
|
|
||||||
wtext = windowText(hwnd);
|
|
||||||
text = toUTF8(wtext);
|
|
||||||
uiFree(wtext);
|
uiFree(wtext);
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiWindowsSetWindowText(HWND hwnd, const char *text)
|
void uiWindowsSetWindowText(HWND hwnd, const char *text)
|
||||||
{
|
{
|
||||||
WCHAR *wtext;
|
WCHAR *wtext = toUTF16(text);
|
||||||
|
|
||||||
wtext = toUTF16(text);
|
|
||||||
setWindowText(hwnd, wtext);
|
setWindowText(hwnd, wtext);
|
||||||
uiFree(wtext);
|
uiFree(wtext);
|
||||||
}
|
}
|
||||||
|
46
deps/libui/win32/utf16.cpp
vendored
46
deps/libui/win32/utf16.cpp
vendored
@ -1,7 +1,7 @@
|
|||||||
// 21 april 2016
|
/* 21 april 2016 */
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// see http://stackoverflow.com/a/29556509/3408572
|
/* see http://stackoverflow.com/a/29556509/3408572 */
|
||||||
|
|
||||||
#define MBTWC(str, wstr, bufsiz) MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, bufsiz)
|
#define MBTWC(str, wstr, bufsiz) MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, bufsiz)
|
||||||
|
|
||||||
@ -18,9 +18,10 @@ WCHAR *toUTF16(const char *str)
|
|||||||
return emptyUTF16();
|
return emptyUTF16();
|
||||||
}
|
}
|
||||||
wstr = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]");
|
wstr = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]");
|
||||||
if (MBTWC(str, wstr, n) != n) {
|
if (MBTWC(str, wstr, n) != n)
|
||||||
|
{
|
||||||
logLastError(L"error converting from UTF-8 to UTF-16");
|
logLastError(L"error converting from UTF-8 to UTF-16");
|
||||||
// and return an empty string
|
/* and return an empty string */
|
||||||
*wstr = L'\0';
|
*wstr = L'\0';
|
||||||
}
|
}
|
||||||
return wstr;
|
return wstr;
|
||||||
@ -33,7 +34,7 @@ char *toUTF8(const WCHAR *wstr)
|
|||||||
char *str;
|
char *str;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (*wstr == L'\0') // empty string
|
if (*wstr == L'\0') /* empty string */
|
||||||
return emptyUTF8();
|
return emptyUTF8();
|
||||||
n = WCTMB(wstr, NULL, 0);
|
n = WCTMB(wstr, NULL, 0);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
@ -41,11 +42,12 @@ char *toUTF8(const WCHAR *wstr)
|
|||||||
return emptyUTF8();
|
return emptyUTF8();
|
||||||
}
|
}
|
||||||
str = (char *) uiAlloc(n * sizeof (char), "char[]");
|
str = (char *) uiAlloc(n * sizeof (char), "char[]");
|
||||||
if (WCTMB(wstr, str, n) != n) {
|
if (WCTMB(wstr, str, n) != n)
|
||||||
logLastError(L"error converting from UTF-16 to UTF-8");
|
{
|
||||||
// and return an empty string
|
logLastError(L"error converting from UTF-16 to UTF-8");
|
||||||
*str = '\0';
|
/* and return an empty string */
|
||||||
}
|
*str = '\0';
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,17 +83,18 @@ WCHAR *vstrf(const WCHAR *format, va_list ap)
|
|||||||
va_copy(ap2, ap);
|
va_copy(ap2, ap);
|
||||||
n = _vscwprintf(format, ap2);
|
n = _vscwprintf(format, ap2);
|
||||||
va_end(ap2);
|
va_end(ap2);
|
||||||
n++; // terminating L'\0'
|
n++; /* terminating L'\0' */
|
||||||
|
|
||||||
buf = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]");
|
buf = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]");
|
||||||
// includes terminating L'\0' according to example in https://msdn.microsoft.com/en-us/library/xa1a1a6z.aspx
|
/* includes terminating L'\0' according
|
||||||
|
* to example in https://msdn.microsoft.com/en-us/library/xa1a1a6z.aspx */
|
||||||
vswprintf_s(buf, n, format, ap);
|
vswprintf_s(buf, n, format, ap);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's shove these utility routines here too.
|
/* Let's shove these utility routines here too.
|
||||||
// Prerequisite: lfonly is UTF-8.
|
* Prerequisite: lfonly is UTF-8. */
|
||||||
char *LFtoCRLF(const char *lfonly)
|
char *LFtoCRLF(const char *lfonly)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -109,25 +112,26 @@ char *LFtoCRLF(const char *lfonly)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prerequisite: s is UTF-8.
|
/* Prerequisite: s is UTF-8. */
|
||||||
void CRLFtoLF(char *s)
|
void CRLFtoLF(char *s)
|
||||||
{
|
{
|
||||||
char *t = s;
|
char *t = s;
|
||||||
|
|
||||||
for (; *s != '\0'; s++) {
|
for (; *s != '\0'; s++)
|
||||||
// be sure to preserve \rs that are genuinely there
|
{
|
||||||
|
/* be sure to preserve \rs that are genuinely there */
|
||||||
if (*s == '\r' && *(s + 1) == '\n')
|
if (*s == '\r' && *(s + 1) == '\n')
|
||||||
continue;
|
continue;
|
||||||
*t++ = *s;
|
*t++ = *s;
|
||||||
}
|
}
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
// pad out the rest of t, just to be safe
|
/* pad out the rest of t, just to be safe */
|
||||||
while (t != s)
|
while (t != s)
|
||||||
*t++ = '\0';
|
*t++ = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::to_string() always uses %f; we want %g
|
/* std::to_string() always uses %f; we want %g
|
||||||
// fortunately std::iostream seems to use %g by default so
|
* fortunately std::iostream seems to use %g by default so */
|
||||||
WCHAR *ftoutf16(double d)
|
WCHAR *ftoutf16(double d)
|
||||||
{
|
{
|
||||||
std::wostringstream ss;
|
std::wostringstream ss;
|
||||||
@ -145,6 +149,6 @@ WCHAR *itoutf16(int i)
|
|||||||
std::wstring s;
|
std::wstring s;
|
||||||
|
|
||||||
ss << i;
|
ss << i;
|
||||||
s = ss.str(); // to be safe
|
s = ss.str(); /* to be safe */
|
||||||
return utf16dup(s.c_str());
|
return utf16dup(s.c_str());
|
||||||
}
|
}
|
||||||
|
21
deps/libui/win32/utilwin.cpp
vendored
21
deps/libui/win32/utilwin.cpp
vendored
@ -1,13 +1,14 @@
|
|||||||
// 14 may 2015
|
/* 14 may 2015 */
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
// The utility window is a special window that performs certain tasks internal to libui.
|
/* The utility window is a special window that performs certain tasks internal to libui.
|
||||||
// It is not a message-only window, and it is always hidden and disabled.
|
* It is not a message-only window, and it is always hidden and disabled.
|
||||||
// Its roles:
|
* Its roles:
|
||||||
// - It is the initial parent of all controls. When a control loses its parent, it also becomes that control's parent.
|
* - It is the initial parent of all controls. When a control loses its parent, it also becomes that control's parent.
|
||||||
// - It handles WM_QUERYENDSESSION and console end session requests.
|
* - It handles WM_QUERYENDSESSION and console end session requests.
|
||||||
// - It handles WM_WININICHANGE and forwards the message to any child windows that request it.
|
* - It handles WM_WININICHANGE and forwards the message to any child windows that request it.
|
||||||
// - It handles executing functions queued to run by uiQueueMain().
|
* - It handles executing functions queued to run by uiQueueMain().
|
||||||
|
*/
|
||||||
|
|
||||||
#define utilWindowClass L"libui_utilWindowClass"
|
#define utilWindowClass L"libui_utilWindowClass"
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
|||||||
wc.hCursor = hDefaultCursor;
|
wc.hCursor = hDefaultCursor;
|
||||||
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||||
if (RegisterClass(&wc) == 0)
|
if (RegisterClass(&wc) == 0)
|
||||||
// see init.cpp for an explanation of the =s
|
/* see init.cpp for an explanation of the =s */
|
||||||
return "=registering utility window class";
|
return "=registering utility window class";
|
||||||
|
|
||||||
utilWindow = CreateWindowExW(0,
|
utilWindow = CreateWindowExW(0,
|
||||||
@ -64,7 +65,7 @@ const char *initUtilWindow(HICON hDefaultIcon, HCURSOR hDefaultCursor)
|
|||||||
NULL, NULL, hInstance, NULL);
|
NULL, NULL, hInstance, NULL);
|
||||||
if (utilWindow == NULL)
|
if (utilWindow == NULL)
|
||||||
return "=creating utility window";
|
return "=creating utility window";
|
||||||
// and just to be safe
|
/* and just to be safe */
|
||||||
EnableWindow(utilWindow, FALSE);
|
EnableWindow(utilWindow, FALSE);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
39
deps/libui/win32/winpublic.cpp
vendored
39
deps/libui/win32/winpublic.cpp
vendored
@ -1,4 +1,4 @@
|
|||||||
// 6 april 2015
|
/* 6 april 2015 */
|
||||||
#include "uipriv_windows.hpp"
|
#include "uipriv_windows.hpp"
|
||||||
|
|
||||||
void uiWindowsEnsureDestroyWindow(HWND hwnd)
|
void uiWindowsEnsureDestroyWindow(HWND hwnd)
|
||||||
@ -35,27 +35,30 @@ void uiWindowsEnsureMoveWindowDuringResize(HWND hwnd, int x, int y, int width, i
|
|||||||
logLastError(L"error moving window");
|
logLastError(L"error moving window");
|
||||||
}
|
}
|
||||||
|
|
||||||
// do these function even error out in any case other than invalid parameters?! I thought all windows had rects
|
/* do these function even error out in any case
|
||||||
|
* other than invalid parameters?! I thought all windows had rects */
|
||||||
void uiWindowsEnsureGetClientRect(HWND hwnd, RECT *r)
|
void uiWindowsEnsureGetClientRect(HWND hwnd, RECT *r)
|
||||||
{
|
{
|
||||||
if (GetClientRect(hwnd, r) == 0) {
|
if (GetClientRect(hwnd, r) == 0)
|
||||||
logLastError(L"error getting window client rect");
|
{
|
||||||
// zero out the rect on error just to be safe
|
logLastError(L"error getting window client rect");
|
||||||
r->left = 0;
|
/* zero out the rect on error just to be safe */
|
||||||
r->top = 0;
|
r->left = 0;
|
||||||
r->right = 0;
|
r->top = 0;
|
||||||
r->bottom = 0;
|
r->right = 0;
|
||||||
}
|
r->bottom = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r)
|
void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r)
|
||||||
{
|
{
|
||||||
if (GetWindowRect(hwnd, r) == 0) {
|
if (GetWindowRect(hwnd, r) == 0)
|
||||||
logLastError(L"error getting window rect");
|
{
|
||||||
// zero out the rect on error just to be safe
|
logLastError(L"error getting window rect");
|
||||||
r->left = 0;
|
/* zero out the rect on error just to be safe */
|
||||||
r->top = 0;
|
r->left = 0;
|
||||||
r->right = 0;
|
r->top = 0;
|
||||||
r->bottom = 0;
|
r->right = 0;
|
||||||
}
|
r->bottom = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user