1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 #ifndef INCLUDED_SFX2_SOURCE_SIDEBAR_FOCUSMANAGER_HXX 20 #define INCLUDED_SFX2_SOURCE_SIDEBAR_FOCUSMANAGER_HXX 21 22 #include <sfx2/sidebar/Panel.hxx> 23 #include <tools/link.hxx> 24 #include <vcl/keycod.hxx> 25 26 class Button; 27 28 namespace sfx2 { namespace sidebar { 29 30 class DeckTitleBar; 31 32 /** Concentrate all focus handling in this class. 33 34 There is one ring of windows that accept the input focus which are 35 cycled through with the arrow keys: 36 - the closer in the deck title (present only when docked) 37 - the panel title bars 38 - the tab bar items 39 40 When the focus is in a panel title then focus travels over 41 - the panel title 42 - the panel closer 43 - the panel content 44 45 Once the focus is in the panel content then focus cycles through 46 all controls inside the panel but not back to the title bar of 47 the panel. Escape places the focus back in the panel title. 48 */ 49 class FocusManager 50 { 51 public: 52 FocusManager(const std::function<void(const Panel&)>& rShowPanelFunctor, 53 const std::function<bool(const sal_Int32)> &rIsDeckOpenFunctor); 54 ~FocusManager(); 55 56 /** Forget all panels and buttons. Remove all window listeners. 57 */ 58 void Clear(); 59 60 /** Transfer the focus into the sidebar tree of windows. This is 61 typically called from the SidebarChildWindow as result of 62 pressing the F6 key. 63 */ 64 void GrabFocus(); 65 void GrabFocusPanel(); 66 67 void SetDeckTitle(DeckTitleBar* pDeckTitleBar); 68 void SetPanels(const SharedPanelContainer& rPanels); 69 void SetButtons(const ::std::vector<Button*>& rButtons); 70 71 private: 72 VclPtr<DeckTitleBar> mpDeckTitleBar; 73 std::vector<VclPtr<Panel> > maPanels; 74 std::vector<VclPtr<Button> > maButtons; 75 const std::function<void(const Panel&)> maShowPanelFunctor; 76 const std::function<bool(const sal_Int32)> mbIsDeckOpenFunctor; 77 78 enum PanelComponent 79 { 80 PC_DeckTitle, 81 PC_DeckToolBox, 82 PC_PanelTitle, 83 PC_PanelToolBox, 84 PC_PanelContent, 85 PC_TabBar, 86 PC_None 87 }; 88 class FocusLocation 89 { 90 public: 91 PanelComponent meComponent; 92 sal_Int32 mnIndex; 93 FocusLocation(const PanelComponent eComponent, const sal_Int32 nIndex); 94 }; 95 96 /** Listen for key events for panels and buttons. 97 */ 98 DECL_LINK( WindowEventListener, VclWindowEvent&, void); 99 DECL_LINK(ChildEventListener, VclWindowEvent&, void); 100 101 void ClearPanels(); 102 void ClearButtons(); 103 104 /** Let the focus manager listen for window events for the given 105 window. 106 */ 107 void RegisterWindow(vcl::Window& rWindow); 108 void UnregisterWindow(vcl::Window& rWindow); 109 110 /** Remove the window from the panel or the button container. 111 */ 112 void RemoveWindow(vcl::Window& rWindow); 113 114 void FocusDeckTitle(); 115 bool IsDeckTitleVisible() const; 116 bool IsPanelTitleVisible(const sal_Int32 nPanelIndex) const; 117 118 /** Set the focus to the title bar of the panel or, if the 119 title bar is not visible, directly to the panel. 120 @param nPanelIndex 121 Index of the panel to focus. 122 @param bFallbackToDeckTitle 123 When the panel title bar is not visible then The fallback 124 bias defines whether to focus the deck (true) or the panel 125 content (false) will be focused instead. 126 */ 127 void FocusPanel(const sal_Int32 nPanelIndex, 128 const bool bFallbackToDeckTitle); 129 130 void FocusPanelContent(const sal_Int32 nPanelIndex); 131 void FocusButton(const sal_Int32 nButtonIndex); 132 void ClickButton(const sal_Int32 nButtonIndex); 133 void MoveFocusInsidePanel(const FocusLocation& rLocation, 134 const sal_Int32 nDirection); 135 void MoveFocusInsideDeckTitle(const FocusLocation& rLocation, 136 const sal_Int32 nDirection); 137 138 void HandleKeyEvent(const vcl::KeyCode& rKeyCode, 139 const vcl::Window& rWindow); 140 141 FocusLocation GetFocusLocation(const vcl::Window& rWindow) const; 142 143 }; 144 145 } } // end of namespace sfx2::sidebar 146 147 #endif 148 149 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 150