/// <summary> /// Called when the <see cref="Content"/> was exchanged. /// </summary> /// <param name="newContent">The new content.</param> /// <param name="oldContent">The old content.</param> protected virtual void OnContentChanged(UIControl newContent, UIControl oldContent) { if (oldContent != null) { VisualChildren.Remove(oldContent); } if (newContent != null) { // Apply ContentStyle to Content. if (IsLoaded && !string.IsNullOrEmpty(ContentStyle)) { newContent.Style = ContentStyle; } VisualChildren.Add(newContent); } InvalidateMeasure(); }
/// <summary> /// Opens a window and returns without waiting for the newly opened window to close. /// </summary> /// <param name="owner"> /// The owner of this window. If this window is closed, the focus moves back to the owner. Must /// not be <see langword="null"/>. /// </param> /// <remarks> /// The window is added to the <see cref="UIScreen"/> of the <paramref name="owner"/> /// (unless it was already added to a screen) and activated (see <see cref="Activate"/>). /// <see cref="DialogResult"/> is reset to <see langword="null"/>. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="owner"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="owner"/> is not loaded. The owner needs to be a visible control. /// </exception> public void Show(UIControl owner) { if (owner == null) throw new ArgumentNullException("owner"); var screen = owner.Screen; if (screen == null) throw new ArgumentException("Invalid owner. Owner must be loaded.", "owner"); Owner = owner; // Make visible and add to screen. IsVisible = true; if (VisualParent == null) screen.Children.Add(this); Activate(); DialogResult = null; #else DialogResult = false; }
protected override void OnHandleInput(InputContext context) { var screen = Screen; var inputService = InputService; var uiService = UIService; bool mouseOrTouchWasHandled = inputService.IsMouseOrTouchHandled; UIControl oldFocusedControl = screen.FocusManager.FocusedControl; if (mouseOrTouchWasHandled && _setSpecialCursor) { // This window has changed the cursor in the last frame, but in this frame another // window has the mouse. // Minor problem: If the other window has also changed the cursor, then we remove // its special cursor. But this case should be rare. uiService.Cursor = null; _setSpecialCursor = false; } // Continue resizing and dragging if already in progress. ContinueResizeAndDrag(context); base.OnHandleInput(context); if (!IsLoaded) return; // Handling of activation is very complicated. For example: The window is clicked, but // a context menu is opened by this click. And there are other difficult cases... Horror! if (!mouseOrTouchWasHandled) { // The mouse was not handled by any control that handled input before this window; if (!screen.IsFocusWithin // Nothing in window is focused. || IsFocusWithin // This window is focused. || oldFocusedControl == screen.FocusManager.FocusedControl) // The focus was not changed by a visual child. (Don't { // activate window if focus moved to a new context menu or other popup!!!) // Mouse must be over the window and left or right mouse button must be pressed. if (IsMouseOver) { if ((inputService.IsPressed(MouseButtons.Left, false) || inputService.IsPressed(MouseButtons.Right, false))) { Activate(); } } } } // If the focus moves into this window, it should become activated. if (IsFocusWithin && !IsActive) Activate(); // Check whether to start resizing or dragging. StartResizeAndDrag(context); // Update mouse cursor. if ((uiService.Cursor == null || _setSpecialCursor) // Cursor of UIService was set by this window. && (!inputService.IsMouseOrTouchHandled || _isResizing)) // Mouse was not yet handled or is currently resizing. { switch (_resizeDirection) { case ResizeDirection.N: case ResizeDirection.S: uiService.Cursor = screen.Renderer.GetCursor("SizeNS"); _setSpecialCursor = true; break; case ResizeDirection.E: case ResizeDirection.W: uiService.Cursor = screen.Renderer.GetCursor("SizeWE"); _setSpecialCursor = true; break; case ResizeDirection.NE: case ResizeDirection.SW: uiService.Cursor = screen.Renderer.GetCursor("SizeNESW"); _setSpecialCursor = true; break; case ResizeDirection.NW: case ResizeDirection.SE: uiService.Cursor = screen.Renderer.GetCursor("SizeNWSE"); _setSpecialCursor = true; break; default: uiService.Cursor = null; _setSpecialCursor = false; break; } } // Mouse cannot act through a window. if (IsMouseOver) inputService.IsMouseOrTouchHandled = true; if (IsModal) { // Modal windows absorb all input. inputService.IsMouseOrTouchHandled = true; inputService.SetGamePadHandled(context.AllowedPlayer, true); inputService.IsKeyboardHandled = true; } }
/// <summary> /// Opens this <see cref="ContextMenu"/> (adds it to the <see cref="UIScreen"/>). /// </summary> /// <param name="owner">The control that opened this context menu.</param> /// <param name="position"> /// The position of the mouse cursor - or where the context menu should be opened. /// (<see cref="Offset"/> will be applied to this position.) /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="owner"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="owner"/> is not loaded. The owner needs to be a visible control. /// </exception> public void Open(UIControl owner, Vector2F position) { if (owner == null) { throw new ArgumentNullException("owner"); } var screen = owner.Screen; if (screen == null) { throw new ArgumentException("Invalid owner. The owner must be loaded.", "owner"); } if (!IsEnabled) { return; } // Close if already opened. Close(); Owner = owner; // Make visible and add to screen. IsVisible = true; screen.Children.Add(this); // Choose position near the given position. // The context menu is positioned so that it fits onto the screen. Measure(new Vector2F(float.PositiveInfinity)); float x = position.X; if (x + DesiredWidth > screen.ActualWidth) { // Show context menu on the left. x = x - DesiredWidth; } float offset = Offset; float y = position.Y + offset; if (y + DesiredHeight > screen.ActualHeight) { // Show context menu on top. // (We use 0.5 * offset if context menu is above cursor. This assumes that the cursor // is similar to the typical arrow where the hot spot is at the top. If the cursor is a // different shape we might need to adjust the offset.) y = y - DesiredHeight - 1.5f * offset; } X = x; Y = y; if (GlobalSettings.PlatformID == PlatformID.WindowsPhone8) { // Imitate position of Silverlight WP7 context menus. if (screen.ActualHeight >= screen.ActualWidth) { // Portrait mode. X = 0; HorizontalAlignment = HorizontalAlignment.Stretch; VerticalAlignment = VerticalAlignment.Top; } else { // Landscape mode. Y = 0; Width = screen.ActualWidth / 2; HorizontalAlignment = HorizontalAlignment.Left; VerticalAlignment = VerticalAlignment.Stretch; if (position.X <= screen.ActualWidth / 2) { // Show context menu on right half of the screen. X = screen.ActualWidth / 2; } else { // Show context menu on the left half of the screen. X = 0; } } } screen.FocusManager.Focus(this); IsOpen = true; }