SProxyWeb.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // Copyright aXiuShen. All Rights Reserved.
  2. #include "SProxyWeb.h"
  3. #include "Widgets/Text/STextBlock.h"
  4. #include "Widgets/Input/SEditableTextBox.h"
  5. #include "Widgets/Input/SButton.h"
  6. #include "Widgets/Images/SThrobber.h"
  7. #include "Kismet/KismetSystemLibrary.h"
  8. #include "Kismet/GameplayStatics.h"
  9. #include "GameFramework/PlayerInput.h"
  10. #include "Engine/Engine.h"
  11. #include "Engine/GameViewportClient.h"
  12. #include "Engine/World.h"
  13. #include "GameFramework/PlayerController.h"
  14. #include "RenderingThread.h"
  15. #include "Textures/SlateUpdatableTexture.h"
  16. #include "Framework/Application/SlateApplication.h"
  17. #include "Async/Async.h"
  18. #ifdef USING_WEBBROWSER
  19. #include "Misc/ConfigCacheIni.h"
  20. #include "WebBrowserViewport.h"
  21. #include "WebBrowserModule.h"
  22. #include "IWebBrowserWindow.h"
  23. #include "SWebBrowserView.h"
  24. //#if WITH_EDITOR
  25. //#include "Materials/MaterialInterface.h"
  26. //#include "Materials/MaterialExpressionMaterialFunctionCall.h"
  27. //#include "Materials/MaterialExpressionTextureSample.h"
  28. //#include "Materials/MaterialExpressionTextureSampleParameter2D.h"
  29. //#include "Materials/MaterialFunction.h"
  30. //#include "Materials/Material.h"
  31. //#include "Factories/MaterialFactoryNew.h"
  32. ////#include "AssetRegistryModule.h"
  33. //#include "PackageHelperFunctions.h"
  34. //#endif
  35. #define LOCTEXT_NAMESPACE "ProxyWeb"
  36. SProxyWeb::SProxyWeb()
  37. : local_dns(TEXT("local:/"))
  38. {
  39. SetCanTick(true);
  40. bMouseTransparency = false;
  41. TransparencyThreadshold = 255;
  42. GConfig->GetString(TEXT("WebView"), TEXT("local_domain"), local_domain, GGameIni);
  43. if (!local_domain.IsEmpty()) {
  44. FString con = FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir());
  45. local_domain = FPaths::Combine(*con,*local_domain);
  46. }
  47. }
  48. SProxyWeb::~SProxyWeb() {
  49. }
  50. FString SProxyWeb::dns_to_local(FString url)const {
  51. if (local_domain.IsEmpty()||!url.StartsWith(local_dns)) return url;
  52. return url.Replace(*local_dns, *local_domain);
  53. }
  54. FString SProxyWeb::local_to_dns(FString url) const {
  55. if (local_domain.IsEmpty() || !url.StartsWith(local_domain)) return url;
  56. return url.Replace(*local_domain, *local_dns);
  57. }
  58. void SProxyWeb::Construct(const FArguments& InArgs){
  59. IWebBrowserSingleton* Singleton = IWebBrowserModule::Get().GetSingleton();
  60. if (Singleton) {
  61. FCreateBrowserWindowSettings Settings;
  62. Settings.BrowserFrameRate = FMath::Clamp(InArgs._BrowserFrameRate, 30, 60);
  63. Settings.bUseTransparency = InArgs._EnableMouseTransparency;
  64. Settings.BackgroundColor = InArgs._BackgroundColor;
  65. Settings.InitialURL = dns_to_local(InArgs._InitialURL);
  66. Settings.ContentsToLoad = FString(TEXT(""));
  67. Settings.bShowErrorMessage = false;
  68. Settings.bThumbMouseButtonNavigation = false;
  69. Singleton->SetDevToolsShortcutEnabled(Settings.bShowErrorMessage);
  70. BrowserWindow = Singleton->CreateBrowserWindow(Settings);
  71. }
  72. #ifdef WEBVIEW_CUSTOMIZED_CORE
  73. FString show_tips = TEXT("If you see this prompt, it is caused by the following reasons: \n\n"
  74. "1. The plug - in is installed in the engine directory, such as : Engine\\Plugins\\Marketplace. \n"
  75. " Solution: Please move the plug - in to the project local plug - in directory \n\n"
  76. "2. Other plug - ins that depend on WebBrowser are enabled, such as : Bridge, WebBrowser, etc. \n"
  77. " Solution : Disable them in the plug - in manager. \n\n"
  78. "Finally, close the project and then open it again.\n");
  79. TAttribute<FText> text_tip = FText::FromString(show_tips);
  80. TSharedRef<STextBlock> TextRef = SNew(STextBlock);
  81. TextRef->SetText(text_tip);
  82. TextRef->SetTextStyle(&InArgs._TextStyle);
  83. #endif
  84. bMouseTransparency = InArgs._EnableMouseTransparency;
  85. TransparencyThreadshold = 255 - InArgs._BackgroundColor.A;
  86. LastMousePixel = FColor::Transparent;
  87. ChildSlot
  88. [
  89. SNew(SOverlay)
  90. .Visibility(this, &SProxyWeb::GetViewportVisibility)
  91. + SOverlay::Slot()
  92. .HAlign(HAlign_Fill).VAlign(VAlign_Fill)
  93. [
  94. SAssignNew(BrowserView, SWebBrowserView, BrowserWindow)
  95. .InitialURL(dns_to_local(InArgs._InitialURL))
  96. .ShowErrorMessage(false)
  97. .SupportsTransparency(true)
  98. .SupportsThumbMouseButtonNavigation(false)
  99. .BackgroundColor(InArgs._BackgroundColor)
  100. .ViewportSize(InArgs._ViewportSize)
  101. .OnUrlChanged(InArgs._OnUrlChanged)
  102. .OnBeforePopup(InArgs._OnBeforePopup)
  103. ]
  104. #ifdef WEBVIEW_CUSTOMIZED_CORE
  105. + SOverlay::Slot()
  106. .HAlign(HAlign_Center).VAlign(VAlign_Center)
  107. [
  108. TextRef
  109. ]
  110. #endif
  111. ];
  112. }
  113. EVisibility SProxyWeb::GetViewportVisibility() const {
  114. if (!BrowserView.IsValid() || !BrowserView->IsInitialized()) {
  115. return EVisibility::Hidden;
  116. }
  117. else if (bMouseTransparency && LastMousePixel.A < TransparencyThreadshold) {
  118. return EVisibility::HitTestInvisible;
  119. }
  120. return EVisibility::Visible;
  121. }
  122. void SProxyWeb::LoadURL(FString NewURL) {
  123. if (BrowserView.IsValid())
  124. BrowserView->LoadURL(dns_to_local(NewURL));
  125. }
  126. void SProxyWeb::LoadString(FString NewURL, FString content) {
  127. if (BrowserView.IsValid())
  128. BrowserView->LoadString(content, dns_to_local(NewURL));
  129. }
  130. void SProxyWeb::ReopenRender(FString NewURL) {
  131. LoadURL(dns_to_local(NewURL));//don`t support open new render. use loadurl impl
  132. }
  133. void SProxyWeb::Reload() {
  134. if (BrowserView.IsValid())
  135. BrowserView->Reload();
  136. }
  137. void SProxyWeb::StopLoad(){
  138. if (BrowserView.IsValid())
  139. BrowserView->StopLoad();
  140. }
  141. FText SProxyWeb::GetTitleText() const {
  142. if (BrowserView.IsValid())
  143. return BrowserView->GetTitleText();
  144. return FText();
  145. }
  146. FString SProxyWeb::GetUrl() const
  147. {
  148. if (BrowserView.IsValid())
  149. return local_to_dns(BrowserView->GetUrl());
  150. return FString();
  151. }
  152. bool SProxyWeb::IsLoading() const
  153. {
  154. if (BrowserView.IsValid())
  155. return BrowserView->IsLoading();
  156. return false;
  157. }
  158. bool SProxyWeb::CanGoBack() const
  159. {
  160. if (BrowserView.IsValid())
  161. return BrowserView->CanGoBack();
  162. return false;
  163. }
  164. void SProxyWeb::GoBack()
  165. {
  166. if (BrowserView.IsValid())
  167. BrowserView->GoBack();
  168. }
  169. bool SProxyWeb::CanGoForward() const {
  170. if (BrowserView.IsValid())
  171. return BrowserView->CanGoForward();
  172. return false;
  173. }
  174. void SProxyWeb::GoForward() {
  175. if (BrowserView.IsValid())
  176. BrowserView->GoForward();
  177. }
  178. void SProxyWeb::ZoomLevel(float zoomlevel) {
  179. // do not implment
  180. }
  181. void SProxyWeb::WebPixel(FIntPoint pixel) {
  182. // do not implment
  183. }
  184. void SProxyWeb::ExecuteJavascript(const FString& ScriptText){
  185. if (BrowserView.IsValid())
  186. BrowserView->ExecuteJavascript(ScriptText);
  187. }
  188. void SProxyWeb::BindUObject(const FString& Name, UObject* Object, bool bIsPermanent){
  189. if (BrowserView.IsValid())
  190. BrowserView->BindUObject(Name, Object, bIsPermanent);
  191. }
  192. void SProxyWeb::UnbindUObject(const FString& Name, UObject* Object, bool bIsPermanent){
  193. if (BrowserView.IsValid())
  194. BrowserView->UnbindUObject(Name, Object, bIsPermanent);
  195. }
  196. void SProxyWeb::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) {
  197. if (!bMouseTransparency || !FSlateApplication::IsInitialized()) {//
  198. this->LastMousePixel = FColor::White;
  199. return;
  200. }
  201. sumDelay += InDeltaTime;
  202. if (sumDelay < 0.2f) return;
  203. sumDelay = 0.0f;
  204. TSharedPtr<ICursor> Mouse = FSlateApplication::Get().GetPlatformCursor();
  205. if (!Mouse.IsValid() /*|| Mouse->GetType() == EMouseCursor::None*/) {
  206. LastMousePixel = FColor::Transparent;
  207. return;
  208. }
  209. FVector2D MousePosition = Mouse->GetPosition();
  210. if (MousePosition.ContainsNaN()) {
  211. LastMousePixel = FColor::Transparent;
  212. return;
  213. }
  214. FVector2D LocalMouse = AllottedGeometry.AbsoluteToLocal(MousePosition);
  215. FVector2D LocalSize = AllottedGeometry.GetLocalSize();
  216. int X = LocalMouse.X * 1000;
  217. int Y = LocalMouse.Y * 1000;
  218. if (preMouseX == X && preMouseY == Y) {
  219. //UE_LOG(CoreWebLog, Log, TEXT("UWebCoreData::Tick no move %f %s"), LastMousePixel.A, *BrowserWindow->GetTitle());
  220. return;//
  221. }
  222. preMouseX = X;
  223. preMouseY = Y;
  224. FVector2D LocalUV;
  225. if (LocalSize.X > 0.0f && LocalSize.Y > 0.0f)
  226. LocalUV = FVector2D(LocalMouse.X / LocalSize.X, LocalMouse.Y / LocalSize.Y);
  227. if (LocalUV.X >= 0.0f && LocalUV.X <= 1.0f && LocalUV.Y >= 0.0f && LocalUV.Y <= 1.0f) {
  228. ReadTexturePixel(LocalUV, LastMousePixel);
  229. return;
  230. }
  231. LastMousePixel = FColor::White;
  232. return;
  233. }
  234. bool SProxyWeb::ReadTexturePixel(FVector2D& LocalUV, FColor& MousePixel) {
  235. MousePixel = FColor::Transparent;
  236. if (!BrowserWindow.IsValid())
  237. return false;
  238. FSlateShaderResource* Resource = BrowserWindow->GetTexture();
  239. if (!Resource || Resource->GetType() != ESlateShaderResource::NativeTexture)
  240. return false;
  241. int width = Resource->GetWidth();
  242. int height = Resource->GetHeight();
  243. int X = FMath::FloorToInt(LocalUV.X * width);
  244. int Y = FMath::FloorToInt(LocalUV.Y * height);
  245. if (X < 0 || width < X || Y < 0 || height < Y) {
  246. MousePixel = FColor::Transparent;
  247. return false;
  248. }
  249. FTexture2DRHIRef TextureRHI;
  250. TextureRHI = ((TSlateTexture<FTexture2DRHIRef>*)Resource)->GetTypedResource();
  251. struct FReadSurfaceContext {
  252. FTexture2DRHIRef Texture;
  253. TArray<FColor>* OutData;
  254. FIntRect Rect;
  255. FReadSurfaceDataFlags Flags;
  256. };
  257. X = FMath::Clamp(X, 0, width - 1);
  258. Y = FMath::Clamp(Y, 0, height - 1);
  259. int Width = 1;
  260. int Height = 1;
  261. Width = FMath::Clamp(Width, 1, width);
  262. Width = Width - FMath::Max(X + Width - width, 0);
  263. Height = FMath::Clamp(Height, 1, height);
  264. Height = Height - FMath::Max(Y + Height - height, 0);
  265. TArray<FColor> OutPixels;
  266. FReadSurfaceContext Context =
  267. {
  268. TextureRHI,
  269. &OutPixels,
  270. FIntRect(X, Y, X + Width, Y + Height),
  271. FReadSurfaceDataFlags()
  272. };
  273. ENQUEUE_RENDER_COMMAND(ReadSurfaceCommand)(
  274. [Context, &MousePixel](FRHICommandListImmediate& RHICmdList)
  275. {
  276. TArray<FColor> OutPixels;
  277. RHICmdList.ReadSurfaceData(
  278. Context.Texture,
  279. Context.Rect,
  280. OutPixels,
  281. Context.Flags
  282. );
  283. if (OutPixels.Num())
  284. AsyncTask(ENamedThreads::Type::GameThread, [&MousePixel, Pixel = OutPixels[0]]() {MousePixel = Pixel; });
  285. });
  286. return true;
  287. }
  288. void SProxyWeb::OnDragEnter(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) {
  289. // do not implment
  290. }
  291. void SProxyWeb::OnDragLeave(const FDragDropEvent& DragDropEvent) {
  292. // do not implment
  293. }
  294. FReply SProxyWeb::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) {
  295. // do not implment
  296. return FReply::Unhandled();
  297. }
  298. FReply SProxyWeb::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) {
  299. // do not implment
  300. return FReply::Unhandled();
  301. }
  302. void SProxyWeb::ShowAddress(bool isShow) {
  303. // do not implment
  304. }
  305. #undef LOCTEXT_NAMESPACE
  306. #endif