aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Library/ml_devices/welcomeWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Library/ml_devices/welcomeWidget.cpp')
-rw-r--r--Src/Plugins/Library/ml_devices/welcomeWidget.cpp760
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