mirror of
https://github.com/ytsodacan/Faucet.git
synced 2026-04-23 15:37:07 +00:00
changed mod menu to use gdi
This commit is contained in:
parent
a498f5ea5e
commit
ee8d07b6f7
|
|
@ -3,139 +3,462 @@
|
|||
#include "UIScene_ModsMenu.h"
|
||||
#include "ModLoader.h"
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma comment(lib, "comctl32.lib")
|
||||
|
||||
#define IDC_MODLIST 1001
|
||||
#define IDC_CLOSE 1002
|
||||
#define IDC_MOD_NAME 1003
|
||||
#define IDC_MOD_ID 1004
|
||||
#define IDC_MOD_AUTHOR 1005
|
||||
#define IDC_MOD_VERSION 1006
|
||||
#define IDC_MOD_DESC 1007
|
||||
#define IDC_MINI_X 1008
|
||||
|
||||
#define MC_BLACK RGB(0, 0, 0)
|
||||
#define MC_DARK_GRY RGB(33, 33, 33)
|
||||
// ---------------------------------------------------------------------------
|
||||
// Colours
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MC_DARK_GRY RGB(33, 33, 33)
|
||||
#define MC_MID_GRY RGB(50, 50, 50)
|
||||
#define MC_LIGHT_GRY RGB(198, 198, 198)
|
||||
#define MC_SEL_BLU RGB(60, 60, 60)
|
||||
#define MC_SEL_BLU RGB(60, 60, 60)
|
||||
#define MC_WHITE RGB(255, 255, 255)
|
||||
#define MC_BORDER RGB(80, 80, 80)
|
||||
#define MC_HOVER RGB(80, 80, 80)
|
||||
#define MC_PRESS RGB(30, 30, 30)
|
||||
#define MC_SCROLLBAR RGB(100, 100, 100)
|
||||
|
||||
static HWND g_hModsWindow = nullptr;
|
||||
static HWND g_hList = nullptr;
|
||||
// ---------------------------------------------------------------------------
|
||||
// Layout constants
|
||||
// ---------------------------------------------------------------------------
|
||||
#define WW 1200
|
||||
#define WH 600
|
||||
|
||||
#define LIST_X 20
|
||||
#define LIST_Y 20
|
||||
#define LIST_W 300
|
||||
#define LIST_H 480
|
||||
#define ITEM_H 32
|
||||
|
||||
#define INFO_X 340
|
||||
#define INFO_W 820
|
||||
|
||||
#define BTN_X 340
|
||||
#define BTN_Y 520
|
||||
#define BTN_W 200
|
||||
#define BTN_H 40
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Global state
|
||||
// ---------------------------------------------------------------------------
|
||||
static HWND g_hWnd = nullptr;
|
||||
static UIScene_ModsMenu* g_pScene = nullptr;
|
||||
static HBRUSH g_hBackBrush = nullptr;
|
||||
static HBRUSH g_hSelBrush = nullptr;
|
||||
|
||||
static HBRUSH g_hBackBrush = nullptr;
|
||||
static HFONT g_hFont = nullptr;
|
||||
static HFONT g_hFontBold = nullptr;
|
||||
|
||||
static std::vector<std::string> g_modNames;
|
||||
|
||||
static int g_selIdx = -1;
|
||||
static int g_listScroll = 0;
|
||||
|
||||
static std::string g_iName, g_iId, g_iAuthor, g_iVersion, g_iDesc;
|
||||
|
||||
static int g_descScroll = 0;
|
||||
static int g_descTextH = 0;
|
||||
|
||||
static bool g_btnHover = false;
|
||||
static bool g_btnPress = false;
|
||||
|
||||
static bool g_trackingMouse = false;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
static void Redraw() { if (g_hWnd) InvalidateRect(g_hWnd, nullptr, FALSE); }
|
||||
|
||||
static RECT RectOf(int x, int y, int w, int h) { return { x, y, x + w, y + h }; }
|
||||
|
||||
static RECT ListRect() { return RectOf(LIST_X, LIST_Y, LIST_W, LIST_H); }
|
||||
static RECT BtnRect() { return RectOf(BTN_X, BTN_Y, BTN_W, BTN_H); }
|
||||
|
||||
static int MaxListScroll()
|
||||
{
|
||||
int visible = LIST_H / ITEM_H;
|
||||
return max(0, (int)g_modNames.size() - visible);
|
||||
}
|
||||
|
||||
static int MeasureDescHeight(HDC hdc, const std::string& text, int width)
|
||||
{
|
||||
if (text.empty()) return 0;
|
||||
RECT r = { 0, 0, width, 32000 };
|
||||
HFONT old = (HFONT)SelectObject(hdc, g_hFont);
|
||||
DrawTextA(hdc, text.c_str(), -1, &r, DT_WORDBREAK | DT_CALCRECT);
|
||||
SelectObject(hdc, old);
|
||||
return r.bottom;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GDI drawing primitives
|
||||
// ---------------------------------------------------------------------------
|
||||
static void FillRoundRect(HDC hdc, RECT r, int rx, COLORREF fill, COLORREF border)
|
||||
{
|
||||
HBRUSH br = CreateSolidBrush(fill);
|
||||
HPEN pen = CreatePen(PS_SOLID, 1, border);
|
||||
HBRUSH ob = (HBRUSH)SelectObject(hdc, br);
|
||||
HPEN op = (HPEN)SelectObject(hdc, pen);
|
||||
RoundRect(hdc, r.left, r.top, r.right, r.bottom, rx, rx);
|
||||
SelectObject(hdc, ob); DeleteObject(br);
|
||||
SelectObject(hdc, op); DeleteObject(pen);
|
||||
}
|
||||
|
||||
static void GdiText(HDC hdc, const std::string& s, RECT r, COLORREF col,
|
||||
HFONT font, UINT flags = DT_SINGLELINE | DT_VCENTER | DT_LEFT)
|
||||
{
|
||||
SetTextColor(hdc, col);
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
HFONT old = (HFONT)SelectObject(hdc, font);
|
||||
DrawTextA(hdc, s.c_str(), -1, &r, flags);
|
||||
SelectObject(hdc, old);
|
||||
}
|
||||
|
||||
static void HLine(HDC hdc, int x0, int x1, int y, COLORREF col)
|
||||
{
|
||||
HPEN pen = CreatePen(PS_SOLID, 1, col);
|
||||
HPEN old = (HPEN)SelectObject(hdc, pen);
|
||||
MoveToEx(hdc, x0, y, nullptr);
|
||||
LineTo(hdc, x1, y);
|
||||
SelectObject(hdc, old);
|
||||
DeleteObject(pen);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Paint
|
||||
// ---------------------------------------------------------------------------
|
||||
static void Paint(HWND hWnd)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hWnd, &ps);
|
||||
|
||||
RECT rcClient;
|
||||
GetClientRect(hWnd, &rcClient);
|
||||
|
||||
HDC mem = CreateCompatibleDC(hdc);
|
||||
HBITMAP bmp = CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom);
|
||||
HBITMAP obmp = (HBITMAP)SelectObject(mem, bmp);
|
||||
|
||||
FillRect(mem, &rcClient, g_hBackBrush);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// List panel
|
||||
// -----------------------------------------------------------------------
|
||||
RECT listRect = ListRect();
|
||||
FillRoundRect(mem,
|
||||
{ listRect.left - 1, listRect.top - 1, listRect.right + 1, listRect.bottom + 1 },
|
||||
4, MC_DARK_GRY, MC_BORDER);
|
||||
|
||||
HRGN listClip = CreateRectRgn(listRect.left, listRect.top,
|
||||
listRect.right, listRect.bottom);
|
||||
SelectClipRgn(mem, listClip);
|
||||
|
||||
if (g_modNames.empty())
|
||||
{
|
||||
GdiText(mem, "No mods installed", listRect, MC_LIGHT_GRY, g_hFont,
|
||||
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
int visible = LIST_H / ITEM_H;
|
||||
for (int i = g_listScroll; i < g_listScroll + visible + 1; ++i)
|
||||
{
|
||||
if (i >= (int)g_modNames.size()) break;
|
||||
|
||||
int drawY = LIST_Y + (i - g_listScroll) * ITEM_H;
|
||||
RECT ir = { LIST_X, drawY, LIST_X + LIST_W, drawY + ITEM_H };
|
||||
|
||||
bool sel = (i == g_selIdx);
|
||||
HBRUSH ibr = CreateSolidBrush(sel ? MC_SEL_BLU : MC_DARK_GRY);
|
||||
FillRect(mem, &ir, ibr);
|
||||
DeleteObject(ibr);
|
||||
|
||||
if (i > g_listScroll)
|
||||
HLine(mem, LIST_X, LIST_X + LIST_W, drawY, MC_BORDER);
|
||||
|
||||
RECT tr = ir;
|
||||
tr.left += 8;
|
||||
GdiText(mem, g_modNames[i], tr, sel ? MC_WHITE : MC_LIGHT_GRY, g_hFont);
|
||||
}
|
||||
}
|
||||
|
||||
SelectClipRgn(mem, nullptr);
|
||||
DeleteObject(listClip);
|
||||
|
||||
if (MaxListScroll() > 0)
|
||||
{
|
||||
int total = (int)g_modNames.size();
|
||||
int visible = LIST_H / ITEM_H;
|
||||
int thumbH = max(20, (int)(((float)visible / total) * LIST_H));
|
||||
int thumbY = LIST_Y + (int)(((float)g_listScroll / (total - visible)) * (LIST_H - thumbH));
|
||||
RECT sb = { LIST_X + LIST_W - 6, thumbY,
|
||||
LIST_X + LIST_W - 2, thumbY + thumbH };
|
||||
HBRUSH sbr = CreateSolidBrush(MC_SCROLLBAR);
|
||||
FillRect(mem, &sb, sbr);
|
||||
DeleteObject(sbr);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Info panel rows
|
||||
// -----------------------------------------------------------------------
|
||||
int iy = 20;
|
||||
|
||||
auto DrawRow = [&](const std::string& label, const std::string& value)
|
||||
{
|
||||
RECT lr = { INFO_X, iy, INFO_X + 75, iy + 24 };
|
||||
RECT vr = { INFO_X + 78, iy, INFO_X + INFO_W, iy + 24 };
|
||||
GdiText(mem, label, lr, MC_LIGHT_GRY, g_hFontBold);
|
||||
GdiText(mem, value, vr, MC_WHITE, g_hFont,
|
||||
DT_SINGLELINE | DT_VCENTER | DT_LEFT | DT_END_ELLIPSIS);
|
||||
iy += 30;
|
||||
};
|
||||
|
||||
DrawRow("Name:", g_iName);
|
||||
DrawRow("ID:", g_iId);
|
||||
DrawRow("Author:", g_iAuthor);
|
||||
DrawRow("Version:", g_iVersion);
|
||||
|
||||
RECT dlr = { INFO_X, iy, INFO_X + 200, iy + 22 };
|
||||
GdiText(mem, "Description:", dlr, MC_LIGHT_GRY, g_hFontBold);
|
||||
iy += 26;
|
||||
|
||||
int descBoxH = BTN_Y - 10 - iy;
|
||||
RECT descBox = { INFO_X, iy, INFO_X + INFO_W, iy + descBoxH };
|
||||
FillRoundRect(mem, descBox, 4, MC_MID_GRY, MC_BORDER);
|
||||
|
||||
int descInnerW = INFO_W - 14;
|
||||
RECT descTextR = { descBox.left + 6,
|
||||
descBox.top + 4 - g_descScroll,
|
||||
descBox.left + 6 + descInnerW,
|
||||
descBox.top + 4 - g_descScroll + 32000 };
|
||||
|
||||
HRGN descClip = CreateRectRgn(descBox.left + 2, descBox.top + 2,
|
||||
descBox.right - 2, descBox.bottom - 2);
|
||||
SelectClipRgn(mem, descClip);
|
||||
|
||||
if (!g_iDesc.empty())
|
||||
{
|
||||
SetTextColor(mem, MC_LIGHT_GRY);
|
||||
SetBkMode(mem, TRANSPARENT);
|
||||
HFONT of = (HFONT)SelectObject(mem, g_hFont);
|
||||
DrawTextA(mem, g_iDesc.c_str(), -1, &descTextR, DT_WORDBREAK | DT_LEFT);
|
||||
SelectObject(mem, of);
|
||||
}
|
||||
|
||||
SelectClipRgn(mem, nullptr);
|
||||
DeleteObject(descClip);
|
||||
|
||||
if (g_descTextH > descBoxH)
|
||||
{
|
||||
int maxDs = g_descTextH - descBoxH;
|
||||
int thumbH = max(20, (int)(((float)descBoxH / g_descTextH) * descBoxH));
|
||||
int thumbY = descBox.top + (int)(((float)g_descScroll / maxDs) * (descBoxH - thumbH));
|
||||
RECT dsb = { descBox.right - 6, thumbY,
|
||||
descBox.right - 2, thumbY + thumbH };
|
||||
HBRUSH dsbr = CreateSolidBrush(MC_SCROLLBAR);
|
||||
FillRect(mem, &dsb, dsbr);
|
||||
DeleteObject(dsbr);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Done button
|
||||
// -----------------------------------------------------------------------
|
||||
RECT btnR = BtnRect();
|
||||
COLORREF bc = g_btnPress ? MC_PRESS : g_btnHover ? MC_HOVER : MC_SEL_BLU;
|
||||
FillRoundRect(mem, btnR, 6, bc, MC_BORDER);
|
||||
GdiText(mem, "Done", btnR, MC_WHITE, g_hFontBold,
|
||||
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
|
||||
BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, mem, 0, 0, SRCCOPY);
|
||||
SelectObject(mem, obmp);
|
||||
DeleteObject(bmp);
|
||||
DeleteDC(mem);
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Window procedure
|
||||
// ---------------------------------------------------------------------------
|
||||
static LRESULT CALLBACK ModsWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) == IDC_CLOSE || LOWORD(wParam) == IDC_MINI_X)
|
||||
{
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
else if (LOWORD(wParam) == IDC_MODLIST && HIWORD(wParam) == LBN_SELCHANGE)
|
||||
{
|
||||
int sel = (int)SendMessage(g_hList, LB_GETCURSEL, 0, 0);
|
||||
if (g_pScene && sel >= 0)
|
||||
g_pScene->ShowModInfoInWindow(sel);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MEASUREITEM:
|
||||
{
|
||||
LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;
|
||||
if (lpmis->CtlID == IDC_MODLIST)
|
||||
{
|
||||
lpmis->itemHeight = 32;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DRAWITEM:
|
||||
{
|
||||
LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
|
||||
if (lpdis->CtlID == IDC_MODLIST && lpdis->itemID != (UINT)-1)
|
||||
{
|
||||
char text[256];
|
||||
SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)text);
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
{
|
||||
FillRect(lpdis->hDC, &lpdis->rcItem, g_hSelBrush);
|
||||
SetTextColor(lpdis->hDC, RGB(255, 255, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
FillRect(lpdis->hDC, &lpdis->rcItem, g_hBackBrush);
|
||||
SetTextColor(lpdis->hDC, MC_LIGHT_GRY);
|
||||
}
|
||||
|
||||
SetBkMode(lpdis->hDC, TRANSPARENT);
|
||||
RECT textRect = lpdis->rcItem;
|
||||
textRect.left += 5;
|
||||
DrawTextA(lpdis->hDC, text, -1, &textRect, DT_SINGLELINE | DT_VCENTER);
|
||||
|
||||
if (lpdis->itemState & ODS_FOCUS)
|
||||
DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CTLCOLORSTATIC:
|
||||
case WM_CTLCOLOREDIT:
|
||||
{
|
||||
HDC hdc = (HDC)wParam;
|
||||
SetTextColor(hdc, MC_LIGHT_GRY);
|
||||
SetBkColor(hdc, MC_DARK_GRY);
|
||||
return (LRESULT)g_hBackBrush;
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
case WM_PAINT:
|
||||
Paint(hWnd);
|
||||
return 0;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
FillRect((HDC)wParam, &rc, g_hBackBrush);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
if (g_pScene)
|
||||
g_pScene->m_bWindowClosed = true;
|
||||
|
||||
if (g_hSelBrush)
|
||||
// -----------------------------------------------------------------------
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (!g_trackingMouse)
|
||||
{
|
||||
DeleteObject(g_hSelBrush);
|
||||
g_hSelBrush = nullptr;
|
||||
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hWnd, 0 };
|
||||
TrackMouseEvent(&tme);
|
||||
g_trackingMouse = true;
|
||||
}
|
||||
|
||||
g_hModsWindow = nullptr;
|
||||
g_hList = nullptr;
|
||||
int mx = (short)LOWORD(lParam), my = (short)HIWORD(lParam);
|
||||
RECT btnR = BtnRect();
|
||||
bool prev = g_btnHover;
|
||||
g_btnHover = (PtInRect(&btnR, { mx, my }) != 0);
|
||||
if (prev != g_btnHover) Redraw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
g_trackingMouse = false;
|
||||
if (g_btnHover) { g_btnHover = false; Redraw(); }
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
int mx = (short)LOWORD(lParam), my = (short)HIWORD(lParam);
|
||||
RECT listR = ListRect();
|
||||
RECT btnR = BtnRect();
|
||||
|
||||
if (PtInRect(&listR, { mx, my }))
|
||||
{
|
||||
int row = (my - LIST_Y) / ITEM_H + g_listScroll;
|
||||
if (row >= 0 && row < (int)g_modNames.size())
|
||||
{
|
||||
g_selIdx = row;
|
||||
g_descScroll = 0;
|
||||
if (g_pScene) g_pScene->ShowModInfoInWindow(row);
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
else if (PtInRect(&btnR, { mx, my }))
|
||||
{
|
||||
g_btnPress = true;
|
||||
SetCapture(hWnd);
|
||||
Redraw();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
int mx = (short)LOWORD(lParam), my = (short)HIWORD(lParam);
|
||||
if (g_btnPress)
|
||||
{
|
||||
g_btnPress = false;
|
||||
ReleaseCapture();
|
||||
RECT btnR = BtnRect();
|
||||
if (PtInRect(&btnR, { mx, my }))
|
||||
{
|
||||
DestroyWindow(hWnd);
|
||||
return 0;
|
||||
}
|
||||
Redraw();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
POINT pt = { (short)LOWORD(lParam), (short)HIWORD(lParam) };
|
||||
ScreenToClient(hWnd, &pt);
|
||||
|
||||
int delta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
|
||||
|
||||
RECT listR = ListRect();
|
||||
if (PtInRect(&listR, pt))
|
||||
{
|
||||
g_listScroll -= delta;
|
||||
g_listScroll = max(0, min(g_listScroll, MaxListScroll()));
|
||||
Redraw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iy = 20 + 4 * 30 + 26;
|
||||
int descBoxH = BTN_Y - 10 - iy;
|
||||
RECT descR = { INFO_X, iy, INFO_X + INFO_W, iy + descBoxH };
|
||||
if (PtInRect(&descR, pt) && g_descTextH > descBoxH)
|
||||
{
|
||||
int maxDs = g_descTextH - descBoxH;
|
||||
g_descScroll -= delta * 20;
|
||||
g_descScroll = max(0, min(g_descScroll, maxDs));
|
||||
Redraw();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN:
|
||||
if (wParam == VK_ESCAPE)
|
||||
{
|
||||
DestroyWindow(hWnd);
|
||||
return 0;
|
||||
}
|
||||
if (wParam == VK_UP || wParam == VK_DOWN)
|
||||
{
|
||||
int next = g_selIdx + (wParam == VK_DOWN ? 1 : -1);
|
||||
next = max(0, min(next, (int)g_modNames.size() - 1));
|
||||
if (next != g_selIdx)
|
||||
{
|
||||
g_selIdx = next;
|
||||
g_descScroll = 0;
|
||||
|
||||
if (g_selIdx < g_listScroll)
|
||||
g_listScroll = g_selIdx;
|
||||
else if (g_selIdx >= g_listScroll + LIST_H / ITEM_H)
|
||||
g_listScroll = g_selIdx - LIST_H / ITEM_H + 1;
|
||||
|
||||
if (g_pScene) g_pScene->ShowModInfoInWindow(g_selIdx);
|
||||
Redraw();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
if (g_pScene) g_pScene->m_bWindowClosed = true;
|
||||
g_hWnd = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Window creation
|
||||
// ---------------------------------------------------------------------------
|
||||
static void CreateModsWindow(UIScene_ModsMenu* pScene)
|
||||
{
|
||||
if (g_hModsWindow) return;
|
||||
if (g_hWnd) return;
|
||||
|
||||
g_pScene = pScene;
|
||||
if (!g_hBackBrush) g_hBackBrush = CreateSolidBrush(MC_DARK_GRY);
|
||||
if (!g_hSelBrush) g_hSelBrush = CreateSolidBrush(MC_SEL_BLU);
|
||||
g_selIdx = -1;
|
||||
g_listScroll = 0;
|
||||
g_descScroll = 0;
|
||||
g_descTextH = 0;
|
||||
g_iName = g_iId = g_iAuthor = g_iVersion = g_iDesc = "";
|
||||
g_btnHover = g_btnPress = false;
|
||||
g_trackingMouse = false;
|
||||
|
||||
if (!g_hBackBrush)
|
||||
g_hBackBrush = CreateSolidBrush(MC_DARK_GRY);
|
||||
|
||||
if (!g_hFont)
|
||||
g_hFont = CreateFont(16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Segoe UI");
|
||||
|
||||
if (!g_hFontBold)
|
||||
g_hFontBold = CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Segoe UI");
|
||||
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
|
||||
if (!GetClassInfoEx(GetModuleHandle(nullptr), "ModsMenuWindow", &wc))
|
||||
{
|
||||
wc.lpfnWndProc = ModsWndProc;
|
||||
wc.hInstance = GetModuleHandle(nullptr);
|
||||
wc.hbrBackground = g_hBackBrush;
|
||||
wc.hbrBackground = nullptr;
|
||||
wc.lpszClassName = "ModsMenuWindow";
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
RegisterClassEx(&wc);
|
||||
|
|
@ -143,72 +466,38 @@ static void CreateModsWindow(UIScene_ModsMenu* pScene)
|
|||
|
||||
HWND hParent = GetActiveWindow();
|
||||
LONG style = GetWindowLong(hParent, GWL_STYLE);
|
||||
if (!(style & WS_CLIPCHILDREN)) SetWindowLong(hParent, GWL_STYLE, style | WS_CLIPCHILDREN);
|
||||
if (!(style & WS_CLIPCHILDREN))
|
||||
SetWindowLong(hParent, GWL_STYLE, style | WS_CLIPCHILDREN);
|
||||
|
||||
RECT rcParent;
|
||||
GetClientRect(hParent, &rcParent);
|
||||
int sw = rcParent.right - rcParent.left;
|
||||
int sh = rcParent.bottom - rcParent.top;
|
||||
int wx = (rcParent.right - WW) / 2;
|
||||
int wy = (rcParent.bottom - WH) / 2;
|
||||
|
||||
int ww = 1200, wh = 600;
|
||||
int wx = (sw - ww) / 2;
|
||||
int wy = (sh - 520) / 2;
|
||||
|
||||
g_hModsWindow = CreateWindowEx(
|
||||
WS_EX_NOPARENTNOTIFY | WS_EX_CONTROLPARENT,
|
||||
g_hWnd = CreateWindowEx(
|
||||
WS_EX_NOPARENTNOTIFY,
|
||||
"ModsMenuWindow", nullptr,
|
||||
WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPSIBLINGS,
|
||||
wx, wy, ww, wh,
|
||||
hParent,
|
||||
nullptr, GetModuleHandle(nullptr), nullptr
|
||||
);
|
||||
|
||||
auto CreateLabel = [](const char* txt, int x, int y, int w, int id = -1) {
|
||||
return CreateWindow("STATIC", txt, WS_CHILD | WS_VISIBLE, x, y, w, 20, g_hModsWindow, (HMENU)id, nullptr, nullptr);
|
||||
};
|
||||
|
||||
g_hList = CreateWindow(
|
||||
"LISTBOX", nullptr,
|
||||
WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_NOTIFY | LBS_HASSTRINGS | LBS_OWNERDRAWFIXED,
|
||||
20, 20, 300, 480,
|
||||
g_hModsWindow, (HMENU)IDC_MODLIST, GetModuleHandle(nullptr), nullptr
|
||||
);
|
||||
|
||||
CreateLabel("Name:", 340, 20, 60);
|
||||
CreateLabel("", 410, 20, 400, IDC_MOD_NAME);
|
||||
CreateLabel("ID:", 340, 50, 60);
|
||||
CreateLabel("", 410, 50, 400, IDC_MOD_ID);
|
||||
CreateLabel("Author:", 340, 80, 60);
|
||||
CreateLabel("", 410, 80, 400, IDC_MOD_AUTHOR);
|
||||
CreateLabel("Version:", 340, 110, 60);
|
||||
CreateLabel("", 410, 110, 400, IDC_MOD_VERSION);
|
||||
CreateLabel("Description:", 340, 140, 100);
|
||||
|
||||
CreateWindowEx(0, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_READONLY | WS_VSCROLL,
|
||||
340, 165, 480, 335, g_hModsWindow, (HMENU)IDC_MOD_DESC, nullptr, nullptr);
|
||||
|
||||
CreateWindow("BUTTON", "Done",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
|
||||
340, 520, 200, 40,
|
||||
g_hModsWindow, (HMENU)IDC_CLOSE, GetModuleHandle(nullptr), nullptr
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
|
||||
wx, wy, WW, WH,
|
||||
hParent, nullptr, GetModuleHandle(nullptr), nullptr
|
||||
);
|
||||
|
||||
SetFocus(g_hWnd);
|
||||
|
||||
g_modNames.clear();
|
||||
const auto& mods = ModLoader::Get().GetMods();
|
||||
for (int i = 0; i < (int)mods.size(); ++i)
|
||||
for (const auto& m : mods)
|
||||
{
|
||||
if (!mods[i].instance) continue;
|
||||
std::string displayName = mods[i].instance->GetInfo()->name;
|
||||
if (!mods[i].healthy) displayName += " (disabled)";
|
||||
SendMessageA(g_hList, LB_ADDSTRING, 0, (LPARAM)displayName.c_str());
|
||||
}
|
||||
|
||||
if (SendMessage(g_hList, LB_GETCOUNT, 0, 0) == 0)
|
||||
{
|
||||
SendMessageA(g_hList, LB_ADDSTRING, 0, (LPARAM)"No mods installed");
|
||||
if (!m.instance) continue;
|
||||
std::string name = m.instance->GetInfo()->name;
|
||||
if (!m.healthy) name += " (disabled)";
|
||||
g_modNames.push_back(name);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// UIScene_ModsMenu implementation
|
||||
// ---------------------------------------------------------------------------
|
||||
UIScene_ModsMenu::UIScene_ModsMenu(int iPad, void* initData, UILayer* parentLayer)
|
||||
: UIScene(iPad, parentLayer)
|
||||
, m_selectedIndex(-1)
|
||||
|
|
@ -219,31 +508,26 @@ UIScene_ModsMenu::UIScene_ModsMenu(int iPad, void* initData, UILayer* parentLaye
|
|||
|
||||
UIScene_ModsMenu::~UIScene_ModsMenu()
|
||||
{
|
||||
if (g_hModsWindow)
|
||||
if (g_hWnd)
|
||||
{
|
||||
DestroyWindow(g_hModsWindow);
|
||||
g_hModsWindow = nullptr;
|
||||
DestroyWindow(g_hWnd);
|
||||
g_hWnd = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
wstring UIScene_ModsMenu::getMoviePath()
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
wstring UIScene_ModsMenu::getMoviePath() { return L""; }
|
||||
|
||||
void UIScene_ModsMenu::handleGainFocus(bool navBack)
|
||||
{
|
||||
}
|
||||
void UIScene_ModsMenu::handleGainFocus(bool navBack) {}
|
||||
|
||||
void UIScene_ModsMenu::tick()
|
||||
{
|
||||
m_hasTickedOnce = true;
|
||||
m_bCanHandleInput = true;
|
||||
|
||||
if (g_hModsWindow && IsWindow(g_hModsWindow))
|
||||
if (g_hWnd && IsWindow(g_hWnd))
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, g_hModsWindow, 0, 0, PM_REMOVE))
|
||||
while (PeekMessage(&msg, g_hWnd, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
|
@ -257,13 +541,14 @@ void UIScene_ModsMenu::tick()
|
|||
}
|
||||
}
|
||||
|
||||
void UIScene_ModsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled)
|
||||
void UIScene_ModsMenu::handleInput(int iPad, int key, bool repeat,
|
||||
bool pressed, bool released, bool& handled)
|
||||
{
|
||||
if (g_hModsWindow && IsWindow(g_hModsWindow)) handled = true;
|
||||
if (g_hWnd && IsWindow(g_hWnd)) handled = true;
|
||||
|
||||
if (key == ACTION_MENU_CANCEL && pressed && m_hasTickedOnce)
|
||||
{
|
||||
if (g_hModsWindow) DestroyWindow(g_hModsWindow);
|
||||
if (g_hWnd) DestroyWindow(g_hWnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,23 +556,31 @@ void UIScene_ModsMenu::handlePress(F64 controlId, F64 childId) {}
|
|||
|
||||
void UIScene_ModsMenu::ShowModInfoInWindow(int index)
|
||||
{
|
||||
if (!g_hModsWindow) return;
|
||||
if (!g_hWnd) return;
|
||||
|
||||
const auto& mods = ModLoader::Get().GetMods();
|
||||
if (index < 0 || index >= (int)mods.size() || !mods[index].instance) return;
|
||||
|
||||
const ModInfo* info = mods[index].instance->GetInfo();
|
||||
|
||||
SetWindowTextA(GetDlgItem(g_hModsWindow, IDC_MOD_NAME), info->name ? info->name : "");
|
||||
SetWindowTextA(GetDlgItem(g_hModsWindow, IDC_MOD_ID), info->id ? info->id : "");
|
||||
SetWindowTextA(GetDlgItem(g_hModsWindow, IDC_MOD_AUTHOR), info->author ? info->author : "");
|
||||
g_iName = info->name ? info->name : "";
|
||||
g_iId = info->id ? info->id : "";
|
||||
g_iAuthor = info->author ? info->author : "";
|
||||
g_iVersion = std::to_string(info->version.major) + "." +
|
||||
std::to_string(info->version.minor) + "." +
|
||||
std::to_string(info->version.patch);
|
||||
g_iDesc = info->description ? info->description : "";
|
||||
if (!mods[index].healthy)
|
||||
g_iDesc += "\r\n[This mod has been disabled due to an error.]";
|
||||
|
||||
std::string ver = std::to_string(info->version.major) + "." + std::to_string(info->version.minor) + "." + std::to_string(info->version.patch);
|
||||
SetWindowTextA(GetDlgItem(g_hModsWindow, IDC_MOD_VERSION), ver.c_str());
|
||||
g_descScroll = 0;
|
||||
|
||||
std::string desc = info->description ? info->description : "";
|
||||
if (!mods[index].healthy) desc += "\r\n[This mod has been disabled due to an error.]";
|
||||
SetWindowTextA(GetDlgItem(g_hModsWindow, IDC_MOD_DESC), desc.c_str());
|
||||
HDC hdc = GetDC(g_hWnd);
|
||||
int descInnerW = INFO_W - 14;
|
||||
g_descTextH = MeasureDescHeight(hdc, g_iDesc, descInnerW);
|
||||
ReleaseDC(g_hWnd, hdc);
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void UIScene_ModsMenu::PopulateModList() {}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,5 +1,4 @@
|
|||
SDK.cpp
|
||||
ServerLevel.cpp
|
||||
UIScene_ModsMenu.cpp
|
||||
Microsoft (R) Incremental Linker Version 14.44.35222.0
|
||||
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
"/OUT:S:\GitHub\Faucet\x64\Debug\Faucet.exe" /INCREMENTAL "/ILK:x64\Debug\Faucet.ilk" d3d11.lib ..\Minecraft.World\x64_Debug\Minecraft.World.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib XInput9_1_0.lib ..\Minecraft.Client\Windows64\Miles\Lib\mss64.lib wsock32.lib /MANIFEST "/MANIFESTUAC:level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG "/PDB:S:\GitHub\Faucet\x64\Debug\Minecraft.Client.pdb" /TLBID:1 /DYNAMICBASE /NXCOMPAT "/IMPLIB:S:\GitHub\Faucet\x64\Debug\Faucet.lib" /MACHINE:X64 x64\Debug\MinecraftWindows.res
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,10 +1,3 @@
|
|||
[15:49:36] === Faucet ModLoader starting ===
|
||||
[15:49:36] Found 0 mod(s) to load
|
||||
[15:49:36] Initialization complete — 0 loaded, 0 failed, 181ms total
|
||||
[15:49:57] Level loaded
|
||||
[15:49:57] Level loaded
|
||||
[15:49:57] Level loaded
|
||||
[15:50:28] Level unloaded
|
||||
[15:50:28] Level unloaded
|
||||
[15:50:28] Level unloaded
|
||||
[15:50:28] Shutting down ModLoader
|
||||
[16:46:29] === Faucet ModLoader starting ===
|
||||
[16:46:29] Found 0 mod(s) to load
|
||||
[16:46:29] Initialization complete — 0 loaded, 0 failed, 116ms total
|
||||
|
|
|
|||
Loading…
Reference in a new issue