| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046 |
- using System;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using System.Windows.Input;
- using System.Windows.Interop;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Threading;
- using Xilium.CefGlue.Helpers.Log;
- using Xilium.CefGlue.WPF.Helpers.Log;
- namespace Xilium.CefGlue.WPF
- {
- public class WpfCefBrowser : ContentControl, IDisposable
- {
- private static readonly Key[] HandledKeys =
- {
- Key.Tab, Key.Home, Key.End, Key.Left, Key.Right, Key.Up, Key.Down
- };
- private bool _disposed;
- private bool _created;
- private Image _browserPageImage;
- private WriteableBitmap _browserPageBitmap;
- private int _browserWidth;
- private int _browserHeight;
- private bool _browserSizeChanged;
- private CefBrowser _browser;
- private CefBrowserHost _browserHost;
- private WpfCefClient _cefClient;
- private Popup _popup;
- private Image _popupImage;
- private WriteableBitmap _popupImageBitmap;
- private ToolTip _tooltip;
- private DispatcherTimer _tooltipTimer;
- Dispatcher _mainUiDispatcher;
- private readonly ILogger _logger;
- public WpfCefBrowser()
- : this(new EmptyLogger("WpfCefBrowser"))
- {
- }
- public WpfCefBrowser(ILogger logger)
- {
- if (logger == null)
- {
- throw new ArgumentNullException("logger");
- }
- _logger = logger;
- StartUrl = "about:blank";
- _popup = CreatePopup();
- _tooltip = new ToolTip();
- _tooltip.StaysOpen = true;
- _tooltip.Visibility = Visibility.Collapsed;
- _tooltip.Closed += TooltipOnClosed;
- _tooltipTimer = new DispatcherTimer();
- _tooltipTimer.Interval = TimeSpan.FromSeconds(0.5);
- KeyboardNavigation.SetAcceptsReturn(this, true);
- _mainUiDispatcher = Dispatcher.CurrentDispatcher;
- }
- #region Disposable
- ~WpfCefBrowser()
- {
- Dispose(false);
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (_tooltipTimer != null)
- {
- _tooltipTimer.Stop();
- }
- if (_browserPageImage != null)
- {
- _browserPageImage.Source = null;
- _browserPageImage = null;
- }
- if (_browserPageBitmap != null)
- {
- _browserPageBitmap = null;
- }
- // if (this.browserPageD3dImage != null)
- // this.browserPageD3dImage = null;
- // TODO: What's the right way of disposing the browser instance?
- if (_browserHost != null)
- {
- _browserHost.CloseBrowser();
- _browserHost = null;
- }
- if (_browser != null)
- {
- _browser.Dispose();
- _browser = null;
- }
- }
- _disposed = true;
- }
- #endregion
- public event LoadStartEventHandler LoadStart;
- public event LoadEndEventHandler LoadEnd;
- public event LoadingStateChangeEventHandler LoadingStateChange;
- public event LoadErrorEventHandler LoadError;
- internal void OnLoadStart(CefFrame frame)
- {
- if (this.LoadStart != null)
- {
- var e = new LoadStartEventArgs(frame);
- this.LoadStart(this, e);
- }
- }
- internal void OnLoadEnd(CefFrame frame, int httpStatusCode)
- {
- if (this.LoadEnd != null)
- {
- var e = new LoadEndEventArgs(frame, httpStatusCode);
- this.LoadEnd(this, e);
- }
- }
- internal void OnLoadingStateChange(bool isLoading, bool canGoBack, bool canGoForward)
- {
- if (this.LoadingStateChange != null)
- {
- var e = new LoadingStateChangeEventArgs(isLoading, canGoBack, canGoForward);
- this.LoadingStateChange(this, e);
- }
- }
- internal void OnLoadError(CefFrame frame, CefErrorCode errorCode, string errorText, string failedUrl)
- {
- if (this.LoadError != null)
- {
- var e = new LoadErrorEventArgs(frame, errorCode, errorText, failedUrl);
- this.LoadError(this, e);
- }
- }
- public string StartUrl { get; set; }
- public bool AllowsTransparency { get; set; }
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- //this.browserPageD3dImage = new D3DImage();
- _browserPageImage = new Image()
- {
- Focusable = false,
- HorizontalAlignment = HorizontalAlignment.Left,
- VerticalAlignment = VerticalAlignment.Top,
- Stretch = Stretch.None
- };
- this.Content = _browserPageImage;
- }
- public void ExecuteJavaScript(string code, string url, int line)
- {
- if (_browser != null)
- this._browser.GetMainFrame().ExecuteJavaScript(code, url, line);
- }
- protected override Size ArrangeOverride(Size arrangeBounds)
- {
- var size = base.ArrangeOverride(arrangeBounds);
- if (_browserPageImage != null)
- {
- var newWidth = (int)size.Width;
- var newHeight = (int)size.Height;
- _logger.Debug("BrowserResize. Old H{0}xW{1}; New H{2}xW{3}.", _browserHeight, _browserWidth, newHeight, newWidth);
- if (newWidth > 0 && newHeight > 0)
- {
- if (!_created)
- {
- AttachEventHandlers(this); // TODO: ?
- // Create the bitmap that holds the rendered website bitmap
- _browserWidth = newWidth;
- _browserHeight = newHeight;
- _browserSizeChanged = true;
- // Find the window that's hosting us
- Window parentWnd = FindParentOfType<Window>(this);
- if (parentWnd != null)
- {
- IntPtr hParentWnd = new WindowInteropHelper(parentWnd).Handle;
- var windowInfo = CefWindowInfo.Create();
- windowInfo.SetAsWindowless(hParentWnd, AllowsTransparency);
- var settings = new CefBrowserSettings();
- _cefClient = new WpfCefClient(this);
- // This is the first time the window is being rendered, so create it.
- CefBrowserHost.CreateBrowser(windowInfo, _cefClient, settings, !string.IsNullOrEmpty(StartUrl) ? StartUrl : "about:blank");
- _created = true;
- }
- }
- else
- {
- // Only update the bitmap if the size has changed
- if (_browserPageBitmap == null || (_browserPageBitmap.Width != newWidth || _browserPageBitmap.Height != newHeight))
- {
- _browserWidth = newWidth;
- _browserHeight = newHeight;
- _browserSizeChanged = true;
- // If the window has already been created, just resize it
- if (_browserHost != null)
- {
- _logger.Trace("CefBrowserHost::WasResized to {0}x{1}.", newWidth, newHeight);
- _browserHost.WasResized();
- }
- }
- }
- }
- }
- return size;
- }
- private void AttachEventHandlers(WpfCefBrowser browser)
- {
- browser.GotKeyboardFocus += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- _browserHost.SendFocusEvent(true);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in GotFocus()", ex);
- }
- };
- browser.LostKeyboardFocus += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- _browserHost.SendFocusEvent(false);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in LostFocus()", ex);
- }
- };
- browser.MouseLeave += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = 0,
- Y = 0
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- _browserHost.SendMouseMoveEvent(mouseEvent, true);
- //_logger.Debug("Browser_MouseLeave");
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in MouseLeave()", ex);
- }
- };
- browser.MouseMove += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Point cursorPos = arg.GetPosition(this);
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- _browserHost.SendMouseMoveEvent(mouseEvent, false);
- //_logger.Debug(string.Format("Browser_MouseMove: ({0},{1})", cursorPos.X, cursorPos.Y));
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in MouseMove()", ex);
- }
- };
- browser.MouseDown += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Focus();
- Point cursorPos = arg.GetPosition(this);
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y,
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- if (arg.ChangedButton == MouseButton.Left)
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Left, false, arg.ClickCount);
- else if (arg.ChangedButton == MouseButton.Middle)
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Middle, false, arg.ClickCount);
- else if (arg.ChangedButton == MouseButton.Right)
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Right, false, arg.ClickCount);
- //_logger.Debug(string.Format("Browser_MouseDown: ({0},{1})", cursorPos.X, cursorPos.Y));
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in MouseDown()", ex);
- }
- };
- browser.MouseUp += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Point cursorPos = arg.GetPosition(this);
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y,
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- if (arg.ChangedButton == MouseButton.Left)
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Left, true, arg.ClickCount);
- else if (arg.ChangedButton == MouseButton.Middle)
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Middle, true, arg.ClickCount);
- else if (arg.ChangedButton == MouseButton.Right)
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Right, true, arg.ClickCount);
- //_logger.Debug(string.Format("Browser_MouseUp: ({0},{1})", cursorPos.X, cursorPos.Y));
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in MouseUp()", ex);
- }
- };
- browser.MouseWheel += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Point cursorPos = arg.GetPosition(this);
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y,
- };
- _browserHost.SendMouseWheelEvent(mouseEvent, 0, arg.Delta);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in MouseWheel()", ex);
- }
- };
- // TODO: require more intelligent processing
- browser.PreviewTextInput += (sender, arg) =>
- {
- if (_browserHost != null)
- {
- _logger.Debug("TextInput: text {0}", arg.Text);
- foreach (var c in arg.Text)
- {
- CefKeyEvent keyEvent = new CefKeyEvent()
- {
- EventType = CefKeyEventType.Char,
- WindowsKeyCode = (int)c,
- // Character = c,
- };
- keyEvent.Modifiers = GetKeyboardModifiers();
- _browserHost.SendKeyEvent(keyEvent);
- }
- }
- arg.Handled = true;
- };
- // TODO: require more intelligent processing
- browser.PreviewKeyDown += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- //_logger.Debug(string.Format("KeyDown: system key {0}, key {1}", arg.SystemKey, arg.Key));
- CefKeyEvent keyEvent = new CefKeyEvent()
- {
- EventType = CefKeyEventType.RawKeyDown,
- WindowsKeyCode = KeyInterop.VirtualKeyFromKey(arg.Key == Key.System ? arg.SystemKey : arg.Key),
- NativeKeyCode = 0,
- IsSystemKey = arg.Key == Key.System,
- };
- keyEvent.Modifiers = GetKeyboardModifiers();
- _browserHost.SendKeyEvent(keyEvent);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in PreviewKeyDown()", ex);
- }
- arg.Handled = HandledKeys.Contains(arg.Key);
- };
- // TODO: require more intelligent processing
- browser.PreviewKeyUp += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- //_logger.Debug(string.Format("KeyUp: system key {0}, key {1}", arg.SystemKey, arg.Key));
- CefKeyEvent keyEvent = new CefKeyEvent()
- {
- EventType = CefKeyEventType.KeyUp,
- WindowsKeyCode = KeyInterop.VirtualKeyFromKey(arg.Key == Key.System ? arg.SystemKey : arg.Key),
- NativeKeyCode = 0,
- IsSystemKey = arg.Key == Key.System,
- };
- keyEvent.Modifiers = GetKeyboardModifiers();
- _browserHost.SendKeyEvent(keyEvent);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in PreviewKeyUp()", ex);
- }
- arg.Handled = true;
- };
- browser._popup.MouseMove += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Point cursorPos = arg.GetPosition(this);
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- _browserHost.SendMouseMoveEvent(mouseEvent, false);
- //_logger.Debug(string.Format("Popup_MouseMove: ({0},{1})", cursorPos.X, cursorPos.Y));
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in Popup.MouseMove()", ex);
- }
- };
- browser._popup.MouseDown += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Point cursorPos = arg.GetPosition(this);
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- _browserHost.SendMouseClickEvent(mouseEvent, CefMouseButtonType.Left, true, 1);
- //_logger.Debug(string.Format("Popup_MouseDown: ({0},{1})", cursorPos.X, cursorPos.Y));
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in Popup.MouseDown()", ex);
- }
- };
- browser._popup.MouseWheel += (sender, arg) =>
- {
- try
- {
- if (_browserHost != null)
- {
- Point cursorPos = arg.GetPosition(this);
- int delta = arg.Delta;
- CefMouseEvent mouseEvent = new CefMouseEvent()
- {
- X = (int)cursorPos.X,
- Y = (int)cursorPos.Y
- };
- mouseEvent.Modifiers = GetMouseModifiers();
- _browserHost.SendMouseWheelEvent(mouseEvent, 0, delta);
- //_logger.Debug(string.Format("MouseWheel: ({0},{1})", cursorPos.X, cursorPos.Y));
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in Popup.MouseWheel()", ex);
- }
- };
- }
- #region Handlers
- public void HandleAfterCreated(CefBrowser browser)
- {
- int width = 0, height = 0;
- bool hasAlreadyBeenInitialized = false;
- _mainUiDispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
- {
- if (_browser != null)
- {
- hasAlreadyBeenInitialized = true;
- }
- else
- {
- _browser = browser;
- _browserHost = _browser.GetHost();
- // _browserHost.SetFocus(IsFocused);
- width = (int)_browserWidth;
- height = (int)_browserHeight;
- }
- }));
- // Make sure we don't initialize ourselves more than once. That seems to break things.
- if (hasAlreadyBeenInitialized)
- return;
- if (width > 0 && height > 0)
- _browserHost.WasResized();
- // mainUiDispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
- // {
- // if (!string.IsNullOrEmpty(this.initialUrl))
- // {
- // NavigateTo(this.initialUrl);
- // this.initialUrl = string.Empty;
- // }
- // }));
- }
- internal bool GetViewRect(ref CefRectangle rect)
- {
- bool rectProvided = false;
- CefRectangle browserRect = new CefRectangle();
- // TODO: simplify this
- //_mainUiDispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
- //{
- try
- {
- // The simulated screen and view rectangle are the same. This is necessary
- // for popup menus to be located and sized inside the view.
- browserRect.X = browserRect.Y = 0;
- browserRect.Width = (int)_browserWidth;
- browserRect.Height = (int)_browserHeight;
- rectProvided = true;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in GetViewRect()", ex);
- rectProvided = false;
- }
- //}));
- if (rectProvided)
- {
- rect = browserRect;
- }
- _logger.Debug("GetViewRect result provided:{0} Rect: X{1} Y{2} H{3} W{4}", rectProvided, browserRect.X, browserRect.Y, browserRect.Height, browserRect.Width);
- return rectProvided;
- }
- internal void GetScreenPoint(int viewX, int viewY, ref int screenX, ref int screenY)
- {
- Point ptScreen = new Point();
- _mainUiDispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
- {
- try
- {
- Point ptView = new Point(viewX, viewY);
- ptScreen = PointToScreen(ptView);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in GetScreenPoint()", ex);
- }
- }));
- screenX = (int)ptScreen.X;
- screenY = (int)ptScreen.Y;
- }
- internal void HandleViewPaint(CefBrowser browser, CefPaintElementType type, CefRectangle[] dirtyRects, IntPtr buffer, int width, int height)
- {
- // When browser size changed - we just skip frame updating.
- // This is dirty precheck to do not do Invoke whenever is possible.
- if (_browserSizeChanged && (width != _browserWidth || height != _browserHeight)) return;
- _mainUiDispatcher.Invoke(DispatcherPriority.Render, new Action(delegate
- {
- // Actual browser size changed check.
- if (_browserSizeChanged && (width != _browserWidth || height != _browserHeight)) return;
- try
- {
- if (_browserSizeChanged)
- {
- _browserPageBitmap = new WriteableBitmap((int)_browserWidth, (int)_browserHeight, 96, 96, AllowsTransparency ? PixelFormats.Bgra32 : PixelFormats.Bgr32, null);
- _browserPageImage.Source = _browserPageBitmap;
- _browserSizeChanged = false;
- }
- if (_browserPageBitmap != null)
- {
- DoRenderBrowser(_browserPageBitmap, width, height, dirtyRects, buffer);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("WpfCefBrowser: Caught exception in HandleViewPaint()", ex);
- }
- }));
- }
- internal void HandlePopupPaint(int width, int height, CefRectangle[] dirtyRects, IntPtr sourceBuffer)
- {
- if (width == 0 || height == 0)
- {
- return;
- }
- _mainUiDispatcher.Invoke(
- DispatcherPriority.Render,
- new Action(
- () =>
- {
- int stride = width * 4;
- int sourceBufferSize = stride * height;
- _logger.Debug("RenderPopup() Bitmap H{0}xW{1}, Browser H{2}xW{3}", _popupImageBitmap.Height, _popupImageBitmap.Width, width, height);
- foreach (CefRectangle dirtyRect in dirtyRects)
- {
- _logger.Debug(
- string.Format(
- "Dirty rect [{0},{1},{2},{3}]",
- dirtyRect.X,
- dirtyRect.Y,
- dirtyRect.Width,
- dirtyRect.Height));
- if (dirtyRect.Width == 0 || dirtyRect.Height == 0)
- {
- continue;
- }
- int adjustedWidth = dirtyRect.Width;
- int adjustedHeight = dirtyRect.Height;
- Int32Rect sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, adjustedWidth, adjustedHeight);
- _popupImageBitmap.WritePixels(sourceRect, sourceBuffer, sourceBufferSize, stride, dirtyRect.X, dirtyRect.Y);
- }
- }));
- }
- private void DoRenderBrowser(WriteableBitmap bitmap, int browserWidth, int browserHeight, CefRectangle[] dirtyRects, IntPtr sourceBuffer)
- {
- int stride = browserWidth * 4;
- int sourceBufferSize = stride * browserHeight;
- _logger.Debug("DoRenderBrowser() Bitmap H{0}xW{1}, Browser H{2}xW{3}", bitmap.Height, bitmap.Width, browserHeight, browserWidth);
- if (browserWidth == 0 || browserHeight == 0)
- {
- return;
- }
- foreach (CefRectangle dirtyRect in dirtyRects)
- {
- _logger.Debug(string.Format("Dirty rect [{0},{1},{2},{3}]", dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height));
- if (dirtyRect.Width == 0 || dirtyRect.Height == 0)
- {
- continue;
- }
- // If the window has been resized, make sure we never try to render too much
- int adjustedWidth = (int)dirtyRect.Width;
- //if (dirtyRect.X + dirtyRect.Width > (int) bitmap.Width)
- //{
- // adjustedWidth = (int) bitmap.Width - (int) dirtyRect.X;
- //}
- int adjustedHeight = (int)dirtyRect.Height;
- //if (dirtyRect.Y + dirtyRect.Height > (int) bitmap.Height)
- //{
- // adjustedHeight = (int) bitmap.Height - (int) dirtyRect.Y;
- //}
- // Update the dirty region
- Int32Rect sourceRect = new Int32Rect((int)dirtyRect.X, (int)dirtyRect.Y, adjustedWidth, adjustedHeight);
- bitmap.WritePixels(sourceRect, sourceBuffer, sourceBufferSize, stride, (int)dirtyRect.X, (int)dirtyRect.Y);
- // int adjustedWidth = browserWidth;
- // if (browserWidth > (int)bitmap.Width)
- // adjustedWidth = (int)bitmap.Width;
- //
- // int adjustedHeight = browserHeight;
- // if (browserHeight > (int)bitmap.Height)
- // adjustedHeight = (int)bitmap.Height;
- //
- // int sourceBufferSize = browserWidth * browserHeight * 4;
- // int stride = browserWidth * 4;
- //
- // Int32Rect sourceRect = new Int32Rect(0, 0, adjustedWidth, adjustedHeight);
- // bitmap.WritePixels(sourceRect, sourceBuffer, sourceBufferSize, stride, 0, 0);
- }
- }
- internal void OnPopupShow(bool show)
- {
- if (_popup == null)
- {
- return;
- }
- _mainUiDispatcher.Invoke(new Action(() => _popup.IsOpen = show));
- }
- internal void OnPopupSize(CefRectangle rect)
- {
- _mainUiDispatcher.Invoke(
- new Action(
- () =>
- {
- _popupImageBitmap = null;
- _popupImageBitmap = new WriteableBitmap(
- rect.Width,
- rect.Height,
- 96,
- 96,
- PixelFormats.Bgr32,
- null);
- _popupImage.Source = this._popupImageBitmap;
- _popup.Width = rect.Width;
- _popup.Height = rect.Height;
- _popup.HorizontalOffset = rect.X;
- _popup.VerticalOffset = rect.Y;
- }));
- }
- internal bool OnTooltip(string text)
- {
- if (string.IsNullOrEmpty(text))
- {
- _tooltipTimer.Stop();
- UpdateTooltip(null);
- }
- else
- {
- _tooltipTimer.Tick += (sender, args) => UpdateTooltip(text);
- _tooltipTimer.Start();
- }
- return true;
- }
- #endregion
- #region Utils
- /// <summary>
- /// Finds a parent of the specific type
- /// </summary>
- private static T FindParentOfType<T>(DependencyObject obj) where T : DependencyObject
- {
- DependencyObject parentObj = VisualTreeHelper.GetParent(obj);
- if (parentObj == null)
- return null;
- // Try to type cast the parent to the desired type.
- // If the cast succeeds, we've found the desired parent.
- T parent = parentObj as T;
- if (parent != null)
- return parent;
- // If we get here, the current parent wasn't of the right type, so keep looking recursively
- return FindParentOfType<T>(parentObj);
- }
- private static CefEventFlags GetMouseModifiers()
- {
- CefEventFlags modifiers = new CefEventFlags();
- if (Mouse.LeftButton == MouseButtonState.Pressed)
- modifiers |= CefEventFlags.LeftMouseButton;
- if (Mouse.MiddleButton == MouseButtonState.Pressed)
- modifiers |= CefEventFlags.MiddleMouseButton;
- if (Mouse.RightButton == MouseButtonState.Pressed)
- modifiers |= CefEventFlags.RightMouseButton;
- return modifiers;
- }
- private static CefEventFlags GetKeyboardModifiers()
- {
- CefEventFlags modifiers = new CefEventFlags();
- if (Keyboard.Modifiers == ModifierKeys.Alt)
- modifiers |= CefEventFlags.AltDown;
- if (Keyboard.Modifiers == ModifierKeys.Control)
- modifiers |= CefEventFlags.ControlDown;
- if (Keyboard.Modifiers == ModifierKeys.Shift)
- modifiers |= CefEventFlags.ShiftDown;
- return modifiers;
- }
- private Popup CreatePopup()
- {
- var popup = new Popup
- {
- Child = this._popupImage = CreatePopupImage(),
- PlacementTarget = this,
- Placement = PlacementMode.Relative
- };
- return popup;
- }
- private Image CreatePopupImage()
- {
- var temp = new Image();
- RenderOptions.SetBitmapScalingMode(temp, BitmapScalingMode.NearestNeighbor);
- temp.Stretch = Stretch.None;
- temp.HorizontalAlignment = HorizontalAlignment.Left;
- temp.VerticalAlignment = VerticalAlignment.Top;
- temp.Source = _popupImageBitmap;
- return temp;
- }
- private void UpdateTooltip(string text)
- {
- _mainUiDispatcher.Invoke(
- DispatcherPriority.Render,
- new Action(
- () =>
- {
- if (string.IsNullOrEmpty(text))
- {
- _tooltip.IsOpen = false;
- }
- else
- {
- _tooltip.Placement = PlacementMode.Mouse;
- _tooltip.Content = text;
- _tooltip.IsOpen = true;
- _tooltip.Visibility = Visibility.Visible;
- }
- }));
- _tooltipTimer.Stop();
- }
- private void TooltipOnClosed(object sender, RoutedEventArgs routedEventArgs)
- {
- _tooltip.Visibility = Visibility.Collapsed;
- _tooltip.Placement = PlacementMode.Absolute;
- }
- #endregion
- #region Methods
- public void NavigateTo(string url)
- {
- // Remove leading whitespace from the URL
- url = url.TrimStart();
- if (_browser != null)
- _browser.GetMainFrame().LoadUrl(url);
- else
- StartUrl = url;
- }
- public void LoadString(string content, string url)
- {
- // Remove leading whitespace from the URL
- url = url.TrimStart();
- if (_browser != null)
- _browser.GetMainFrame().LoadString(content, url);
- }
- public bool CanGoBack()
- {
- if (_browser != null)
- return _browser.CanGoBack;
- else
- return false;
- }
- public void GoBack()
- {
- if (_browser != null)
- _browser.GoBack();
- }
- public bool CanGoForward()
- {
- if (_browser != null)
- return _browser.CanGoForward;
- else
- return false;
- }
- public void GoForward()
- {
- if (_browser != null)
- _browser.GoForward();
- }
- public void Refresh()
- {
- if (_browser != null)
- _browser.Reload();
- }
- #endregion
- }
- }
|