diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_devices/welcomeWidget.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_devices/welcomeWidget.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_devices/welcomeWidget.cpp | 760 |
1 files changed, 760 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_devices/welcomeWidget.cpp b/Src/Plugins/Library/ml_devices/welcomeWidget.cpp new file mode 100644 index 00000000..a4ea327b --- /dev/null +++ b/Src/Plugins/Library/ml_devices/welcomeWidget.cpp @@ -0,0 +1,760 @@ +#include "main.h" +#include "./welcomeWidget.h" +#include "../winamp/commandLink.h" + +#include <strsafe.h> + +#define WELCOMEWIDGET_OFFSET_LEFT_DLU 4 +#define WELCOMEWIDGET_OFFSET_TOP_DLU 2 +#define WELCOMEWIDGET_OFFSET_RIGHT_DLU 4 +#define WELCOMEWIDGET_OFFSET_BOTTOM_DLU 2 + +#define WELCOMEWIDGET_IMAGE_MIN_WIDTH 280 +#define WELCOMEWIDGET_IMAGE_MIN_HEIGHT (424 - 200) + +#define WELCOMEWIDGET_TITLE_MAX_HEIGHT 168 +#define WELCOMEWIDGET_TITLE_MIN_WIDTH WELCOMEWIDGET_IMAGE_MIN_WIDTH + +#define WELCOMEWIDGET_TEXT_MAX_HEIGHT 66 +#define WELCOMEWIDGET_TEXT_MIN_WIDTH WELCOMEWIDGET_IMAGE_MIN_WIDTH + +#define WELCOMEWIDGET_HELP_LINK 1000 + +typedef struct WelcomeWidget +{ + HDC context; + long contextWidth; + long contextHeight; + HBITMAP previousBitmap; + HFONT helpFont; +} WelcomeWidget; + +static BOOL +WelcomeWidget_GetBestTextRect(HDC hdc, const wchar_t *text, unsigned int length, + RECT *rect, long maxWidth, unsigned int format) +{ + RECT testRect; + long right; + + if (NULL == rect) + return FALSE; + + format |= DT_CALCRECT; + + if (length < 0) + length = (NULL != text) ? lstrlen(text) : 0; + + if (0 == length || NULL == text) + { + rect->right = rect->left; + rect->bottom = rect->top; + return TRUE; + } + + + SetRect(&testRect, rect->left, rect->top, rect->right, rect->top); + maxWidth += rect->left; + right = rect->right; + + for(;;) + { + if (FALSE == DrawText(hdc, text, length, &testRect, format)) + return FALSE; + + if (testRect.bottom <= rect->bottom || right >= maxWidth) + { + CopyRect(rect, &testRect); + break; + } + + long increment = maxWidth - right; + if (increment > 60) + increment = increment / 4; + else if (increment > 4) + increment = increment / 2; + + right += increment; + testRect.right = right; + testRect.bottom = rect->top; + } + + return TRUE; +} + +static COLORREF +WelcomeWidget_GetTextColor(WidgetStyle *style, COLORREF *shadowColor, BOOL titleMode) +{ + COLORREF frontColor, backColor; + WORD backHue, backLuma, backSat, frontHue, frontLuma, frontSat; + + backColor = WIDGETSTYLE_BACK_COLOR(style); + frontColor = WIDGETSTYLE_TEXT_COLOR(style); + + ColorRGBToHLS(backColor, &backHue, &backLuma, &backSat); + ColorRGBToHLS(frontColor, &frontHue, &frontLuma, &frontSat); + + if(frontLuma > backLuma) + { + if (NULL != shadowColor) + { + if (FALSE != titleMode || backLuma > 180) + *shadowColor = Graphics_BlendColors(0x000000, backColor, 102); + else + *shadowColor = backColor; + } + + return Graphics_BlendColors((FALSE != titleMode) ? 0xBBBBBB : 0xEEEEEE, frontColor, 230); + } + + if (NULL != shadowColor) + { + if (FALSE != titleMode || backLuma < 60) + *shadowColor = Graphics_BlendColors(0xFFFFFF, backColor, 102); + else + *shadowColor = backColor; + } + + return Graphics_BlendColors((FALSE != titleMode) ? 0x333333 : 0x111111, frontColor, 230); +} + +static HFONT +WelcomeWidget_CreateTitleFont(WidgetStyle *style, HDC hdc) +{ + LOGFONT lf; + HFONT textFont; + long height, pixelsY; + + pixelsY = GetDeviceCaps(hdc, LOGPIXELSY); + height = MulDiv(16, pixelsY, 96); + + textFont = WIDGETSTYLE_TITLE_FONT(style); + if (NULL != textFont) + { + HFONT prevFont; + TEXTMETRIC tm; + + prevFont = SelectFont(hdc, textFont); + if (FALSE != GetTextMetricsW(hdc, &tm)) + { + long test = MulDiv(tm.tmHeight - tm.tmInternalLeading, 96, pixelsY); + test = MulDiv((test + 2), pixelsY, 72); + if (test > height) + height = test; + } + SelectFont(hdc, prevFont); + } + + lf.lfHeight = -height; + lf.lfWidth = 0; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfWeight = FW_DONTCARE; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfQuality = Graphics_GetSysFontQuality(); + lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + StringCchCopy(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), L"Arial"); + + return CreateFontIndirect(&lf); +} + +static BOOL +WelcomeWidget_FillContext(HDC targetDC, long width, long height, HDC sourceDC, + HBITMAP backBitmap, long backWidth, long backHeight, WidgetStyle *style) +{ + RECT rect, partRect; + wchar_t buffer[4096] = {0}; + int bufferLength; + COLORREF textColor, shadowColor; + HFONT prevFont; + + if (NULL == targetDC || + NULL == sourceDC || + NULL == style) + { + return FALSE; + } + + SetRect(&rect, 0, 0, width, height); + + FillRect(targetDC, &rect, WIDGETSTYLE_BACK_BRUSH(style)); + + + if (NULL != backBitmap) + { + Image_AlphaBlend(targetDC, &rect, sourceDC, NULL, 255, backBitmap, NULL, + AlphaBlend_AlignCenter | AlphaBlend_AlignVCenter, NULL); + } + + SetBkMode(targetDC, TRANSPARENT); + + + WASABI_API_LNGSTRINGW_BUF(IDS_WELCOMEWIDGET_TITLE, buffer, ARRAYSIZE(buffer)); + if (L'\0' != buffer[0]) + { + BOOL textMode; + + textMode = TRUE; + + if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, buffer, -1, L"WINAMP DEVICE MANAGER", -1)) + { + HBITMAP titleBitmap; + titleBitmap = Image_LoadEx(Plugin_GetInstance(), MAKEINTRESOURCE(IDR_WELCOME_WIDGET_TITLE_IMAGE), + SRC_TYPE_PNG, ISF_PREMULTIPLY, 0, 0); + if (NULL != titleBitmap) + { + SetRect(&partRect, rect.left, rect.top, rect.right, rect.top + WELCOMEWIDGET_TITLE_MAX_HEIGHT); + + if (FALSE != Image_AlphaBlend(targetDC, &partRect, sourceDC, NULL, 255, titleBitmap, NULL, + AlphaBlend_AlignCenter | AlphaBlend_AlignVCenter, NULL)) + { + textMode = FALSE; + } + + DeleteObject(titleBitmap); + } + } + + if (FALSE != textMode) + { + HFONT titleFont; + + bufferLength = lstrlen(buffer); + + titleFont = WelcomeWidget_CreateTitleFont(style, targetDC); + + textColor = WelcomeWidget_GetTextColor(style, &shadowColor, TRUE); + prevFont = SelectFont(targetDC, (NULL != titleFont) ? titleFont : WIDGETSTYLE_TITLE_FONT(style)); + + SetRect(&partRect, 0, 0, width, 0); + + if (FALSE != DrawText(targetDC, buffer, bufferLength, &partRect, + DT_CALCRECT | DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS)) + { + if (partRect.bottom > WELCOMEWIDGET_TITLE_MAX_HEIGHT) + { + TEXTMETRIC textMetrics; + if (FALSE != GetTextMetrics(targetDC, &textMetrics)) + partRect.bottom = (WELCOMEWIDGET_TITLE_MAX_HEIGHT/textMetrics.tmHeight)*textMetrics.tmHeight; + } + + OffsetRect(&partRect, + rect.left + (RECTWIDTH(rect) - RECTWIDTH(partRect))/2, + rect.top + (WELCOMEWIDGET_TITLE_MAX_HEIGHT - RECTHEIGHT(partRect))/2); + + OffsetRect(&partRect, 0, 2); + SetTextColor(targetDC, shadowColor); + DrawText(targetDC, buffer, bufferLength, &partRect, + DT_CENTER | DT_TOP | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS); + + OffsetRect(&partRect, 0, -2); + + SetTextColor(targetDC, textColor); + DrawText(targetDC, buffer, bufferLength, &partRect, + DT_CENTER | DT_TOP | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS); + } + + SelectFont(targetDC, prevFont); + if (NULL != titleFont) + DeleteObject(titleFont); + } + } + + WASABI_API_LNGSTRINGW_BUF(IDS_WELCOMEWIDGET_TEXT, buffer, ARRAYSIZE(buffer)); + if (L'\0' != buffer[0]) + { + bufferLength = lstrlen(buffer); + + textColor = WelcomeWidget_GetTextColor(style, &shadowColor, FALSE); + prevFont = SelectFont(targetDC, WIDGETSTYLE_TEXT_FONT(style)); + + SetRect(&partRect, 0, 0, WELCOMEWIDGET_TEXT_MIN_WIDTH, WELCOMEWIDGET_TEXT_MAX_HEIGHT); + + if (FALSE != WelcomeWidget_GetBestTextRect(targetDC, buffer, bufferLength, &partRect, width, + DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS)) + { + if (partRect.bottom > WELCOMEWIDGET_TEXT_MAX_HEIGHT) + { + TEXTMETRIC textMetrics; + if (FALSE != GetTextMetrics(targetDC, &textMetrics)) + partRect.bottom = (WELCOMEWIDGET_TEXT_MAX_HEIGHT/textMetrics.tmHeight)*textMetrics.tmHeight; + } + + OffsetRect(&partRect, + rect.left + (RECTWIDTH(rect) - RECTWIDTH(partRect))/2, + rect.bottom - WELCOMEWIDGET_TEXT_MAX_HEIGHT); + + OffsetRect(&partRect, 0, 1); + SetTextColor(targetDC, shadowColor); + DrawText(targetDC, buffer, bufferLength, &partRect, + DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS); + + OffsetRect(&partRect, 0, -1); + + SetTextColor(targetDC, textColor); + DrawText(targetDC, buffer, bufferLength, &partRect, + DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL | DT_END_ELLIPSIS); + } + + SelectFont(targetDC, prevFont); + } + + return TRUE; +} + +static HDC +WelcomeWidget_CreateContext(HWND hwnd, WidgetStyle *style, HBITMAP *prevBitmapOut, long *widthOut, long *heightOut) +{ + + HDC windowDC, targetDC, sourceDC; + HBITMAP backBitmap, targetBitmap; + HBITMAP prevTargetBitmap; + long width, height, backWidth, backHeight; + + if (NULL == prevBitmapOut || NULL == style) + return NULL; + + windowDC = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS); + if (NULL == windowDC) + return NULL; + + backBitmap = Image_LoadEx(Plugin_GetInstance(), MAKEINTRESOURCE(IDR_WELCOME_WIDGET_IMAGE), + SRC_TYPE_PNG, ISF_PREMULTIPLY, 0, 0); + + width = WELCOMEWIDGET_IMAGE_MIN_WIDTH; + height = WELCOMEWIDGET_IMAGE_MIN_HEIGHT; + backWidth = 0; + backHeight = 0; + + if (NULL != backBitmap) + { + BITMAP bi; + if (sizeof(bi) == GetObject(backBitmap, sizeof(bi), &bi)) + { + backWidth = bi.bmWidth; + if (backWidth > width) + width = backWidth; + + backHeight = ABS(bi.bmHeight); + if (backHeight > height) + height = backHeight; + } + } + + targetDC = CreateCompatibleDC(windowDC); + sourceDC = CreateCompatibleDC(windowDC); + targetBitmap = CreateCompatibleBitmap(windowDC, width, height); + prevTargetBitmap = NULL; + + ReleaseDC(hwnd, windowDC); + + if (NULL != targetDC && + NULL != sourceDC && + NULL != targetBitmap) + { + + HFONT prevTargetFont; + prevTargetBitmap = SelectBitmap(targetDC, targetBitmap); + prevTargetFont = GetCurrentFont(targetDC); + HBITMAP prevSourceBitmap = GetCurrentBitmap(sourceDC); + + if (FALSE == WelcomeWidget_FillContext(targetDC, width, height, sourceDC, + backBitmap, backWidth, backHeight, style)) + { + SelectBitmap(targetDC, prevTargetBitmap); + prevTargetBitmap = NULL; + DeleteObject(targetBitmap); + targetBitmap = NULL; + } + + SelectFont(targetDC, prevTargetFont); + SelectBitmap(sourceDC, prevSourceBitmap); + } + + if (NULL != sourceDC) + DeleteDC(sourceDC); + + if (NULL != targetDC && NULL == targetBitmap) + { + DeleteDC(targetDC); + targetDC = NULL; + prevTargetBitmap = NULL; + } + + if (NULL != backBitmap) + DeleteObject(backBitmap); + + *prevBitmapOut = prevTargetBitmap; + if (NULL != widthOut) + *widthOut = width; + if (NULL != heightOut) + *heightOut = height; + + return targetDC; +} + +static void +WelcomeWidget_ResetContext(WelcomeWidget * self) +{ + if (NULL == self || + NULL == self->context) + { + return; + } + + if (NULL != self->previousBitmap) + { + HBITMAP bitmap = SelectBitmap(self->context, self->previousBitmap); + if (NULL != bitmap) + DeleteObject(bitmap); + } + + DeleteDC(self->context); + self->context = NULL; + self->previousBitmap = NULL; + self->contextWidth = 0; + self->contextHeight = 0; +} + +static BOOL +WelcomeWidget_GetViewOrigin(HWND hwnd, POINT *pt) +{ + SCROLLINFO scrollInfo; + + if (NULL == pt) + return FALSE; + + scrollInfo.cbSize = sizeof(scrollInfo); + scrollInfo.fMask = SIF_POS; + + if (FALSE == GetScrollInfo(hwnd, SB_HORZ, &scrollInfo)) + return FALSE; + pt->x = -scrollInfo.nPos; + + if (FALSE == GetScrollInfo(hwnd, SB_VERT, &scrollInfo)) + return FALSE; + pt->y = -scrollInfo.nPos; + + return TRUE; +} + +static BOOL +WelcomeWidget_UpdateHelpPosition(WelcomeWidget *self, HWND hwnd, const RECT *clientRect, BOOL redraw) +{ + HWND elementWindow; + RECT elementRect; + unsigned int positionFlags; + long left, top; + POINT origin; + + if (NULL == self || NULL == hwnd || NULL == clientRect) + return FALSE; + + elementWindow = GetDlgItem(hwnd, WELCOMEWIDGET_HELP_LINK); + if (NULL == elementWindow) + return FALSE; + + + if (FALSE == WelcomeWidget_GetViewOrigin(hwnd, &origin)) + { + origin.x = 0; + origin.y = 0; + } + + if (FALSE == GetWindowRect(elementWindow, &elementRect)) + return FALSE; + + positionFlags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE; + if (FALSE == redraw) + positionFlags |= SWP_NOREDRAW; + + left = clientRect->right; + left -= (RECTWIDTH(elementRect) + 2); + if (left < clientRect->left) + left = clientRect->left; + + top = clientRect->top; + top += 2; + + return SetWindowPos(elementWindow, NULL, left, origin.y + top, 0, 0, positionFlags); +} + +static BOOL +WelcomeWidget_EnsureHelpVisible(WelcomeWidget *self, HWND hwnd) +{ + HWND elementWindow; + POINT origin; + + if (NULL == self || NULL == hwnd) + return FALSE; + + elementWindow = GetDlgItem(hwnd, WELCOMEWIDGET_HELP_LINK); + if (NULL == elementWindow) + return FALSE; + + if (FALSE != WelcomeWidget_GetViewOrigin(hwnd, &origin) && + 0 != origin.y) + { + return WIDGET_SCROLL(hwnd, 0, origin.y, TRUE); + } + + return FALSE; +} + +static BOOL +WelcomeWidget_GetHelpUrl(wchar_t *buffer, size_t bufferMax) +{ + if (NULL == buffer) + return FALSE; + + WASABI_API_LNGSTRINGW_BUF(IDS_WELCOMEWIDGET_HELP_URL, buffer, bufferMax); + return (L'\0' != buffer[0]); +} + +static BOOL +WelcomeWidget_InitCb(HWND hwnd, void **object, void *param) +{ + wchar_t buffer[64] = {0}; + WelcomeWidget *self = (WelcomeWidget*)malloc(sizeof(WelcomeWidget)); + + if (NULL == self) + return FALSE; + + ZeroMemory(self, sizeof(WelcomeWidget)); + WIDGET_ENABLE_CHILDREN_SCROLL(hwnd, FALSE); + + + WASABI_API_LNGSTRINGW_BUF(IDS_HELP_LINK, buffer, ARRAYSIZE(buffer)); + CommandLink_CreateWindow(WS_EX_NOPARENTNOTIFY, + buffer, + WS_CHILD | WS_VISIBLE | WS_TABSTOP | + /*CLS_ALWAYSUNDERLINE |*/ CLS_HOTTRACK | CLS_HIGHLIGHTCOLOR, + 0, 0, 0, 0, hwnd, WELCOMEWIDGET_HELP_LINK); + + *object = self; + + return TRUE; +} + +static void +WelcomeWidget_DestroyCb(WelcomeWidget *self, HWND hwnd) +{ + if (NULL == self) + return; + + WelcomeWidget_ResetContext(self); + if (NULL != self->helpFont) + DeleteObject(self->helpFont); + + free(self); +} + + +static void +WelcomeWidget_LayoutCb(WelcomeWidget *self, HWND hwnd, WidgetStyle *style, + const RECT *clientRect, SIZE *viewSize, BOOL redraw) +{ + if (NULL == self || NULL == style) + return; + + if (NULL == self->context) + { + self->context = WelcomeWidget_CreateContext(hwnd, style, &self->previousBitmap, &self->contextWidth, &self->contextHeight); + if (NULL == self->context) + return; + } + + viewSize->cx = self->contextWidth + + WIDGETSTYLE_DLU_TO_HORZ_PX(style, WELCOMEWIDGET_OFFSET_LEFT_DLU); + + viewSize->cy = self->contextHeight + + WIDGETSTYLE_DLU_TO_VERT_PX(style, WELCOMEWIDGET_OFFSET_TOP_DLU); + + + WelcomeWidget_UpdateHelpPosition(self, hwnd, clientRect, redraw); +} + + +static BOOL +WelcomeWidget_PaintCb(WelcomeWidget *self, HWND hwnd, WidgetStyle *style, HDC hdc, const RECT *paintRect, BOOL erase) +{ + FillRegion fillRegion; + + FillRegion_Init(&fillRegion, paintRect); + + if (NULL != self->context) + { + RECT partRect, rect; + long offsetX, offsetY; + + GetClientRect(hwnd, &rect); + + SetRect(&partRect, 0, 0, self->contextWidth, self->contextHeight); + + offsetX = rect.left + WIDGETSTYLE_DLU_TO_HORZ_PX(style, WELCOMEWIDGET_OFFSET_LEFT_DLU); + offsetY = WIDGETSTYLE_DLU_TO_HORZ_PX(style, WELCOMEWIDGET_OFFSET_RIGHT_DLU); + if ((offsetX + partRect.right + offsetY) < rect.right) + offsetX += (rect.right - (offsetX + partRect.right + offsetY))/2; + + offsetY = rect.top + WIDGETSTYLE_DLU_TO_VERT_PX(style, WELCOMEWIDGET_OFFSET_TOP_DLU); + + OffsetRect(&partRect, offsetX, offsetY); + + if (FALSE != IntersectRect(&rect, &partRect, paintRect) && + FALSE != BitBlt(hdc, rect.left, rect.top, RECTWIDTH(rect), RECTHEIGHT(rect), + self->context, rect.left - partRect.left, rect.top - partRect.top, SRCCOPY)) + { + FillRegion_ExcludeRect(&fillRegion, &rect); + } + + } + + + if (FALSE != erase) + FillRegion_BrushFill(&fillRegion, hdc, WIDGETSTYLE_BACK_BRUSH(style)); + + FillRegion_Uninit(&fillRegion); + + return TRUE; +} + +static void +WelcomeWidget_StyleColorChangedCb(WelcomeWidget *self, HWND hwnd, WidgetStyle *style) +{ + HWND elementWindow; + + if (NULL == self) + return; + + WelcomeWidget_ResetContext(self); + self->context = WelcomeWidget_CreateContext(hwnd, style, &self->previousBitmap, &self->contextWidth, &self->contextHeight); + + elementWindow = GetDlgItem(hwnd, WELCOMEWIDGET_HELP_LINK); + if (NULL != elementWindow) + { + CommandLink_SetBackColor(elementWindow, WIDGETSTYLE_BACK_COLOR(style)); + CommandLink_SetTextColor(elementWindow, WelcomeWidget_GetTextColor(style, NULL, TRUE)); + CommandLink_SetHighlightColor(elementWindow, WelcomeWidget_GetTextColor(style, NULL, FALSE)); + } +} + +static void +WelcomeWidget_StyleFontChangedCb(WelcomeWidget *self, HWND hwnd, WidgetStyle *style) +{ + HWND elementWindow; + + if (NULL == self) + return; + + WelcomeWidget_ResetContext(self); + self->context = WelcomeWidget_CreateContext(hwnd, style, &self->previousBitmap, &self->contextWidth, &self->contextHeight); + + elementWindow = GetDlgItem(hwnd, WELCOMEWIDGET_HELP_LINK); + if (NULL != elementWindow) + { + SIZE elementSize; + + if (NULL != self->helpFont) + DeleteObject(self->helpFont); + + self->helpFont = Graphics_DuplicateFont(WIDGETSTYLE_TEXT_FONT(style), 0, TRUE, TRUE); + + SendMessage(elementWindow, WM_SETFONT, (WPARAM)self->helpFont, 0L); + if (FALSE != CommandLink_GetIdealSize(elementWindow, &elementSize)) + { + SetWindowPos(elementWindow, NULL, 0, 0, elementSize.cx, elementSize.cy, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); + } + } +} + +static void +WelcomeWidget_ScrollCb(WelcomeWidget *self, HWND hwnd, int *dx, int *dy) +{ + RECT clientRect; + if (FALSE != GetClientRect(hwnd, &clientRect)) + WelcomeWidget_UpdateHelpPosition(self, hwnd, &clientRect, TRUE); + +} + +static void +WelcomeWidget_HelpLinkCb(WelcomeWidget *self, HWND hwnd, NMHDR *pnmh, LRESULT *result) +{ + switch(pnmh->code) + { + case NM_CLICK: + { + wchar_t buffer[4096] = {0}; + if (FALSE != WelcomeWidget_GetHelpUrl(buffer, ARRAYSIZE(buffer))) + MediaLibrary_ShowHelp(Plugin_GetLibraryWindow(), buffer); + } + break; + case NM_SETFOCUS: + WelcomeWidget_EnsureHelpVisible(self, hwnd); + break; + + } +} + +static BOOL +WelcomeWidget_NotifyCb(WelcomeWidget *self, HWND hwnd, NMHDR *pnmh, LRESULT *result) +{ + switch(pnmh->idFrom) + { + case WELCOMEWIDGET_HELP_LINK: + WelcomeWidget_HelpLinkCb(self, hwnd, pnmh, result); + return TRUE; + } + + return FALSE; +} + +static BOOL +WelcomeWidget_HelpCb(WelcomeWidget *self, HWND hwnd, wchar_t *buffer, size_t bufferMax) +{ + return WelcomeWidget_GetHelpUrl(buffer, bufferMax); +} + +HWND WelcomeWidget_CreateWindow(HWND parentWindow, int x, int y, int width, int height, BOOL border, unsigned int controlId) +{ + const static WidgetInterface welcomeWidgetInterface = + { + (WidgetInitCallback)WelcomeWidget_InitCb, + (WidgetDestroyCallback)WelcomeWidget_DestroyCb, + (WidgetLayoutCallback)WelcomeWidget_LayoutCb, + (WidgetPaintCallback)WelcomeWidget_PaintCb, + (WidgetStyleCallback)WelcomeWidget_StyleColorChangedCb, + (WidgetStyleCallback)WelcomeWidget_StyleFontChangedCb, + NULL /*mouseMove*/, + NULL /*leftButtonDown*/, + NULL /*leftButtonUp*/, + NULL /*leftButtonDblClk*/, + NULL /*rightButtonDown*/, + NULL /*rightButtonUp*/, + NULL /*keyDown*/, + NULL /*keyUp*/, + NULL /*character*/, + NULL /*inputRequest*/, + NULL /*focusChanged*/, + NULL /*contextMenu*/, + NULL /*zoomChanging*/, + NULL /*scrollBefore*/, + (WidgetScrollCallback)WelcomeWidget_ScrollCb, + (WidgetNotifyCallback)WelcomeWidget_NotifyCb, + (WidgetHelpCallback)WelcomeWidget_HelpCb, + + }; + + return Widget_CreateWindow(WIDGET_TYPE_WELCOME, + &welcomeWidgetInterface, + NULL, + ((FALSE != border) ? WS_EX_CLIENTEDGE : 0) | WS_EX_CONTROLPARENT, + WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + x, y, width, height, + parentWindow, + controlId, 0L); +}
\ No newline at end of file |