SWebInterfaceBrowserView.h 15.9 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
// Engine/Source/Runtime/WebBrowser/Public/SWebBrowserView.h
#pragma once

#include "CoreMinimal.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Input/PopupMethodReply.h"
#include "Widgets/SWidget.h"
#include "Widgets/SCompoundWidget.h"
#include "Framework/Application/IMenu.h"
#include "Framework/SlateDelegates.h"
#include "Widgets/SViewport.h"
#include "IWebInterfaceBrowserSingleton.h"

class FWebInterfaceBrowserViewport;
class IWebInterfaceBrowserAdapter;
class IWebInterfaceBrowserDialog;
class IWebInterfaceBrowserPopupFeatures;
class IWebInterfaceBrowserWindow;
struct FWebNavigationRequest;
enum class EWebInterfaceBrowserDialogEventResponse;
enum class EWebInterfaceBrowserDocumentState;

DECLARE_DELEGATE_RetVal_TwoParams(bool, FOnBeforePopupDelegate, FString, FString);
DECLARE_DELEGATE_RetVal_TwoParams(bool, FOnCreateWindowDelegate, const TWeakPtr<IWebInterfaceBrowserWindow>&, const TWeakPtr<IWebInterfaceBrowserPopupFeatures>&);
DECLARE_DELEGATE_RetVal_OneParam(bool, FOnCloseWindowDelegate, const TWeakPtr<IWebInterfaceBrowserWindow>&);
DECLARE_DELEGATE_RetVal_OneParam(TSharedPtr<IToolTip>, FOnCreateToolTip, const FText&);

#if WITH_CEF3
typedef SViewport SWebInterfaceBrowserWidget;
#else
typedef SWidget SWebInterfaceBrowserWidget;
#endif

class WEBBROWSERUI_API SWebInterfaceBrowserView
	: public SCompoundWidget
{
public:
	DECLARE_DELEGATE_RetVal_TwoParams(bool, FOnBeforeBrowse, const FString& /*Url*/, const FWebNavigationRequest& /*Request*/)
	DECLARE_DELEGATE_RetVal_ThreeParams(bool, FOnLoadUrl, const FString& /*Method*/, const FString& /*Url*/, FString& /* Response */)
	DECLARE_DELEGATE_RetVal_OneParam(EWebInterfaceBrowserDialogEventResponse, FOnShowDialog, const TWeakPtr<IWebInterfaceBrowserDialog>&);
	DECLARE_DELEGATE_RetVal(bool, FOnSuppressContextMenu);
	DECLARE_DELEGATE_RetVal_OneParam(bool, FOnDragWindow, const FPointerEvent& /* MouseEvent */);
	DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyDown, const FKeyEvent& /*KeyEvent*/);
	DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyUp, const FKeyEvent& /*KeyEvent*/);
	DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyChar, const FCharacterEvent& /*CharacterEvent*/);

	SLATE_BEGIN_ARGS(SWebInterfaceBrowserView)
		: _InitialURL(TEXT("https://www.google.com"))
		, _ShowErrorMessage(true)
		, _SupportsTransparency(false)
		, _SupportsThumbMouseButtonNavigation(true)
		, _BackgroundColor(255,255,255,255)
		, _BrowserFrameRate(24)
		, _PopupMenuMethod(TOptional<EPopupMethod>())
		, _ContextSettings()
		, _AltRetryDomains(TArray<FString>())
		, _ViewportSize(FVector2D::ZeroVector)
	{ }

		/** A reference to the parent window. */
		SLATE_ARGUMENT(TSharedPtr<SWindow>, ParentWindow)

		/** URL that the browser will initially navigate to. */
		SLATE_ARGUMENT(FString, InitialURL)

		/** Optional string to load contents as a web page. */
		SLATE_ARGUMENT(TOptional<FString>, ContentsToLoad)

		/** Whether to show an error message in case of loading errors. */
		SLATE_ARGUMENT(bool, ShowErrorMessage)

		/** Should this browser window support transparency. */
		SLATE_ARGUMENT(bool, SupportsTransparency)

		/** Whether to allow forward and back navigation via the mouse thumb buttons. */
		SLATE_ARGUMENT(bool, SupportsThumbMouseButtonNavigation)

		/** Opaque background color used before a document is loaded and when no document color is specified. */
		SLATE_ARGUMENT(FColor, BackgroundColor)

		/** The frames per second rate that the browser will attempt to use. */
		SLATE_ARGUMENT(int, BrowserFrameRate)

		/** Override the popup menu method used for popup menus. If not set, parent widgets will be queried instead. */
		SLATE_ARGUMENT(TOptional<EPopupMethod>, PopupMenuMethod)

		/** Override the default global context settings for this specific window. If not set, the global default will be used. */
		SLATE_ARGUMENT(TOptional<FInterfaceBrowserContextSettings>, ContextSettings)

		/** Domains to retry if original domain cannot connect. */
		SLATE_ARGUMENT(TArray<FString>, AltRetryDomains)

		/** Desired size of the web browser viewport. */
		SLATE_ATTRIBUTE(FVector2D, ViewportSize);

		/** Called when document loading completed. */
		SLATE_EVENT(FSimpleDelegate, OnLoadCompleted)

		/** Called when document loading failed. */
		SLATE_EVENT(FSimpleDelegate, OnLoadError)

		/** Called when document loading started. */
		SLATE_EVENT(FSimpleDelegate, OnLoadStarted)

		/** Called when document title changed. */
		SLATE_EVENT(FOnTextChanged, OnTitleChanged)

		/** Called when the Url changes. */
		SLATE_EVENT(FOnTextChanged, OnUrlChanged)

		/** Called before a popup window happens */
		SLATE_EVENT(FOnBeforePopupDelegate, OnBeforePopup)

		/** Called when the browser requests the creation of a new window */
		SLATE_EVENT(FOnCreateWindowDelegate, OnCreateWindow)

		/** Called when a browser window close event is detected */
		SLATE_EVENT(FOnCloseWindowDelegate, OnCloseWindow)

		/** Called before browser navigation. */
		SLATE_EVENT(FOnBeforeBrowse, OnBeforeNavigation)

		/** Called to allow bypassing page content on load. */
		SLATE_EVENT(FOnLoadUrl, OnLoadUrl)

		/** Called when the browser needs to show a dialog to the user. */
		SLATE_EVENT(FOnShowDialog, OnShowDialog)

		/** Called to dismiss any dialogs shown via OnShowDialog. */
		SLATE_EVENT(FSimpleDelegate, OnDismissAllDialogs)

		/** Called to allow supression of the browser context menu. */
		SLATE_EVENT(FOnSuppressContextMenu, OnSuppressContextMenu);

		/** Called to allow overriding of ToolTip widget construction. */
		SLATE_EVENT(FOnCreateToolTip, OnCreateToolTip)

		/** Called when drag is detected in a web page area tagged as a drag region. */
		SLATE_EVENT(FOnDragWindow, OnDragWindow)
		
		/** Called to allow the handling of any key down events not handled by the browser. */
		SLATE_EVENT(FOnUnhandledKeyDown, OnUnhandledKeyDown)

		/** Called to allow the handling of any key up events not handled by the browser. */
		SLATE_EVENT(FOnUnhandledKeyUp, OnUnhandledKeyUp)

		/** Called to allow the handling of any key char events not handled by the browser. */
		SLATE_EVENT(FOnUnhandledKeyChar, OnUnhandledKeyChar)

	SLATE_END_ARGS()


	/** Default constructor. */
	SWebInterfaceBrowserView();

	~SWebInterfaceBrowserView();

	virtual bool SupportsKeyboardFocus() const override {return true;}

	/**
	 * Construct the widget.
	 *
	 * @param InArgs  Declaration from which to construct the widget.
	 */
	void Construct(const FArguments& InArgs, const TSharedPtr<IWebInterfaceBrowserWindow>& InWebBrowserWindow = nullptr);

	virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;

	/**
	 * Load the specified URL.
	 *
	 * @param NewURL New URL to load.
	 */
	void LoadURL(FString NewURL);

	/**
	* Load a string as data to create a web page.
	*
	* @param Contents String to load.
	* @param DummyURL Dummy URL for the page.
	*/
	void LoadString(FString Contents, FString DummyURL);

	/** Reload the current page. */
	void Reload();

	/** Stop loading the page. */
	void StopLoad();

	/** Get the current title of the web page. */
	FText GetTitleText() const;

	/**
	 * Gets the currently loaded URL.
	 *
	 * @return The URL, or empty string if no document is loaded.
	 */
	FString GetUrl() const;

	/**
	 * Gets the URL that appears in the address bar, this may not be the URL that is currently loaded in the frame.
	 *
	 * @return The address bar URL.
	 */
	FText GetAddressBarUrlText() const;

	/** Whether the document finished loading. */
	bool IsLoaded() const;

	/** Whether the document is currently being loaded. */
	bool IsLoading() const;

	/** Whether the browser widget is done initializing. */
	bool IsInitialized() const;

	/** Execute javascript on the current window */
	void ExecuteJavascript(const FString& ScriptText);

	/**
	 * Gets the source of the main frame as raw HTML.
	 *
	 * This method has to be called asynchronously by passing a callback function, which will be called at a later point when the
	 * result is ready.
	 * @param	Callback	A callable that takes a single string reference for handling the result.
	 */
	void GetSource(TFunction<void (const FString&)> Callback) const ;

	/**
	 * Expose a UObject instance to the browser runtime.
	 * Properties and Functions will be accessible from JavaScript side.
	 * As all communication with the rendering procesis asynchronous, return values (both for properties and function results) are wrapped into JS Future objects.
	 *
	 * @param Name The name of the object. The object will show up as window.ue4.{Name} on the javascript side. If there is an existing object of the same name, this object will replace it. If bIsPermanent is false and there is an existing permanent binding, the permanent binding will be restored when the temporary one is removed.
	 * @param Object The object instance.
	 * @param bIsPermanent If true, the object will be visible to all pages loaded through this browser widget, otherwise, it will be deleted when navigating away from the current page. Non-permanent bindings should be registered from inside an OnLoadStarted event handler in order to be available before JS code starts loading.
	 */
	void BindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true);

	/**
	 * Remove an existing script binding registered by BindUObject.
	 *
	 * @param Name The name of the object to remove.
	 * @param Object The object will only be removed if it is the same object as the one passed in.
	 * @param bIsPermanent Must match the bIsPermanent argument passed to BindUObject.
	 */
	void UnbindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true);

	void BindAdapter(const TSharedRef<IWebInterfaceBrowserAdapter>& Adapter);

	void UnbindAdapter(const TSharedRef<IWebInterfaceBrowserAdapter>& Adapter);

	void BindInputMethodSystem(ITextInputMethodSystem* TextInputMethodSystem);

	void UnbindInputMethodSystem();

	/** Returns true if the browser can navigate backwards. */
	bool CanGoBack() const;

	/** Navigate backwards. */
	void GoBack();

	/** Returns true if the browser can navigate forwards. */
	bool CanGoForward() const;

	/** Navigate forwards. */
	void GoForward();

private:

	void SetupParentWindowHandlers();

	/** Callback for document loading state changes. */
	void HandleBrowserWindowDocumentStateChanged(EWebInterfaceBrowserDocumentState NewState);

	/** Callback to tell slate we want to update the contents of the web view based on changes inside the view. */
	void HandleBrowserWindowNeedsRedraw();

	/** Callback for document title changes. */
	void HandleTitleChanged(FString NewTitle);

	/** Callback for loaded url changes. */
	void HandleUrlChanged(FString NewUrl);

	/** Callback for showing browser tool tips. */
	void HandleToolTip(FString ToolTipText);

	/**
	 * A delegate that is executed prior to browser navigation.
	 *
	 * @return true if the navigation was handled an no further action should be taken by the browser, false if the browser should handle.
	 */
	bool HandleBeforeNavigation(const FString& Url, const FWebNavigationRequest& Request);

	bool HandleLoadUrl(const FString& Method, const FString& Url, FString& OutResponse);

	/**
	 * A delegate that is executed when the browser requests window creation.
	 *
	 * @return true if if the window request was handled, false if the browser requesting the new window should be closed.
	 */
	bool HandleCreateWindow(const TWeakPtr<IWebInterfaceBrowserWindow>& NewBrowserWindow, const TWeakPtr<IWebInterfaceBrowserPopupFeatures>& PopupFeatures);

	/**
	 * A delegate that is executed when closing the browser window.
	 *
	 * @return true if if the window close was handled, false otherwise.
	 */
	bool HandleCloseWindow(const TWeakPtr<IWebInterfaceBrowserWindow>& BrowserWindow);

	/** Callback for showing dialogs to the user */
	EWebInterfaceBrowserDialogEventResponse HandleShowDialog(const TWeakPtr<IWebInterfaceBrowserDialog>& DialogParams);

	/** Callback for dismissing any dialogs previously shown  */
	void HandleDismissAllDialogs();

	/** Callback for popup window permission */
	bool HandleBeforePopup(FString URL, FString Target);

	/** Callback for showing a popup menu */
	void HandleShowPopup(const FIntRect& PopupSize);

	/** Callback for hiding the popup menu */
	void HandleDismissPopup();

	/** Callback from the popup menu notifiying it has been dismissed */
	void HandleMenuDismissed(TSharedRef<IMenu>);

	virtual FPopupMethodReply OnQueryPopupMethod() const override
	{
		return PopupMenuMethod.IsSet()
			? FPopupMethodReply::UseMethod(PopupMenuMethod.GetValue())
			: FPopupMethodReply::Unhandled();
	}

	void HandleWindowDeactivated();
	void HandleWindowActivated();
	bool UnhandledKeyDown(const FKeyEvent& KeyEvent);
	bool UnhandledKeyUp(const FKeyEvent& KeyEvent);
	bool UnhandledKeyChar(const FCharacterEvent& CharacterEvent);

	bool HandleDrag(const FPointerEvent& MouseEvent);

private:

	/** Interface for dealing with a web browser window. */
	TSharedPtr<IWebInterfaceBrowserWindow> BrowserWindow;
	/** The slate window that contains this widget. This must be stored weak otherwise we create a circular reference. */
	mutable TWeakPtr<SWindow> SlateParentWindowPtr;
	/** Viewport interface for rendering the web page. */
	TSharedPtr<FWebInterfaceBrowserViewport> BrowserViewport;
	/** Viewport interface for rendering popup menus. */
	TSharedPtr<FWebInterfaceBrowserViewport>	MenuViewport;
	/** The implementation dependent widget that renders the browser contents. */
	TSharedPtr<SWebInterfaceBrowserWidget> BrowserWidget;

	TArray<TSharedRef<IWebInterfaceBrowserAdapter>> Adapters;

	/**
	 * An interface pointer to a menu object presenting a popup.
	 * Pointer is null when a popup is not visible.
	 */
	TWeakPtr<IMenu> PopupMenuPtr;

	/** Can be set to override the popup menu method used for popup menus. If not set, parent widgets will be queried instead. */
	TOptional<EPopupMethod> PopupMenuMethod;

	/** The url that appears in the address bar which can differ from the url of the loaded page */
	FText AddressBarUrl;

	/** A delegate that is invoked when document loading completed. */
	FSimpleDelegate OnLoadCompleted;

	/** A delegate that is invoked when document loading failed. */
	FSimpleDelegate OnLoadError;

	/** A delegate that is invoked when document loading started. */
	FSimpleDelegate OnLoadStarted;

	/** A delegate that is invoked when document title changed. */
	FOnTextChanged OnTitleChanged;

	/** A delegate that is invoked when document address changed. */
	FOnTextChanged OnUrlChanged;

	/** A delegate that is invoked when the browser attempts to pop up a new window */
	FOnBeforePopupDelegate OnBeforePopup;

	/** A delegate that is invoked when the browser requests a UI window for another browser it spawned */
	FOnCreateWindowDelegate OnCreateWindow;

	/** A delegate that is invoked when a window close event is detected */
	FOnCloseWindowDelegate OnCloseWindow;

	/** A delegate that is invoked prior to browser navigation */
	FOnBeforeBrowse OnBeforeNavigation;

	/** A delegate that is invoked when loading a resource, allowing the application to provide contents directly */
	FOnLoadUrl OnLoadUrl;

	/** A delegate that is invoked when when the browser needs to present a dialog to the user */
	FOnShowDialog OnShowDialog;

	/** A delegate that is invoked when when the browser needs to dismiss all dialogs */
	FSimpleDelegate OnDismissAllDialogs;

	FOnSuppressContextMenu OnSuppressContextMenu;

	/** A delegate that is invoked when when the browser wishes to create a tooltip */
	FOnCreateToolTip OnCreateToolTip;

	/** A delegate that is invoked when the browser detects drag event in within drag region */
	FOnDragWindow OnDragWindow;
	
		/** A delegate for handling key down events not handled by browser. */
	FOnUnhandledKeyDown OnUnhandledKeyDown;

	/** A delegate for handling key up events not handled by browser. */
	FOnUnhandledKeyUp OnUnhandledKeyUp;

	/** A delegate for handling key char events not handled by browser. */
	FOnUnhandledKeyChar OnUnhandledKeyChar;

protected:
	bool HandleSuppressContextMenu();

};