void UpdateRowsColumns(ViewMode newMode, DisplayRegionHelperInfo info, Rect rcControl) { if (m_columnLeft != null && m_columnMiddle != null && m_columnRight != null && m_rowTop != null && m_rowMiddle != null && m_rowBottom != null) { // Reset split lengths m_columnMiddle.Width = new GridLength(0, GridUnitType.Pixel); m_rowMiddle.Height = new GridLength(0, GridUnitType.Pixel); // Set columns lengths if (newMode == ViewMode.LeftRight || newMode == ViewMode.RightLeft) { m_columnLeft.Width = (newMode == ViewMode.LeftRight) ? Pane1Length : Pane2Length; m_columnRight.Width = (newMode == ViewMode.LeftRight) ? Pane2Length : Pane1Length; } else { m_columnLeft.Width = new GridLength(1, GridUnitType.Star); m_columnRight.Width = new GridLength(0, GridUnitType.Pixel); } // Set row lengths if (newMode == ViewMode.TopBottom || newMode == ViewMode.BottomTop) { m_rowTop.Height = (newMode == ViewMode.TopBottom) ? Pane1Length : Pane2Length; m_rowBottom.Height = (newMode == ViewMode.TopBottom) ? Pane2Length : Pane1Length; } else { m_rowTop.Height = new GridLength(1, GridUnitType.Star); m_rowBottom.Height = new GridLength(0, GridUnitType.Pixel); } // Handle regions if (IsInMultipleRegions(info, rcControl) && newMode != ViewMode.Pane1Only && newMode != ViewMode.Pane2Only) { Rect rc1 = info.Regions[0]; Rect rc2 = info.Regions[1]; Rect rcWindow = DisplayRegionHelper.WindowRect(); if (info.Mode == TwoPaneViewMode.Wide) { m_columnMiddle.Width = new GridLength(rc2.X - rc1.Width, GridUnitType.Pixel); m_columnLeft.Width = new GridLength(rc1.Width - rcControl.X, GridUnitType.Pixel); // UNO TODO: Max is needed when regions don't match the Window size orientation m_columnRight.Width = new GridLength(Math.Max(0, rc2.Width - ((rcWindow.Width - rcControl.Width) - rcControl.X)), GridUnitType.Pixel); } else { m_rowMiddle.Height = new GridLength(rc2.Y - rc1.Height, GridUnitType.Pixel); m_rowTop.Height = new GridLength(rc1.Height - rcControl.Y, GridUnitType.Pixel); // UNO TODO: Max is needed when regions don't match the Window size orientation m_rowBottom.Height = new GridLength(Math.Max(0, rc2.Height - ((rcWindow.Height - rcControl.Height) - rcControl.Y)), GridUnitType.Pixel); } } } }
bool IsInMultipleRegions(DisplayRegionHelperInfo info, Rect rcControl) { bool isInMultipleRegions = false; if (info.Mode != TwoPaneViewMode.SinglePane) { Rect rc1 = info.Regions[0]; Rect rc2 = info.Regions[1]; Rect rcWindow = DisplayRegionHelper.WindowRect(); if (info.Mode == TwoPaneViewMode.Wide) { // Check that the control is over the split if (rcControl.X < rc1.Width && rcControl.X + rcControl.Width > rc2.X) { isInMultipleRegions = true; } } else if (info.Mode == TwoPaneViewMode.Tall) { // Check that the control is over the split if (rcControl.Y < rc1.Height && rcControl.Y + rcControl.Height > rc2.Y) { isInMultipleRegions = true; } } } return(isInMultipleRegions); }
internal static DisplayRegionHelperInfo GetRegionInfo() { var instance = LifetimeHandler.GetDisplayRegionHelperInstance(); var info = new DisplayRegionHelperInfo(); info.Mode = TwoPaneViewMode.SinglePane; if (instance.m_simulateDisplayRegions) { // Create fake rectangles for test app if (instance.m_simulateMode == TwoPaneViewMode.Wide) { info.Regions[0] = m_simulateWide0; info.Regions[1] = m_simulateWide1; info.Mode = TwoPaneViewMode.Wide; } else if (instance.m_simulateMode == TwoPaneViewMode.Tall) { info.Regions[0] = m_simulateTall0; info.Regions[1] = m_simulateTall1; info.Mode = TwoPaneViewMode.Tall; } else { info.Regions[0] = m_simulateWide0; } } else { // ApplicationView.GetForCurrentView throws on failure; in that case we just won't do anything. ApplicationView view = null; try { view = ApplicationView.GetForCurrentView(); } catch { } if (view != null) { var rects = view.GetSpanningRects(); if (rects.Count == 2) { info.Regions = new Rect[rects.Count]; info.Regions[0] = new Rect(rects[0].Location.PhysicalToLogicalPixels(), rects[0].Size.PhysicalToLogicalPixels()); info.Regions[1] = new Rect(rects[1].Location.PhysicalToLogicalPixels(), rects[1].Size.PhysicalToLogicalPixels()); // Determine orientation. If neither of these are true, default to doing nothing. if (info.Regions[0].X < info.Regions[1].X && info.Regions[0].Y == info.Regions[1].Y) { // Double portrait info.Mode = TwoPaneViewMode.Wide; } else if (info.Regions[0].X == info.Regions[1].X && info.Regions[0].Y < info.Regions[1].Y) { // Double landscape info.Mode = TwoPaneViewMode.Tall; } } } } return(info); }
void UpdateMode() { // Don't bother running this logic until after we hit OnApplyTemplate. if (!m_loaded) { return; } double controlWidth = ActualWidth; double controlHeight = ActualHeight; ViewMode newMode = (PanePriority == TwoPaneViewPriority.Pane1) ? ViewMode.Pane1Only : ViewMode.Pane2Only; // Calculate new mode DisplayRegionHelperInfo info = DisplayRegionHelper.GetRegionInfo(); Rect rcControl = GetControlRect(); bool isInMultipleRegions = IsInMultipleRegions(info, rcControl); if (isInMultipleRegions) { if (info.Mode == TwoPaneViewMode.Wide) { // Regions are laid out horizontally if (WideModeConfiguration != TwoPaneViewWideModeConfiguration.SinglePane) { newMode = (WideModeConfiguration == TwoPaneViewWideModeConfiguration.LeftRight) ? ViewMode.LeftRight : ViewMode.RightLeft; } } else if (info.Mode == TwoPaneViewMode.Tall) { // Regions are laid out vertically if (TallModeConfiguration != TwoPaneViewTallModeConfiguration.SinglePane) { newMode = (TallModeConfiguration == TwoPaneViewTallModeConfiguration.TopBottom) ? ViewMode.TopBottom : ViewMode.BottomTop; } } } else { // One region if (controlWidth > MinWideModeWidth && WideModeConfiguration != TwoPaneViewWideModeConfiguration.SinglePane) { // Split horizontally newMode = (WideModeConfiguration == TwoPaneViewWideModeConfiguration.LeftRight) ? ViewMode.LeftRight : ViewMode.RightLeft; } else if (controlHeight > MinTallModeHeight && TallModeConfiguration != TwoPaneViewTallModeConfiguration.SinglePane) { // Split vertically newMode = (TallModeConfiguration == TwoPaneViewTallModeConfiguration.TopBottom) ? ViewMode.TopBottom : ViewMode.BottomTop; } } // Update row/column sizes (this may need to happen even if the mode doesn't change) UpdateRowsColumns(newMode, info, rcControl); // Update mode if necessary if (newMode != m_currentMode) { m_currentMode = newMode; TwoPaneViewMode newViewMode = TwoPaneViewMode.SinglePane; switch (m_currentMode) { case ViewMode.Pane1Only: VisualStateManager.GoToState(this, "ViewMode_OneOnly", true); break; case ViewMode.Pane2Only: VisualStateManager.GoToState(this, "ViewMode_TwoOnly", true); break; case ViewMode.LeftRight: VisualStateManager.GoToState(this, "ViewMode_LeftRight", true); newViewMode = TwoPaneViewMode.Wide; break; case ViewMode.RightLeft: VisualStateManager.GoToState(this, "ViewMode_RightLeft", true); newViewMode = TwoPaneViewMode.Wide; break; case ViewMode.TopBottom: VisualStateManager.GoToState(this, "ViewMode_TopBottom", true); newViewMode = TwoPaneViewMode.Tall; break; case ViewMode.BottomTop: VisualStateManager.GoToState(this, "ViewMode_BottomTop", true); newViewMode = TwoPaneViewMode.Tall; break; } if (newViewMode != Mode) { SetValue(ModeProperty, newViewMode); ModeChanged?.Invoke(this, this); } } }