void CMainFrame::OnGoSmall() { // ShowWindow(SW_SHOWMINIMIZED); // show/hide toolbars instead... if (m_bHideToolbars) ShowToolbars(false); else HideToolbars(); #ifndef BOB_DEMO_VER m_wndSystemBox->InDialAncestor()->ShowWindow(SW_SHOW); #endif }
bool CMainFrameControls::ShowToolbarsSelection() { auto& st = m_controlsVisibilityState; const auto newCS = GetEffectiveToolbarsSelection(); bool bRecalcLayout = false; if (!InFullscreenWithPermahiddenToolbars()) { const bool bResize = (newCS != st.nCurrentCS && !ToolbarsCoverVideo() && !m_pMainFrame->IsZoomed()); if (bResize) { CRect newRect; m_pMainFrame->GetWindowRect(newRect); newRect.bottom -= GetToolbarsHeight(st.nCurrentCS); bRecalcLayout = ShowToolbars(newCS); st.nCurrentCS = newCS; // some toolbars' height may depend on ControlChecked() newRect.bottom += GetToolbarsHeight(st.nCurrentCS); m_pMainFrame->MoveWindow(newRect); } else { bRecalcLayout = ShowToolbars(newCS); } } st.nCurrentCS = newCS; return bRecalcLayout; }
void CMainFrameControls::UpdateToolbarsVisibility() { ASSERT(GetCurrentThreadId() == AfxGetApp()->m_nThreadID); const auto& s = AfxGetAppSettings(); auto& st = m_controlsVisibilityState; const auto ePolicy = s.eHideFullscreenControlsPolicy; const unsigned uTimeout = s.uHideFullscreenControlsDelay; CPoint screenPoint; VERIFY(GetCursorPos(&screenPoint)); CPoint clientPoint(screenPoint); m_pMainFrame->ScreenToClient(&clientPoint); const MLS mls = m_pMainFrame->GetLoadState(); const bool bCanAutoHide = s.bHideFullscreenControls && (mls == MLS::LOADED || m_bDelayShowNotLoaded) && (m_pMainFrame->m_fFullScreen || s.bHideWindowedControls) && ePolicy != CAppSettings::HideFullscreenControlsPolicy::SHOW_NEVER; const bool bCanHideDockedPanels = s.bHideFullscreenDockedPanels; bool bEnumedPanelZones = false; struct { int maskShow, maskHide; void show(int mask) { maskShow |= mask; maskHide &= ~mask; } void hide(int mask) { maskHide |= mask; maskShow &= ~mask; } } mask = { 0, 0 }; const int maskAll = DOCK_LEFT | DOCK_RIGHT | DOCK_TOP | DOCK_BOTTOM; bool bRecalcLayout = false; bool bExclSeekbar = false; if (m_pMainFrame->m_fFullScreen && m_pMainFrame->m_pMVRS) { BOOL bOptExcl = FALSE, bOptExclSeekbar = FALSE; VERIFY(m_pMainFrame->m_pMVRS->SettingsGetBoolean(L"enableExclusive", &bOptExcl)); VERIFY(m_pMainFrame->m_pMVRS->SettingsGetBoolean(L"enableSeekbar", &bOptExclSeekbar)); bExclSeekbar = (bOptExcl && bOptExclSeekbar); } else if (m_bDelayShowNotLoaded && st.bLastHaveExclusiveSeekbar) { bExclSeekbar = true; } if (m_pMainFrame->m_fFullScreen && s.bHideFullscreenControls && ePolicy == CAppSettings::HideFullscreenControlsPolicy::SHOW_NEVER) { // hide completely mask.hide(maskAll); } else if (bCanAutoHide) { if (m_pMainFrame->m_wndSeekBar.DraggingThumb()) { // show bottom while dragging the seekbar thumb mask.show(DOCK_BOTTOM); } else { if (uTimeout == 0) { // hide initially when the timeout is zero; testCapture() and testHovering() may override it mask.hide(maskAll); // but exclude zone locks for (const auto zone : m_zoneHideLocks) { mask.maskHide &= ~zone; } } const bool bOnWindow = CMouse::CursorOnRootWindow(screenPoint, *m_pMainFrame); auto testCapture = [&]() { bool ret = false; if (HWND hWnd = GetCapture()) { if (hWnd != m_pMainFrame->m_hWnd) { if (GetAncestor(hWnd, GA_ROOT) == m_pMainFrame->m_hWnd) { if (!bEnumedPanelZones) { EnumPanelZones(); bEnumedPanelZones = true; } std::map<HWND, DockZone> targetParents; for (const auto& pair : m_panelDocks) { targetParents.emplace(std::make_pair(pair.second->m_hWnd, pair.first)); } for (const auto& pair : m_toolbars) { targetParents.emplace(std::make_pair(pair.second->m_hWnd, DOCK_BOTTOM)); } while (hWnd && hWnd != m_pMainFrame->m_hWnd) { auto it = targetParents.find(hWnd); if (it != targetParents.end()) { if (ePolicy == CAppSettings::HideFullscreenControlsPolicy::SHOW_WHEN_CURSOR_MOVED) { mask.show(maskAll); } else { ASSERT(ePolicy == CAppSettings::HideFullscreenControlsPolicy::SHOW_WHEN_HOVERED); mask.show(it->second); } } hWnd = GetParent(hWnd); } } ret = true; } } return ret; }; auto testHovering = [&]() { bool ret = false; if (bOnWindow) { unsigned uTop, uLeft, uRight, uBottom; GetDockZones(uTop, uLeft, uRight, uBottom, bEnumedPanelZones ? false : (bEnumedPanelZones = true)); unsigned uExclSeekbarHeight = 0; if (bExclSeekbar) { uExclSeekbarHeight = 56; // TODO: query this through IMadVRInfo uBottom = 0; } if (!bCanHideDockedPanels) { uTop = uLeft = uRight = 0; } CRect clientRect; m_pMainFrame->GetClientRect(clientRect); const bool bHoveringExclSeekbar = (bExclSeekbar && clientPoint.y + (int)uExclSeekbarHeight >= clientRect.Height()); ret = true; if (clientRect.PtInRect(clientPoint)) { if (ePolicy == CAppSettings::HideFullscreenControlsPolicy::SHOW_WHEN_CURSOR_MOVED) { if (!bHoveringExclSeekbar) { CRect nondockRect(clientRect); nondockRect.DeflateRect(uLeft, uTop, uRight, uBottom); if (!nondockRect.PtInRect(clientPoint)) { // hovering any - show all mask.show(maskAll); } else { ret = false; } } } else { ASSERT(ePolicy == CAppSettings::HideFullscreenControlsPolicy::SHOW_WHEN_HOVERED); // show hovered auto hoveringZone = [&](unsigned uTargetTop, unsigned uTargetLeft, unsigned uTargetRight, unsigned uTargetBottom) { DockZone ret = DOCK_NONE; if (clientPoint.y <= (int)uTargetTop) { ret = DOCK_TOP; } else if (clientPoint.y + (int)uTargetBottom >= clientRect.Height()) { ret = DOCK_BOTTOM; } else if (clientPoint.x <= (int)uTargetLeft) { ret = DOCK_LEFT; } else if (clientPoint.x + (int)uTargetRight >= clientRect.Width()) { ret = DOCK_RIGHT; } return ret; }; unsigned uVisibleTop, uVisibleLeft, uVisibleRight, uVisibleBottom; GetVisibleDockZones(uVisibleTop, uVisibleLeft, uVisibleRight, uVisibleBottom, bEnumedPanelZones ? false : (bEnumedPanelZones = true)); DockZone hoverZone = hoveringZone(uVisibleTop, uVisibleLeft, uVisibleRight, uVisibleBottom); if (hoverZone == DOCK_NONE) { if (!bHoveringExclSeekbar) { hoverZone = hoveringZone(uTop, uLeft, uRight, uBottom); if (hoverZone == DOCK_NONE) { ret = false; } else { mask.show(hoverZone); } } } else { mask.show(hoverZone); } } } } return ret; }; if (!testCapture() && !testHovering() && ePolicy == CAppSettings::HideFullscreenControlsPolicy::SHOW_WHEN_CURSOR_MOVED && bOnWindow && !CMouse::PointEqualsImprecise(screenPoint, st.lastShowPoint) && !m_pMainFrame->m_wndView.Dragging() && uTimeout > 0) { // show when corresponding hide policy is used, not hovering, non-zero timeout, the cursor moved, and not dragging mask.show(maskAll); } } } else { // always show otherwise mask.show(maskAll); } // we don't care for zone locks if we can't autohide at this point of time if (!bCanAutoHide) { m_zoneHideLocks.clear(); } // always hide bottom when madVR exclusive seekbar is enabled, // but respect zone locks if (bExclSeekbar && m_zoneHideLocks.find(DOCK_BOTTOM) == m_zoneHideLocks.end()) { mask.hide(DOCK_BOTTOM); } if ((mask.maskHide || mask.maskShow) && !bEnumedPanelZones) { EnumPanelZones(); bEnumedPanelZones = true; } const bool bNoTimer = m_zoneHideTicks.empty(); const DWORD dwTick = GetTickCount(); for (const auto& pair : m_zoneHideTicks) { if (pair.second <= dwTick && !(mask.maskShow & pair.first)) { mask.hide(pair.first); } } { auto delayedAutohideZone = [&](DockZone zone) { ASSERT(zone != DOCK_NONE); if (!(zone & mask.maskHide) && !(zone & mask.maskShow)) { if ((zone == DOCK_BOTTOM || (bCanHideDockedPanels && m_panelZones.find(zone) != m_panelZones.end())) && m_zoneHideTicks.find(zone) == m_zoneHideTicks.end() && m_zoneHideLocks.find(zone) == m_zoneHideLocks.end()) { ASSERT(uTimeout > 0); m_zoneHideTicks[zone] = dwTick + uTimeout; } } }; if (!st.bLastCanAutoHidePanels && bCanAutoHide && bCanHideDockedPanels) { delayedAutohideZone(DOCK_BOTTOM); delayedAutohideZone(DOCK_TOP); delayedAutohideZone(DOCK_LEFT); delayedAutohideZone(DOCK_RIGHT); } else if (!st.bLastCanAutoHideToolbars && bCanAutoHide) { delayedAutohideZone(DOCK_BOTTOM); } if (!bCanAutoHide && (st.bLastCanAutoHideToolbars || st.bLastCanAutoHidePanels)) { m_zoneHideTicks.clear(); } } if (!bCanHideDockedPanels) { for (const auto& pair : m_panels) { if (pair.second->IsAutohidden()) { bRecalcLayout = true; m_pMainFrame->ShowControlBar(pair.second, TRUE, TRUE); pair.second->SetAutohidden(false); } } } { auto showZone = [&](DockZone zone) { ASSERT(zone != DOCK_NONE); if (zone & mask.maskShow) { bool bSetTick = false; if (zone == DOCK_BOTTOM) { if (ShowToolbarsSelection()) { bRecalcLayout = true; } bSetTick = true; } auto it = m_panelZones.find(zone); if (it != m_panelZones.end()) { const auto& panels = it->second; for (const auto panel : panels) { if (m_panels[panel]->IsAutohidden()) { bRecalcLayout = true; m_pMainFrame->ShowControlBar(m_panels[panel], TRUE, TRUE); } if (bCanHideDockedPanels) { bSetTick = true; } } } if (bSetTick && bCanAutoHide) { if (m_zoneHideLocks.find(zone) == m_zoneHideLocks.end()) { // hide zone after timeout m_zoneHideTicks[zone] = dwTick + uTimeout; } else { // delay hiding locked zone for at least current timeout ASSERT(m_zoneHideTicks.find(zone) != m_zoneHideTicks.end()); DWORD dwNewHideTick = dwTick + uTimeout; DWORD& dwHideTick = m_zoneHideTicks[zone]; if (dwNewHideTick > dwHideTick) { m_zoneHideLocks.erase(zone); dwHideTick = dwNewHideTick; } } } else { m_zoneHideTicks.erase(zone); } } }; showZone(DOCK_BOTTOM); showZone(DOCK_TOP); showZone(DOCK_LEFT); showZone(DOCK_RIGHT); } if (mask.maskShow) { st.lastShowPoint = screenPoint; } { auto checkForPopup = [&](DockZone zone) { ASSERT(zone != DOCK_NONE); if (zone & mask.maskHide) { auto it = m_panelZones.find(zone); if (it != m_panelZones.end()) { const auto& panels = it->second; for (const auto panel : panels) { if (m_panels[panel]->HasActivePopup()) { mask.maskHide &= ~zone; break; } } } } }; checkForPopup(DOCK_BOTTOM); checkForPopup(DOCK_TOP); checkForPopup(DOCK_LEFT); checkForPopup(DOCK_RIGHT); } { auto autohideZone = [&](DockZone zone) { ASSERT(zone != DOCK_NONE); if (zone & mask.maskHide) { auto it = m_panelZones.find(zone); if (it != m_panelZones.end() && bCanHideDockedPanels) { const auto panels = it->second; // copy for (const auto panel : panels) { auto pBar = m_panels[panel]; if (!pBar->IsAutohidden() && GetCapture() != pBar->m_hWnd) { bRecalcLayout = true; m_pMainFrame->ShowControlBar(pBar, FALSE, TRUE); pBar->SetAutohidden(true); } } } if (zone == DOCK_BOTTOM) { if (ShowToolbars(CS_NONE)) { bRecalcLayout = true; } } m_zoneHideTicks.erase(zone); m_zoneHideLocks.erase(zone); } }; autohideZone(DOCK_BOTTOM); autohideZone(DOCK_TOP); autohideZone(DOCK_LEFT); autohideZone(DOCK_RIGHT); } const bool bNeedTimer = !m_zoneHideTicks.empty(); if (bNoTimer && bNeedTimer) { m_pMainFrame->m_timer32Hz.Subscribe(CMainFrame::Timer32HzSubscriber::TOOLBARS_HIDER, std::bind(&CMainFrameControls::UpdateToolbarsVisibility, this)); } else if (!bNoTimer && !bNeedTimer) { m_pMainFrame->m_timer32Hz.Unsubscribe(CMainFrame::Timer32HzSubscriber::TOOLBARS_HIDER); } if (bRecalcLayout) { m_pMainFrame->RecalcLayout(); } st.bLastCanAutoHideToolbars = bCanAutoHide; st.bLastCanAutoHidePanels = bCanAutoHide && bCanHideDockedPanels; st.bLastHaveExclusiveSeekbar = bExclSeekbar; }