diff --git a/Client/core/CClientVariables.cpp b/Client/core/CClientVariables.cpp index 85dee800fa..01b3006234 100644 --- a/Client/core/CClientVariables.cpp +++ b/Client/core/CClientVariables.cpp @@ -357,6 +357,7 @@ void CClientVariables::LoadDefaults() DEFAULT("discord_rpc_share_data", false); // Consistent Rich Presence data sharing DEFAULT("discord_rpc_share_data_firsttime", false); // Display the user data sharing consent dialog box - for the first time DEFAULT("browser_enable_gpu", true); // Enable GPU in CEF? (allows stuff like WebGL to function) + DEFAULT("cgui_modern_interface", true); // Enable modern CGUI interface (testing for upcoming main menu revamp) if (!Exists("locale")) { diff --git a/Client/core/CCore.cpp b/Client/core/CCore.cpp index 12e8cf81d5..fdd3df84e3 100644 --- a/Client/core/CCore.cpp +++ b/Client/core/CCore.cpp @@ -1020,6 +1020,8 @@ void CCore::DeinitGUI() void CCore::InitGUI(IDirect3DDevice9* pDevice) { m_pGUI = InitModule(m_GUIModule, "GUI", "InitGUIInterface", pDevice); + m_pGUI->SetXMLParser(m_pXML); + m_pGUI->SetGraphics(m_pGraphics); } void CCore::CreateGUI() diff --git a/Client/core/CGUI.cpp b/Client/core/CGUI.cpp index 6273536347..149ee89eeb 100644 --- a/Client/core/CGUI.cpp +++ b/Client/core/CGUI.cpp @@ -44,6 +44,7 @@ CLocalGUI::CLocalGUI() m_LastSettingsRevision = -1; m_LocaleChangeCounter = 0; + CVARS_GET("cgui_modern_interface", m_ModernSkinEnabled); } CLocalGUI::~CLocalGUI() @@ -138,6 +139,12 @@ void CLocalGUI::CreateWindows(bool bGameIsAlreadyLoaded) { CGUI* pGUI = CCore::GetSingleton().GetGUI(); + bool modern; + CVARS_GET("cgui_modern_interface", modern); + + if (modern) + pGUI->SetModernSkinEnabled(true); + // Create chatbox m_pChat = new CChat(pGUI, CVector2D(0.0125f, 0.015f)); m_pChat->SetVisible(false, true); @@ -171,6 +178,9 @@ void CLocalGUI::CreateWindows(bool bGameIsAlreadyLoaded) // Create our news headlines if we're already ingame if (bGameIsAlreadyLoaded) m_pMainMenu->GetNewsBrowser()->CreateHeadlines(); + + if (modern) + pGUI->SetModernSkinEnabled(false); } void CLocalGUI::CreateObjects(IUnknown* pDevice) @@ -212,6 +222,8 @@ void CLocalGUI::DestroyObjects() void CLocalGUI::DoPulse() { + bool didSetSkin = false; + m_pVersionUpdater->DoPulse(); CClientVariables* cvars = CCore::GetSingleton().GetCVars(); @@ -228,7 +240,10 @@ void CLocalGUI::DoPulse() if (currentSkinName != m_LastSkinName) { if (!CCore::GetSingleton().GetModManager()->IsLoaded()) + { SetSkin(currentSkinName); + didSetSkin = true; + } else { CCore::GetSingleton().GetConsole()->Printf("Please disconnect before changing skin"); @@ -273,6 +288,28 @@ void CLocalGUI::DoPulse() } } } + + // Check for modern skin change + bool modern; + CVARS_GET("cgui_modern_interface", modern); + + if (modern != m_ModernSkinEnabled) + { + if (!CCore::GetSingleton().GetModManager()->IsLoaded()) + { + m_ModernSkinEnabled = modern; + + if (!didSetSkin) + { + SetSkin(m_LastSkinName); + } + } + else + { + CCore::GetSingleton().GetConsole()->Printf("Please disconnect before setting modern interface"); + cvars->Set("cgui_modern_interface", m_ModernSkinEnabled); + } + } } } diff --git a/Client/core/CGUI.h b/Client/core/CGUI.h index f667082844..70b3337339 100644 --- a/Client/core/CGUI.h +++ b/Client/core/CGUI.h @@ -118,4 +118,5 @@ class CLocalGUI : public CSingleton SString m_LastSkinName; SString m_LastLocaleName; uint m_LocaleChangeCounter; + bool m_ModernSkinEnabled; }; diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 566a374247..20a6534a9c 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -947,7 +947,7 @@ void CSettings::CreateGUI() m_pLabelBrowserBlacklistAdd = reinterpret_cast(pManager->CreateLabel(m_pEditBrowserBlacklistAdd, _("Enter a domain e.g. google.com"))); m_pLabelBrowserBlacklistAdd->SetPosition(CVector2D(10.0f, 3.0f), false); - m_pLabelBrowserBlacklistAdd->SetTextColor(0, 0, 0); + m_pLabelBrowserBlacklistAdd->SetPlaceholderColors(); m_pLabelBrowserBlacklistAdd->SetSize(CVector2D(1, 1), true); m_pLabelBrowserBlacklistAdd->SetAlpha(0.7f); m_pLabelBrowserBlacklistAdd->SetProperty("MousePassThroughEnabled", "True"); @@ -982,7 +982,7 @@ void CSettings::CreateGUI() m_pLabelBrowserWhitelistAdd = reinterpret_cast(pManager->CreateLabel(m_pEditBrowserWhitelistAdd, _("Enter a domain e.g. google.com"))); m_pLabelBrowserWhitelistAdd->SetPosition(CVector2D(10.0f, 3.0f), false); - m_pLabelBrowserWhitelistAdd->SetTextColor(0, 0, 0); + m_pLabelBrowserWhitelistAdd->SetPlaceholderColors(); m_pLabelBrowserWhitelistAdd->SetSize(CVector2D(1, 1), true); m_pLabelBrowserWhitelistAdd->SetAlpha(0.7f); m_pLabelBrowserWhitelistAdd->SetProperty("MousePassThroughEnabled", "True"); @@ -1272,6 +1272,7 @@ void CSettings::CreateGUI() m_pChatLoadPreset->SetClickHandler(GUI_CALLBACK(&CSettings::OnChatLoadPresetClick, this)); m_pInterfaceLanguageSelector->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnLanguageChanged, this)); m_pInterfaceSkinSelector->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnSkinChanged, this)); + m_pInterfaceModern->SetClickHandler(GUI_CALLBACK(&CSettings::OnModernClick, this)); m_pMapAlpha->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnMapAlphaChanged, this)); m_pAudioMasterVolume->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnMasterVolumeChanged, this)); m_pAudioRadioVolume->SetOnScrollHandler(GUI_CALLBACK(&CSettings::OnRadioVolumeChanged, this)); @@ -2055,6 +2056,11 @@ void CSettings::CreateInterfaceTabGUI() // Language pLabel = reinterpret_cast(pManager->CreateLabel(m_pTabInterface, strLanguage)); pLabel->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); + + m_pInterfaceModernLabel = reinterpret_cast(pManager->CreateLabel(m_pTabInterface, _("Use modern interface"))); + m_pInterfaceModernLabel->SetPosition(CVector2D(vecTemp.fX + fIndentX + fComboWidth + 35.0f, vecTemp.fY + 20.0f)); + m_pInterfaceModernLabel->AutoSize(); + pLabel->GetPosition(vecTemp); pLabel->AutoSize(); @@ -2063,6 +2069,14 @@ void CSettings::CreateInterfaceTabGUI() m_pInterfaceLanguageSelector->SetSize(CVector2D(fComboWidth, 200.0f)); m_pInterfaceLanguageSelector->SetReadOnly(true); + m_pInterfaceModern = reinterpret_cast(pManager->CreateCheckBox(m_pTabInterface, "")); + m_pInterfaceModern->SetPosition(CVector2D(vecTemp.fX + fIndentX + fComboWidth + 10.0f, vecTemp.fY - 1.0f)); + m_pInterfaceModern->SetSize(CVector2D(20.0f, 20.0f)); + + bool modern; + CVARS_GET("cgui_modern_interface", modern); + m_pInterfaceModern->SetSelected(modern); + // Grab languages and populate for (const auto& strLocale : g_pCore->GetLocalization()->GetAvailableLocales()) { @@ -3711,6 +3725,10 @@ void CSettings::SaveData() CVARS_SET("server_can_flash_window", m_pFlashWindow->GetSelected()); CVARS_SET("allow_tray_notifications", m_pTrayBalloon->GetSelected()); + // Save modern skin setting + CVARS_SET("cgui_modern_interface", m_pInterfaceModern->GetSelected()); + + // Set our new skin last, as it'll destroy all our GUI pItem = m_pInterfaceSkinSelector->GetSelectedItem(); if (pItem) @@ -4926,3 +4944,15 @@ bool CSettings::IsActive() { return m_pWindow->IsActive(); } + +bool CSettings::OnModernClick(CGUIElement* pElement) +{ + if (m_bIsModLoaded) + { + m_pInterfaceModern->SetSelected(!m_pInterfaceModern->GetSelected()); + g_pCore->ShowMessageBox(_("Error") + _E("CC82"), _("Please disconnect before changing the modern interface"), MB_BUTTON_OK | MB_ICON_INFO); + m_pWindow->MoveToBack(); + return true; + } + return true; +} diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 91a14ca40e..4678d94826 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -288,6 +288,9 @@ class CSettings CGUIComboBox* m_pInterfaceSkinSelector; CGUIButton* m_pInterfaceLoadSkin; + CGUILabel* m_pInterfaceModernLabel; + CGUICheckBox* m_pInterfaceModern; + CGUIComboBox* m_pChatPresets; CGUIButton* m_pChatLoadPreset; @@ -408,6 +411,8 @@ class CSettings bool OnTabChanged(CGUIElement* pElement); void ReloadBrowserLists(); + bool OnModernClick(CGUIElement* pElement); + private: void CreateInterfaceTabGUI(); void UpdateChatColorPreview(eChatColorType eType); diff --git a/Client/core/ServerBrowser/CServerBrowser.cpp b/Client/core/ServerBrowser/CServerBrowser.cpp index 2ea47cafdf..eb9f3f1bab 100644 --- a/Client/core/ServerBrowser/CServerBrowser.cpp +++ b/Client/core/ServerBrowser/CServerBrowser.cpp @@ -333,7 +333,7 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) m_pLabelAddressDescription[type] = reinterpret_cast(pManager->CreateLabel(m_pEditAddress[type], "Enter an address [IP:Port]")); m_pLabelAddressDescription[type]->SetPosition(CVector2D(10, 5), false); - m_pLabelAddressDescription[type]->SetTextColor(0, 0, 0); + m_pLabelAddressDescription[type]->SetPlaceholderColors(); m_pLabelAddressDescription[type]->AutoSize(m_pLabelAddressDescription[type]->GetText().c_str()); m_pLabelAddressDescription[type]->SetAlpha(0.6f); m_pLabelAddressDescription[type]->SetProperty("MousePassThroughEnabled", "True"); @@ -421,7 +421,7 @@ void CServerBrowser::CreateTab(ServerBrowserType type, const char* szName) m_pLabelSearchDescription[type] = reinterpret_cast(pManager->CreateLabel(m_pEditSearch[type], _("Search servers..."))); m_pLabelSearchDescription[type]->SetPosition(CVector2D(10, 3), false); - m_pLabelSearchDescription[type]->SetTextColor(0, 0, 0); + m_pLabelSearchDescription[type]->SetPlaceholderColors(); m_pLabelSearchDescription[type]->SetSize(CVector2D(1, 1), true); m_pLabelSearchDescription[type]->SetAlpha(0.6f); m_pLabelSearchDescription[type]->SetProperty("MousePassThroughEnabled", "True"); diff --git a/Client/gui/CGUIButton_Impl.cpp b/Client/gui/CGUIButton_Impl.cpp index ac48dc86f5..b34426d268 100644 --- a/Client/gui/CGUIButton_Impl.cpp +++ b/Client/gui/CGUIButton_Impl.cpp @@ -22,7 +22,7 @@ CGUIButton_Impl::CGUIButton_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const ch pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIBUTTON_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIBUTTON_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setText(CGUI_Impl::GetUTFString(szCaption)); diff --git a/Client/gui/CGUICheckBox_Impl.cpp b/Client/gui/CGUICheckBox_Impl.cpp index e7967fe126..884c1f9270 100644 --- a/Client/gui/CGUICheckBox_Impl.cpp +++ b/Client/gui/CGUICheckBox_Impl.cpp @@ -22,7 +22,7 @@ CGUICheckBox_Impl::CGUICheckBox_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, cons pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUICHECKBOX_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUICHECKBOX_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setText(CGUI_Impl::GetUTFString(szCaption)); diff --git a/Client/gui/CGUIComboBox_Impl.cpp b/Client/gui/CGUIComboBox_Impl.cpp index b5783e8848..a5605c7a34 100644 --- a/Client/gui/CGUIComboBox_Impl.cpp +++ b/Client/gui/CGUIComboBox_Impl.cpp @@ -22,7 +22,7 @@ CGUIComboBox_Impl::CGUIComboBox_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, cons pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUICOMBOBOX_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUICOMBOBOX_NAME), szUnique); m_pWindow->setDestroyedByParent(false); // This needs a better alternative, so changing comboBox will change this - Jyrno42 diff --git a/Client/gui/CGUIEdit_Impl.cpp b/Client/gui/CGUIEdit_Impl.cpp index ddb7c91f17..badbd0675e 100644 --- a/Client/gui/CGUIEdit_Impl.cpp +++ b/Client/gui/CGUIEdit_Impl.cpp @@ -22,7 +22,7 @@ CGUIEdit_Impl::CGUIEdit_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* pGUI->GetUniqueName(szUnique); // Create the edit and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIEDIT_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIEDIT_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Absolute, CEGUI::Rect(0.00f, 0.00f, 0.128f, 0.24f)); diff --git a/Client/gui/CGUIGridList_Impl.cpp b/Client/gui/CGUIGridList_Impl.cpp index bed682670a..f351a08ea7 100644 --- a/Client/gui/CGUIGridList_Impl.cpp +++ b/Client/gui/CGUIGridList_Impl.cpp @@ -32,9 +32,9 @@ CGUIGridList_Impl::CGUIGridList_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, bool // Create the window and set default settings if (bFrame) - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIGRIDLIST_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIGRIDLIST_NAME), szUnique); else - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIGRIDLISTNOFRAME_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIGRIDLISTNOFRAME_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.00f, 0.00f, 0.40f, 0.40f)); diff --git a/Client/gui/CGUILabel_Impl.cpp b/Client/gui/CGUILabel_Impl.cpp index c07103da79..1b470abc7a 100644 --- a/Client/gui/CGUILabel_Impl.cpp +++ b/Client/gui/CGUILabel_Impl.cpp @@ -22,7 +22,7 @@ CGUILabel_Impl::CGUILabel_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUILABEL_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUILABEL_NAME), szUnique); m_pWindow->setDestroyedByParent(false); // Store the pointer to this CGUI element in the CEGUI element @@ -164,3 +164,27 @@ float CGUILabel_Impl::GetTextExtent() return 0.0f; } + +void CGUILabel_Impl::InvertTextColor() +{ + auto& color = GetTextColor(); + SetTextColor(255 - color.R, 255 - color.G, 255 - color.B); +} + +void CGUILabel_Impl::SetPlaceholderColors() +{ + auto* text = reinterpret_cast(m_pWindow); + + if (!text->isPropertyPresent("PlaceholderTextColours")) + { + InvertTextColor(); + return; + } + + auto& prop = text->getProperty("PlaceholderTextColours"); + + unsigned int color = 0; + const char* buffer = prop.c_str(); + sscanf(buffer, "tl:%x tr:%x bl:%x br:%x", &color, &color, &color, &color); + SetTextColor(color >> 16, (color >> 8) & 0xFF, color & 0xFF); +} diff --git a/Client/gui/CGUILabel_Impl.h b/Client/gui/CGUILabel_Impl.h index 121c7cb3e6..563ebab70e 100644 --- a/Client/gui/CGUILabel_Impl.h +++ b/Client/gui/CGUILabel_Impl.h @@ -43,7 +43,11 @@ class CGUILabel_Impl : public CGUILabel, public CGUIElement_Impl eCGUIType GetType() { return CGUI_LABEL; }; + void InvertTextColor(); + void SetPlaceholderColors(); + #define EXCLUDE_SET_TEXT #include "CGUIElement_Inc.h" #undef EXCLUDE_SET_TEXT + }; diff --git a/Client/gui/CGUIListItem_Impl.cpp b/Client/gui/CGUIListItem_Impl.cpp index 0a2e8c6569..a5ffabccb9 100644 --- a/Client/gui/CGUIListItem_Impl.cpp +++ b/Client/gui/CGUIListItem_Impl.cpp @@ -11,6 +11,8 @@ #include "StdInc.h" +extern CGUI_Impl* g_pGUI; + CGUIListItem_Impl::CGUIListItem_Impl(const char* szText, unsigned int uiType, CGUIStaticImage_Impl* pImage) { ItemType = uiType; @@ -33,7 +35,7 @@ CGUIListItem_Impl::CGUIListItem_Impl(const char* szText, unsigned int uiType, CG { // Set flags and properties m_pListItem->setAutoDeleted(false); - m_pListItem->setSelectionBrushImage("CGUI-Images", "ListboxSelectionBrush"); + m_pListItem->setSelectionBrushImage("CGUI-Images", g_pGUI->ResolveModernName("ListboxSelectionBrush")); } m_pData = NULL; diff --git a/Client/gui/CGUIMemo_Impl.cpp b/Client/gui/CGUIMemo_Impl.cpp index 61746b29f0..845f38c0a1 100644 --- a/Client/gui/CGUIMemo_Impl.cpp +++ b/Client/gui/CGUIMemo_Impl.cpp @@ -22,7 +22,7 @@ CGUIMemo_Impl::CGUIMemo_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const char* pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIMEMO_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIMEMO_NAME), szUnique); m_pWindow->setDestroyedByParent(false); // Store the pointer to this CGUI element in the CEGUI element diff --git a/Client/gui/CGUIProgressBar_Impl.cpp b/Client/gui/CGUIProgressBar_Impl.cpp index 113afc5fa9..f7e17c39f5 100644 --- a/Client/gui/CGUIProgressBar_Impl.cpp +++ b/Client/gui/CGUIProgressBar_Impl.cpp @@ -22,7 +22,7 @@ CGUIProgressBar_Impl::CGUIProgressBar_Impl(CGUI_Impl* pGUI, CGUIElement* pParent pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUILABEL_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUILABEL_NAME), szUnique); m_pWindow->setDestroyedByParent(false); // Store the pointer to this CGUI element in the CEGUI element diff --git a/Client/gui/CGUIRadioButton_Impl.cpp b/Client/gui/CGUIRadioButton_Impl.cpp index dee554707d..cd07ee2e96 100644 --- a/Client/gui/CGUIRadioButton_Impl.cpp +++ b/Client/gui/CGUIRadioButton_Impl.cpp @@ -22,7 +22,7 @@ CGUIRadioButton_Impl::CGUIRadioButton_Impl(CGUI_Impl* pGUI, CGUIElement* pParent pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIRADIOBUTTON_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIRADIOBUTTON_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setText(CGUI_Impl::GetUTFString(szCaption)); diff --git a/Client/gui/CGUIScrollBar_Impl.cpp b/Client/gui/CGUIScrollBar_Impl.cpp index 07e8cc61ad..2375d9c81c 100644 --- a/Client/gui/CGUIScrollBar_Impl.cpp +++ b/Client/gui/CGUIScrollBar_Impl.cpp @@ -23,7 +23,7 @@ CGUIScrollBar_Impl::CGUIScrollBar_Impl(CGUI_Impl* pGUI, bool bHorizontal, CGUIEl pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(bHorizontal ? CGUISCROLLBAR_HORIZONTAL_NAME : CGUISCROLLBAR_VERTICAL_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(bHorizontal ? CGUISCROLLBAR_HORIZONTAL_NAME : CGUISCROLLBAR_VERTICAL_NAME), szUnique); m_pWindow->setDestroyedByParent(false); // Store the pointer to this CGUI element in the CEGUI element diff --git a/Client/gui/CGUIScrollPane_Impl.cpp b/Client/gui/CGUIScrollPane_Impl.cpp index 2849308aa1..92d3762636 100644 --- a/Client/gui/CGUIScrollPane_Impl.cpp +++ b/Client/gui/CGUIScrollPane_Impl.cpp @@ -25,7 +25,7 @@ CGUIScrollPane_Impl::CGUIScrollPane_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUISCROLLPANE_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUISCROLLPANE_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.9f, 0.9f, 0.9f, 0.9f)); diff --git a/Client/gui/CGUIStaticImage_Impl.cpp b/Client/gui/CGUIStaticImage_Impl.cpp index b57d75f0ca..7d8af1cb20 100644 --- a/Client/gui/CGUIStaticImage_Impl.cpp +++ b/Client/gui/CGUIStaticImage_Impl.cpp @@ -29,7 +29,7 @@ CGUIStaticImage_Impl::CGUIStaticImage_Impl(CGUI_Impl* pGUI, CGUIElement* pParent pGUI->GetUniqueName(szUnique); // Create the control and set default properties - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUISTATICIMAGE_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUISTATICIMAGE_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.0f, 0.0f, 1.0f, 1.0f)); reinterpret_cast(m_pWindow)->setBackgroundEnabled(false); diff --git a/Client/gui/CGUITabPanel_Impl.cpp b/Client/gui/CGUITabPanel_Impl.cpp index 8ad196a467..b44d6b78df 100644 --- a/Client/gui/CGUITabPanel_Impl.cpp +++ b/Client/gui/CGUITabPanel_Impl.cpp @@ -25,7 +25,7 @@ CGUITabPanel_Impl::CGUITabPanel_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) pGUI->GetUniqueName(szUnique); // Create the window and set default settings - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUITABPANEL_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUITABPANEL_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.9f, 0.9f, 0.9f, 0.9f)); reinterpret_cast(m_pWindow)->setAbsoluteTabTextPadding(10.0f); diff --git a/Client/gui/CGUIWebBrowser_Impl.cpp b/Client/gui/CGUIWebBrowser_Impl.cpp index 308f2945d0..b3f7b90531 100644 --- a/Client/gui/CGUIWebBrowser_Impl.cpp +++ b/Client/gui/CGUIWebBrowser_Impl.cpp @@ -26,7 +26,7 @@ CGUIWebBrowser_Impl::CGUIWebBrowser_Impl(CGUI_Impl* pGUI, CGUIElement* pParent) pGUI->GetUniqueName(szUnique); // Create the control and set default properties - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIWEBBROWSER_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIWEBBROWSER_NAME), szUnique); m_pWindow->setDestroyedByParent(false); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.0f, 0.0f, 1.0f, 1.0f)); reinterpret_cast(m_pWindow)->setBackgroundEnabled(false); diff --git a/Client/gui/CGUIWindow_Impl.cpp b/Client/gui/CGUIWindow_Impl.cpp index 6936cbdbc9..d9e7fd36d0 100644 --- a/Client/gui/CGUIWindow_Impl.cpp +++ b/Client/gui/CGUIWindow_Impl.cpp @@ -32,7 +32,7 @@ CGUIWindow_Impl::CGUIWindow_Impl(CGUI_Impl* pGUI, CGUIElement* pParent, const ch if (!m_pWindow) { // Create new here - m_pWindow = pGUI->GetWindowManager()->createWindow(CGUIWINDOW_NAME, szUnique); + m_pWindow = pGUI->GetWindowManager()->createWindow(pGUI->ResolveModernName(CGUIWINDOW_NAME), szUnique); m_pWindow->setRect(CEGUI::Relative, CEGUI::Rect(0.10f, 0.10f, 0.60f, 0.90f)); m_pWindow->setAlpha(0.8f); diff --git a/Client/gui/CGUI_Impl.cpp b/Client/gui/CGUI_Impl.cpp index 67d625ed5e..0229a7bfbd 100644 --- a/Client/gui/CGUI_Impl.cpp +++ b/Client/gui/CGUI_Impl.cpp @@ -11,24 +11,30 @@ #include "StdInc.h" #include "CEGUIExceptions.h" +#include +#include +#include +#include +#include +#include using std::list; -#define CGUI_MTA_DEFAULT_FONT "tahoma.ttf" // %WINDIR%/font/<...> -#define CGUI_MTA_DEFAULT_FONT_BOLD "tahomabd.ttf" // %WINDIR%/font/<...> -#define CGUI_MTA_CLEAR_FONT "verdana.ttf" // %WINDIR%/font/<...> +#define CGUI_MTA_DEFAULT_FONT "tahoma.ttf" // %WINDIR%/font/<...> +#define CGUI_MTA_DEFAULT_FONT_BOLD "tahomabd.ttf" // %WINDIR%/font/<...> +#define CGUI_MTA_CLEAR_FONT "verdana.ttf" // %WINDIR%/font/<...> -#define CGUI_MTA_DEFAULT_REG "Tahoma (TrueType)" -#define CGUI_MTA_DEFAULT_REG_BOLD "Tahoma Bold (TrueType)" -#define CGUI_MTA_CLEAR_REG "Verdana (TrueType)" +#define CGUI_MTA_DEFAULT_REG "Tahoma (TrueType)" +#define CGUI_MTA_DEFAULT_REG_BOLD "Tahoma Bold (TrueType)" +#define CGUI_MTA_CLEAR_REG "Verdana (TrueType)" -#define CGUI_MTA_SUBSTITUTE_FONT "cgui/unifont.ttf" // GTA/MTA/<...> -#define CGUI_MTA_SANS_FONT "cgui/sans.ttf" // GTA/MTA/<...> -#define CGUI_SA_HEADER_FONT "cgui/saheader.ttf" // GTA/MTA/<...> -#define CGUI_SA_GOTHIC_FONT "cgui/sagothic.ttf" // GTA/MTA/<...> -#define CGUI_SA_HEADER_SIZE 26 -#define CGUI_SA_GOTHIC_SIZE 47 -#define CGUI_MTA_SANS_FONT_SIZE 9 +#define CGUI_MTA_SUBSTITUTE_FONT "cgui/unifont.ttf" // GTA/MTA/<...> +#define CGUI_MTA_SANS_FONT "cgui/sans.ttf" // GTA/MTA/<...> +#define CGUI_SA_HEADER_FONT "cgui/saheader.ttf" // GTA/MTA/<...> +#define CGUI_SA_GOTHIC_FONT "cgui/sagothic.ttf" // GTA/MTA/<...> +#define CGUI_SA_HEADER_SIZE 26 +#define CGUI_SA_GOTHIC_SIZE 47 +#define CGUI_MTA_SANS_FONT_SIZE 9 CGUI_Impl::CGUI_Impl(IDirect3DDevice9* pDevice) : m_HasSchemeLoaded(false), m_fCurrentServerCursorAlpha(1.0f) { @@ -115,7 +121,15 @@ void CGUI_Impl::SetSkin(const char* szName) CEGUI::SchemeManager::getSingleton().unloadScheme(m_CurrentSchemeName); } - PushGuiWorkingDirectory(CalcMTASAPath(PathJoin("skins", szName))); + bool bConvertSkin = ConvertToModernSkin(szName); + + if (!bConvertSkin) + { + BrowseToSolution("gui-skin", EXIT_GAME_FIRST, SString("Error converting skin '%s' to modern", szName)); + return; + } + + PushGuiWorkingDirectory(CalcMTASAPath(PathJoin("MTA", "cgui", "modern", "autogenerated"))); CEGUI::Scheme* scheme = CEGUI::SchemeManager::getSingleton().loadScheme("CGUI.xml"); m_CurrentSchemeName = scheme->getName().c_str(); @@ -123,7 +137,7 @@ void CGUI_Impl::SetSkin(const char* szName) PopGuiWorkingDirectory(); - CEGUI::System::getSingleton().setDefaultMouseCursor("CGUI-Images", "MouseArrow"); + CEGUI::System::getSingleton().setDefaultMouseCursor("CGUI-Images", "MouseArrowModern"); // Always use modern mouse arrow // Destroy any windows we already have CEGUI::WindowManager::getSingleton().destroyAllWindows(); @@ -150,6 +164,351 @@ void CGUI_Impl::SetSkin(const char* szName) m_eInputMode = INPUTMODE_NO_BINDS_ON_EDIT; } +bool CGUI_Impl::ConvertToModernSkin(const char* skinName) +{ + if (!m_pXML) + { + AddReportLog(1337, "ConvertToModernSkin: XML interface not initialized"); + return false; + } + + if (!m_pGraphics) + { + AddReportLog(1337, "ConvertToModernSkin: Graphics interface not initialized"); + return false; + } + + // Duplicate all the CGUI files in the skin folder to a temporary folder + SString skinPath = CalcMTASAPath(PathJoin("skins", skinName)); + + if (!DirectoryExists(skinPath)) + { + AddReportLog(1337, "ConvertToModernSkin: Skin folder not found"); + return false; + } + + SString modernPath = PathJoin("MTA", "cgui", "modern"); + SString tempPath = CalcMTASAPath(PathJoin(modernPath, "autogenerated")); + SString modernVersionPath = CalcMTASAPath(PathJoin(modernPath, ".version")); + SString tempVersionPath = PathJoin(tempPath, ".version"); + + if (!DirectoryExists(tempPath)) + { + CreateDirectory(tempPath, 0); + } + else + { + // Verify if the modern skin version has changed since the skin was last converted + std::ifstream modernVersionFile(modernVersionPath); + std::string modernVersion; + + if (modernVersionFile.is_open()) + { + std::getline(modernVersionFile, modernVersion); + modernVersionFile.close(); + } + + std::ifstream tempVersionFile(tempVersionPath); + std::string tempVersion; + + if (tempVersionFile.is_open()) + { + std::getline(tempVersionFile, tempVersion); + tempVersionFile.close(); + } + + if (!modernVersion.empty() && !tempVersion.empty() && modernVersion == tempVersion) + { + // Verify if the skin has changed, or if files already up to date + SString hashesPath = PathJoin(tempPath, ".integrity"); + + if (FileExists(hashesPath)) + { + std::ifstream hashesFile(hashesPath); + + if (hashesFile.good()) + { + std::string checkSkinName; + std::getline(hashesFile, checkSkinName); + + if (checkSkinName == skinName) + { + SString lookNFeelXmlPath = PathJoin(skinPath, "CGUI.lnf.xml"); + SString imagesetXmlPath = PathJoin(skinPath, "CGUI.is.xml"); + SString imagesetPngPath = PathJoin(skinPath, "CGUI.png"); + SString schemeXmlPath = PathJoin(skinPath, "CGUI.xml"); + + SString lookNFeelXmlHash = CMD5Hasher::CalculateHexString(lookNFeelXmlPath); + SString imagesetXmlHash = CMD5Hasher::CalculateHexString(imagesetXmlPath); + SString imagesetPngHash = CMD5Hasher::CalculateHexString(imagesetPngPath); + SString schemeXmlHash = CMD5Hasher::CalculateHexString(schemeXmlPath); + + std::string hashes; + std::getline(hashesFile, hashes); + + if (hashes == lookNFeelXmlHash + imagesetXmlHash + imagesetPngHash + schemeXmlHash) + { + hashesFile.close(); + return true; + } + } + } + } + } + } + + // Copy all files from requested skin to 'temporary' folder + SString skinLookNFeelXmlPath = PathJoin(skinPath, "CGUI.lnf.xml"); + SString skinImagesetXmlPath = PathJoin(skinPath, "CGUI.is.xml"); + SString skinImagesetPngPath = PathJoin(skinPath, "CGUI.png"); + SString skinSchemeXmlPath = PathJoin(skinPath, "CGUI.xml"); + + if (!FileExists(skinLookNFeelXmlPath) || !FileExists(skinImagesetXmlPath) || !FileExists(skinImagesetPngPath) || !FileExists(skinSchemeXmlPath)) + { + AddReportLog(1337, "ConvertToModernSkin: Skin files not found"); + return false; + } + + SString tempLookNFeelXmlPath = PathJoin(tempPath, "CGUI.lnf.xml"); + SString tempImagesetXmlPath = PathJoin(tempPath, "CGUI.is.xml"); + SString tempImagesetPngPath = PathJoin(tempPath, "CGUI.png"); + SString tempSchemeXmlPath = PathJoin(tempPath, "CGUI.xml"); + + CopyFile(skinLookNFeelXmlPath, tempLookNFeelXmlPath, 0); + CopyFile(skinImagesetXmlPath, tempImagesetXmlPath, 0); + CopyFile(skinImagesetPngPath, tempImagesetPngPath, 0); + CopyFile(skinSchemeXmlPath, tempSchemeXmlPath, 0); + + if (!FileExists(tempLookNFeelXmlPath) || !FileExists(tempImagesetXmlPath) || !FileExists(tempImagesetPngPath) || !FileExists(tempSchemeXmlPath)) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to copy skin files"); + return false; + } + + // Store the hashes of each file under .skinname + SString integrityFilePath = PathJoin(tempPath, ".integrity"); + std::ofstream integrityFileStream(integrityFilePath, std::ofstream::out | std::ofstream::trunc); + + if (!integrityFileStream.is_open()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open integrity file stream"); + return false; + } + + SString lookNFeelXmlHash = CMD5Hasher::CalculateHexString(skinLookNFeelXmlPath); + SString imagesetXmlHash = CMD5Hasher::CalculateHexString(skinImagesetXmlPath); + SString imagesetPngHash = CMD5Hasher::CalculateHexString(skinImagesetPngPath); + SString schemeXmlHash = CMD5Hasher::CalculateHexString(skinSchemeXmlPath); + + integrityFileStream << skinName << std::endl; + integrityFileStream << lookNFeelXmlHash << imagesetXmlHash << imagesetPngHash << schemeXmlHash; + integrityFileStream.close(); + + // Open the modern XML templates (using TinyXML) + SString modernTemplatesPath = CalcMTASAPath(PathJoin(modernPath, "templates")); + SString modernLookNFeelPath = PathJoin(modernTemplatesPath, "looknfeel.xml"); + SString modernSchemePath = PathJoin(modernTemplatesPath, "scheme.xml"); + SString modernImagesetXmlPath = PathJoin(modernTemplatesPath, "imageset.xml"); + SString modernImagesetPngPath = PathJoin(modernTemplatesPath, "imageset.png"); + + if (!FileExists(modernLookNFeelPath) || !FileExists(modernSchemePath) || !FileExists(modernImagesetXmlPath) || !FileExists(modernImagesetPngPath)) + { + AddReportLog(1337, "ConvertToModernSkin: Modern skin templates not found"); + return false; + } + + // Load the modern LookNFeel, read-only + CXMLFile* modernLookNFeelFile = m_pXML->CreateXML(modernLookNFeelPath, false, true); + + if (!modernLookNFeelFile || !modernLookNFeelFile->Parse()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open/parse modern LookNFeel"); + return false; + } + + // Load the requested skin's LookNFeel, read-write + CXMLFile* skinLookNFeelFile = m_pXML->CreateXML(tempLookNFeelXmlPath); + + if (!skinLookNFeelFile || !skinLookNFeelFile->Parse()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open/parse skin LookNFeel"); + return false; + } + + // Copy the modern LookNFeel into the skin LookNFeel + CXMLNode* modernRootNode = modernLookNFeelFile->GetRootNode(); + modernRootNode->CopyChildrenInto(skinLookNFeelFile->GetRootNode(), true, false); + + // Save the skin LookNFeel + if (!skinLookNFeelFile->Write()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to write skin LookNFeel"); + return false; + } + + delete modernLookNFeelFile; + delete skinLookNFeelFile; + + // Load the modern scheme, read-only + CXMLFile* modernSchemeFile = m_pXML->CreateXML(modernSchemePath, false, true); + + if (!modernSchemeFile || !modernSchemeFile->Parse()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open/parse modern scheme"); + return false; + } + + // Load the requested skin's scheme, read-write + CXMLFile* skinSchemeFile = m_pXML->CreateXML(tempSchemeXmlPath); + + if (!skinSchemeFile || !skinSchemeFile->Parse()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open/parse skin scheme"); + return false; + } + + // Copy the modern scheme into the skin scheme + modernRootNode = modernSchemeFile->GetRootNode(); + modernRootNode->CopyChildrenInto(skinSchemeFile->GetRootNode(), true, false); + + // Save the skin scheme + if (!skinSchemeFile->Write()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to write skin scheme"); + return false; + } + + delete modernSchemeFile; + delete skinSchemeFile; + + // Load the imagesets as CTextureItem + auto renderManager = m_pGraphics->GetRenderItemManager(); + auto modernImagesetTexture = renderManager->CreateTexture(modernImagesetPngPath); + auto skinImagesetTexture = renderManager->CreateTexture(skinImagesetPngPath); + + if (!modernImagesetTexture || !skinImagesetTexture) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to create imageset textures"); + return false; + } + + // Create a render target to hold both imagesets + int width = modernImagesetTexture->m_uiSizeX + skinImagesetTexture->m_uiSizeX; + auto renderTarget = + renderManager->CreateRenderTarget(width, std::max(modernImagesetTexture->m_uiSizeY, skinImagesetTexture->m_uiSizeY), false, true, 0, true); + + auto device = m_pGraphics->GetDevice(); + + if (!m_HasSchemeLoaded && device->BeginScene() != D3D_OK) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to begin scene for imageset drawing"); + return false; + } + + // Start draw batch + renderManager->SetRenderTarget(renderTarget, true); + + // Draw the imagesets side-by-side + m_pGraphics->DrawTexture(skinImagesetTexture, 0, 0, 1, 1, 0, 0, 0, 0xFFFFFFFF, 0, 0, 1, 1, true); + m_pGraphics->DrawTexture(modernImagesetTexture, skinImagesetTexture->m_uiSizeX, 0, 1, 1, 0, 0, 0, 0xFFFFFFFF, 0, 0, 1, 1, true); + + // Stop draw batch + renderManager->RestoreDefaultRenderTarget(); + + if (!m_HasSchemeLoaded && device->EndScene() != D3D_OK) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to end scene for imageset drawing"); + return false; + } + + D3DXSaveTextureToFile(tempImagesetPngPath, D3DXIFF_PNG, renderTarget->m_pD3DTexture, 0); + + if (!FileExists(tempImagesetPngPath)) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to save imageset texture"); + return false; + } + + // Load the requested skin's imageset, read-write + CXMLFile* tempImagesetFile = m_pXML->CreateXML(tempImagesetXmlPath); + + if (!tempImagesetFile || !tempImagesetFile->Parse()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open/parse skin imageset"); + return false; + } + + // Load the modern imageset, read-only + CXMLFile* modernImagesetFile = m_pXML->CreateXML(modernImagesetXmlPath, false, true); + + if (!modernImagesetFile || !modernImagesetFile->Parse()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to open/parse modern imageset"); + return false; + } + + // Adjust each Image in the modern imageset to have the correct offset (XPos, YPos) + modernRootNode = modernImagesetFile->GetRootNode(); + + for (uint i = 0; i < modernRootNode->GetSubNodeCount(); i++) + { + CXMLNode* node = modernRootNode->GetSubNode(i); + CXMLAttributes& attributes = node->GetAttributes(); + + auto xPos = attributes.Find("XPos"); + + if (xPos) + { + try + { + auto x = std::stoi(xPos->GetValue()); + xPos->SetValue((uint)x + skinImagesetTexture->m_uiSizeX); + } + catch (std::invalid_argument) + { + AddReportLog(1337, "ConvertToModernSkin: Invalid XPos value in imageset"); + return false; + } + } + } + + // Set the Imageset root node NativeHorzRes and NativeVertRes to the modern imageset's resolution + CXMLAttributes& skinAttributes = tempImagesetFile->GetRootNode()->GetAttributes(); + CXMLAttributes& modernAttributes = modernImagesetFile->GetRootNode()->GetAttributes(); + + auto skinHorzRes = skinAttributes.Find("NativeHorzRes"); + auto skinVertRes = skinAttributes.Find("NativeVertRes"); + auto modernHorzRes = modernAttributes.Find("NativeHorzRes"); + auto modernVertRes = modernAttributes.Find("NativeVertRes"); + + if (skinHorzRes && skinVertRes && modernHorzRes && modernVertRes) + { + skinHorzRes->SetValue(modernHorzRes->GetValue().c_str()); + skinVertRes->SetValue(modernVertRes->GetValue().c_str()); + } + + // Copy the modern imageset into the skin imageset + modernRootNode->CopyChildrenInto(tempImagesetFile->GetRootNode(), true, false); + + // Save the skin imageset + if (!tempImagesetFile->Write()) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to write skin imageset"); + return false; + } + + // Copy the modern version file + CopyFile(modernVersionPath, tempVersionPath, 0); + + if (!FileExists(tempVersionPath)) + { + AddReportLog(1337, "ConvertToModernSkin: Failed to copy modern version file"); + return false; + } + + return true; +} + void CGUI_Impl::SetBidiEnabled(bool bEnabled) { m_pSystem->SetBidiEnabled(bEnabled); @@ -1700,3 +2059,8 @@ CEGUI::Window* CGUI_Impl::GetMasterWindow(CEGUI::Window* wnd) } return wnd; } + +std::string CGUI_Impl::ResolveModernName(const char* name) +{ + return m_bUseModernSkin ? std::string(name) + "Modern" : name; +} diff --git a/Client/gui/CGUI_Impl.h b/Client/gui/CGUI_Impl.h index 3015380866..c93593144c 100644 --- a/Client/gui/CGUI_Impl.h +++ b/Client/gui/CGUI_Impl.h @@ -16,6 +16,8 @@ class CGUI_Impl; #include #include #include +#include +#include #define CGUI_CHAR_SIZE 6 @@ -279,6 +281,12 @@ class CGUI_Impl : public CGUI, public CGUITabList CGUIWindow* LoadLayout(CGUIElement* pParent, const SString& strFilename); bool LoadImageset(const SString& strFilename); + void SetModernSkinEnabled(bool bEnabled) { m_bUseModernSkin = bEnabled; } + std::string ResolveModernName(const char* name); + + void SetXMLParser(CXML* pXML) { m_pXML = pXML; } + void SetGraphics(CGraphicsInterface* pGraphicsInterface) { m_pGraphics = pGraphicsInterface; } + private: CGUIButton* _CreateButton(CGUIElement_Impl* pParent = NULL, const char* szCaption = ""); CGUICheckBox* _CreateCheckBox(CGUIElement_Impl* pParent = NULL, const char* szCaption = "", bool bChecked = false); @@ -300,6 +308,8 @@ class CGUI_Impl : public CGUI, public CGUITabList bool bAutoScale = false); void ApplyGuiWorkingDirectory(); + bool ConvertToModernSkin(const char* skinName); + IDirect3DDevice9* m_pDevice; CEGUI::Renderer* m_pRenderer; @@ -350,4 +360,8 @@ class CGUI_Impl : public CGUI, public CGUITabList bool m_HasSchemeLoaded; SString m_CurrentSchemeName; CElapsedTime m_RenderOkTimer; + + bool m_bUseModernSkin = false; + CGraphicsInterface* m_pGraphics; + CXML* m_pXML; }; diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index 1fb33f54bc..d5b16df17d 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -66,7 +66,7 @@ void CTransferBox::CreateTransferWindow() float fTempX = (m_progressBar->GetSize().fX - m_GUI->GetTextExtent(m_infoLabel->GetText().c_str()) - TRANSFERBOX_ICONSIZE - 4) * 0.5f; m_infoLabel->SetPosition(CVector2D(fTempX + TRANSFERBOX_ICONSIZE + 4, 0)); m_infoLabel->SetSize(CVector2D(fTransferBoxWidth, TRANSFERBOX_PROGRESSHEIGHT)); - m_infoLabel->SetTextColor(0, 0, 0); + m_infoLabel->SetPlaceholderColors(); m_infoLabel->SetVerticalAlign(CGUI_ALIGN_VERTICALCENTER); for (size_t i = 0; i < m_iconImages.size(); ++i) diff --git a/Client/sdk/core/CGraphicsInterface.h b/Client/sdk/core/CGraphicsInterface.h index b8e0ef744b..ebdf479e6b 100644 --- a/Client/sdk/core/CGraphicsInterface.h +++ b/Client/sdk/core/CGraphicsInterface.h @@ -103,6 +103,12 @@ enum class eRenderStage POST_GUI }; +class CTextureItem; +class CMaterialItem; +class CRenderItemManagerInterface; +class CScreenGrabberInterface; +class CPixelsManagerInterface; + class CGraphicsInterface { public: diff --git a/Client/sdk/gui/CGUI.h b/Client/sdk/gui/CGUI.h index d6e27bd3da..d4d40c2f09 100644 --- a/Client/sdk/gui/CGUI.h +++ b/Client/sdk/gui/CGUI.h @@ -37,6 +37,9 @@ class CGUI; #include "CGUIComboBox.h" #include "CGUITypes.h" +class CXML; +class CGraphicsInterface; + // Path defines for CGUI #define CGUI_ICON_MESSAGEBOX_INFO "cgui\\images\\info.png" #define CGUI_ICON_MESSAGEBOX_QUESTION "cgui\\images\\question.png" @@ -169,4 +172,8 @@ class CGUI virtual CGUIWindow* LoadLayout(CGUIElement* pParent, const SString& strFilename) = 0; virtual bool LoadImageset(const SString& strFilename) = 0; + + virtual void SetModernSkinEnabled(bool bEnabled) = 0; + virtual void SetXMLParser(CXML* pXML) = 0; + virtual void SetGraphics(CGraphicsInterface* pGraphicsInterface) = 0; }; diff --git a/Client/sdk/gui/CGUILabel.h b/Client/sdk/gui/CGUILabel.h index b7eebff98d..993eb30bb4 100644 --- a/Client/sdk/gui/CGUILabel.h +++ b/Client/sdk/gui/CGUILabel.h @@ -36,4 +36,7 @@ class CGUILabel : public CGUIElement virtual float GetCharacterWidth(int iCharIndex) = 0; virtual float GetFontHeight() = 0; virtual float GetTextExtent() = 0; + + virtual void InvertTextColor() = 0; + virtual void SetPlaceholderColors() = 0; }; diff --git a/Shared/XML/CXMLNodeImpl.cpp b/Shared/XML/CXMLNodeImpl.cpp index 3c83fb7606..4ab9b43a52 100644 --- a/Shared/XML/CXMLNodeImpl.cpp +++ b/Shared/XML/CXMLNodeImpl.cpp @@ -365,10 +365,13 @@ CXMLNode* CXMLNodeImpl::CopyNode(CXMLNode* pParent) return dynamic_cast(pNew); } -bool CXMLNodeImpl::CopyChildrenInto(CXMLNode* pDestination, bool bRecursive) +bool CXMLNodeImpl::CopyChildrenInto(CXMLNode* pDestination, bool bRecursive, bool bDelete) { - // Delete all the children of the target - pDestination->DeleteAllSubNodes(); + if (bDelete) + { + // Delete all the children of the target + pDestination->DeleteAllSubNodes(); + } // Iterate through our children if we have. Otherwize just copy the content if (m_Children.size() > 0) @@ -405,14 +408,18 @@ bool CXMLNodeImpl::CopyChildrenInto(CXMLNode* pDestination, bool bRecursive) { if (!pMyChildNode->CopyChildrenInto(pNewChildNode, true)) { - pDestination->DeleteAllSubNodes(); + if (bDelete) + pDestination->DeleteAllSubNodes(); + return false; } } } else { - pDestination->DeleteAllSubNodes(); + if (bDelete) + pDestination->DeleteAllSubNodes(); + return false; } } diff --git a/Shared/XML/CXMLNodeImpl.h b/Shared/XML/CXMLNodeImpl.h index 369d23d79c..550bf1030a 100644 --- a/Shared/XML/CXMLNodeImpl.h +++ b/Shared/XML/CXMLNodeImpl.h @@ -71,7 +71,7 @@ class CXMLNodeImpl : public CXMLNode bool IsUsingIDs() { return m_bUsingIDs; }; CXMLNode* CopyNode(CXMLNode* pParent = NULL); - bool CopyChildrenInto(CXMLNode* pDestination, bool bRecursive); + bool CopyChildrenInto(CXMLNode* pDestination, bool bRecursive, bool bDelete = true); TiXmlElement* GetNode(); void DeleteWrapper(); diff --git a/Shared/data/MTA San Andreas/MTA/cgui/modern/.version b/Shared/data/MTA San Andreas/MTA/cgui/modern/.version new file mode 100644 index 0000000000..8a9ecc2ea9 --- /dev/null +++ b/Shared/data/MTA San Andreas/MTA/cgui/modern/.version @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file diff --git a/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/imageset.png b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/imageset.png new file mode 100644 index 0000000000..9103dd11fc Binary files /dev/null and b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/imageset.png differ diff --git a/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/imageset.xml b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/imageset.xml new file mode 100644 index 0000000000..aa65d63cf6 --- /dev/null +++ b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/imageset.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/looknfeel.xml b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/looknfeel.xml new file mode 100644 index 0000000000..2608d5171f --- /dev/null +++ b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/looknfeel.xml @@ -0,0 +1,2177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + +
+
+ +
+ + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+ + + + + + + + + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+
+
+ + +
+ + + + +
+ + + + +
+ +
+
+
+ + +
+ +
+
+
+ + + +
+ +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+ + +
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + +
+
+ +
+ + + + +
+ +
+
+ +
+
+
+ + +
+
+ +
+ + + + +
+
+ +
+ + + + +
+ +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + +
+
+ +
+ + + + +
+ +
+
+ +
+
+
+ + +
+
+ +
+ + + + +
+
+ +
+ + + + +
+ +
+
+ +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + diff --git a/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/scheme.xml b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/scheme.xml new file mode 100644 index 0000000000..fa92aeb85d --- /dev/null +++ b/Shared/data/MTA San Andreas/MTA/cgui/modern/templates/scheme.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Shared/sdk/xml/CXMLNode.h b/Shared/sdk/xml/CXMLNode.h index 80051930e6..016175928f 100644 --- a/Shared/sdk/xml/CXMLNode.h +++ b/Shared/sdk/xml/CXMLNode.h @@ -53,7 +53,7 @@ class CXMLNode : public CXMLCommon virtual void SetTagContentf(const char* szFormat, ...) = 0; virtual CXMLNode* CopyNode(CXMLNode* pParent) = 0; - virtual bool CopyChildrenInto(CXMLNode* pDestination, bool bRecursive) = 0; + virtual bool CopyChildrenInto(CXMLNode* pDestination, bool bRecursive, bool bDelete = true) = 0; virtual bool IsValid() = 0; @@ -62,4 +62,5 @@ class CXMLNode : public CXMLCommon virtual void SetCommentText(const char* szCommentText, bool bLeadingBlankLine = false) = 0; virtual std::string ToString() = 0; + virtual void AddToList(CXMLNode* pNode) = 0; };