aboutsummaryrefslogtreecommitdiff
path: root/Src/omBrowser/ratingMenuCustomizer.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/omBrowser/ratingMenuCustomizer.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/omBrowser/ratingMenuCustomizer.cpp')
-rw-r--r--Src/omBrowser/ratingMenuCustomizer.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/Src/omBrowser/ratingMenuCustomizer.cpp b/Src/omBrowser/ratingMenuCustomizer.cpp
new file mode 100644
index 00000000..bb397d42
--- /dev/null
+++ b/Src/omBrowser/ratingMenuCustomizer.cpp
@@ -0,0 +1,161 @@
+#include "main.h"
+#include "./ratingMenuCustomizer.h"
+#include "./ifc_skinhelper.h"
+#include "./ifc_skinnedrating.h"
+
+#include "../Plugins/General/gen_ml/ml_ipc_0313.h"
+
+#define RATING_MINSPACECX 16
+
+RatingMenuCustomizer::RatingMenuCustomizer(HMENU hMenu, ifc_skinnedrating *skinnedRating)
+ : ref(1), menu(hMenu), skin(skinnedRating)
+{
+ if (NULL != skin)
+ skin->AddRef();
+}
+
+RatingMenuCustomizer::~RatingMenuCustomizer()
+{
+ if (NULL != skin)
+ skin->Release();
+}
+
+HRESULT RatingMenuCustomizer::CreateInstance(HMENU hMenu, ifc_skinnedrating *skinnedRating, RatingMenuCustomizer **instance)
+{
+ if (NULL == instance) return E_POINTER;
+ *instance = NULL;
+
+ if (NULL == hMenu || NULL == skinnedRating) return E_INVALIDARG;
+
+ *instance = new RatingMenuCustomizer(hMenu, skinnedRating);
+ if (NULL == *instance) return E_OUTOFMEMORY;
+
+ return S_OK;
+}
+
+size_t RatingMenuCustomizer::AddRef()
+{
+ return InterlockedIncrement((LONG*)&ref);
+}
+
+size_t RatingMenuCustomizer::Release()
+{
+ if (0 == ref)
+ return ref;
+
+ LONG r = InterlockedDecrement((LONG*)&ref);
+ if (0 == r)
+ delete(this);
+
+ return r;
+}
+
+int RatingMenuCustomizer::QueryInterface(GUID interface_guid, void **object)
+{
+ if (NULL == object) return E_POINTER;
+
+ if (IsEqualIID(interface_guid, IFC_MenuCustomizer))
+ *object = static_cast<ifc_menucustomizer*>(this);
+ else
+ {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
+
+ if (NULL == *object)
+ return E_UNEXPECTED;
+
+ AddRef();
+ return S_OK;
+}
+
+
+INT RatingMenuCustomizer::CustomDraw(HMENU menuInstance, INT action, HDC hdc, LPARAM param)
+{
+ if (menuInstance != menu)
+ return FALSE;
+
+ switch(action)
+ {
+ case MLMENU_ACTION_MEASUREITEM: return MeasureRating(hdc, (MEASUREITEMSTRUCT*)param);
+ case MLMENU_ACTION_DRAWITEM: return MLMENU_WANT_DRAWPART;
+ case MLMENU_ACTION_DRAWBACK: break;
+ case MLMENU_ACTION_DRAWICON: break;
+ case MLMENU_ACTION_DRAWTEXT: return DrawRating(hdc, (DRAWITEMSTRUCT*)param);
+ }
+
+ return FALSE;
+}
+
+HRESULT RatingMenuCustomizer::GetValue(INT itemId, INT *valueOut)
+{
+ if (NULL == menu) return E_UNEXPECTED;
+
+ WCHAR szBuffer[32] = {0};
+ INT cchBuffer = GetMenuStringW(menu, itemId, szBuffer, ARRAYSIZE(szBuffer), MF_BYCOMMAND);
+ if (cchBuffer < 1 || cchBuffer > 5)
+ return E_INVALIDARG;
+
+ for (INT i = 1; i < cchBuffer; i++)
+ {
+ if (szBuffer[i -1] != szBuffer[i])
+ return E_INVALIDARG;
+ }
+
+ if (NULL != valueOut)
+ *valueOut = cchBuffer;
+
+ return S_OK;
+}
+
+INT RatingMenuCustomizer::MeasureRating(HDC hdc, MEASUREITEMSTRUCT *pmis)
+{
+ RECT rect;
+ if (NULL == skin || NULL == hdc ||
+ FAILED(GetValue(pmis->itemID, NULL)) ||
+ FAILED(skin->CalcMinRect(5, &rect)))
+ {
+ return FALSE;
+ }
+
+ pmis->itemHeight = rect.bottom - rect.top + 6;
+
+ TEXTMETRIC tm;
+ if (GetTextMetrics(hdc, &tm) &&
+ (UINT)(tm.tmHeight + 2) > pmis->itemHeight)
+ {
+ pmis->itemHeight = tm.tmHeight + 2;
+ }
+
+ INT spaceCX = (pmis->itemHeight > RATING_MINSPACECX) ? pmis->itemHeight : RATING_MINSPACECX;
+ pmis->itemWidth = rect.right - rect.left + (2 * spaceCX) - (GetSystemMetrics(SM_CXMENUCHECK) - 1);
+
+ return TRUE;
+}
+
+INT RatingMenuCustomizer::DrawRating(HDC hdc, DRAWITEMSTRUCT *pdis)
+{
+ INT value;
+ if (NULL == skin || NULL == hdc || FAILED(GetValue(pdis->itemID, &value)))
+ return FALSE;
+
+ INT spaceCX = ((pdis->rcItem.bottom - pdis->rcItem.top) > RATING_MINSPACECX) ?
+ (pdis->rcItem.bottom - pdis->rcItem.top) :
+ RATING_MINSPACECX;
+
+ RECT rect;
+ CopyRect(&rect, &pdis->rcItem);
+ rect.left += spaceCX;
+
+ UINT menuState = GetMenuState(menu, pdis->itemID, MF_BYCOMMAND);
+ UINT trackingValue = (0 == ((MF_DISABLED | MF_GRAYED) & menuState)) ? value : 0;
+
+ return SUCCEEDED(skin->Draw(hdc, 5, value, trackingValue, &rect, RDS_LEFT | RDS_VCENTER | RDS_HOT));
+}
+
+#define CBCLASS RatingMenuCustomizer
+START_DISPATCH;
+ CB(API_CUSTOMDRAW, CustomDraw);
+END_DISPATCH;
+#undef CBCLASS
+