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 
20 #ifndef INCLUDED_SVX_SOURCE_INC_FMCONTROLBORDERMANAGER_HXX
21 #define INCLUDED_SVX_SOURCE_INC_FMCONTROLBORDERMANAGER_HXX
22 
23 #include <com/sun/star/awt/VisualEffect.hpp>
24 #include <com/sun/star/awt/FontUnderline.hpp>
25 #include <com/sun/star/awt/XControl.hpp>
26 #include <com/sun/star/awt/XVclWindowPeer.hpp>
27 #include <o3tl/typed_flags_set.hxx>
28 #include <tools/color.hxx>
29 
30 #include <set>
31 
32 namespace com { namespace sun { namespace star { namespace form { namespace validation {
33     class XValidatableFormComponent;
34 } } } } }
35 
36 enum class ControlStatus {
37     NONE        = 0x00,
38     Focused     = 0x01,
39     MouseHover  = 0x02,
40     Invalid     = 0x04
41 };
42 namespace o3tl {
43     template<> struct typed_flags<ControlStatus> : is_typed_flags<ControlStatus, 0x07> {};
44 }
45 
46 
47 namespace svxform
48 {
49 
50 
51     struct BorderDescriptor
52     {
53         sal_Int16   nBorderType;
54         Color       nBorderColor;
55 
BorderDescriptorsvxform::BorderDescriptor56         BorderDescriptor()
57             :nBorderType( css::awt::VisualEffect::FLAT )
58         {
59         }
60     };
61 
62     struct UnderlineDescriptor
63     {
64         sal_Int16 nUnderlineType;
65         Color     nUnderlineColor;
66 
UnderlineDescriptorsvxform::UnderlineDescriptor67         UnderlineDescriptor()
68             :nUnderlineType( css::awt::FontUnderline::NONE )
69         {
70         }
71 
UnderlineDescriptorsvxform::UnderlineDescriptor72         UnderlineDescriptor( sal_Int16 _nUnderlineType, Color _nUnderlineColor )
73             :nUnderlineType( _nUnderlineType )
74             ,nUnderlineColor( _nUnderlineColor )
75         {
76         }
77     };
78 
79     struct ControlData : public BorderDescriptor, UnderlineDescriptor
80     {
81         css::uno::Reference< css::awt::XControl > xControl;
82         OUString                                                     sOriginalHelpText;
83 
ControlDatasvxform::ControlData84         ControlData() : BorderDescriptor() { }
ControlDatasvxform::ControlData85         ControlData( const css::uno::Reference< css::awt::XControl >& _rxControl )
86             :xControl( _rxControl )
87         {
88         }
89     };
90 
91 
92     //= ControlBorderManager
93 
94     /** manages the dynamic border color for form controls
95 
96         Used by the <type>FormController</type>, this class manages the dynamic changes in the
97         border color of form controls. For this a set of events have to be forwarded to the manager
98         instance, which then will switch the border color depending on the mouse and focus status
99         of the controls.
100     */
101     class ControlBorderManager
102     {
103     private:
104         struct ControlDataCompare
105         {
operator ()svxform::ControlBorderManager::ControlDataCompare106            bool operator()( const ControlData& _rLHS, const ControlData& _rRHS ) const
107            {
108                return _rLHS.xControl.get() < _rRHS.xControl.get();
109            }
110         };
111 
112         typedef ::std::set< ControlData, ControlDataCompare > ControlBag;
113         typedef ::std::set< css::uno::Reference< css::awt::XVclWindowPeer > >  PeerBag;
114 
115         PeerBag     m_aColorableControls;
116         PeerBag     m_aNonColorableControls;
117 
118         ControlData m_aFocusControl;
119         ControlData m_aMouseHoverControl;
120         ControlBag  m_aInvalidControls;
121 
122 
123         // attributes
124         Color       m_nFocusColor;
125         Color       m_nMouseHoveColor;
126         Color       m_nInvalidColor;
127         bool        m_bDynamicBorderColors;
128 
129     public:
130         ControlBorderManager();
131         ~ControlBorderManager();
132 
133     public:
134         void    focusGained( const css::uno::Reference< css::uno::XInterface >& _rxControl );
135         void    focusLost( const css::uno::Reference< css::uno::XInterface >& _rxControl );
136         void    mouseEntered( const css::uno::Reference< css::uno::XInterface >& _rxControl );
137         void    mouseExited( const css::uno::Reference< css::uno::XInterface >& _rxControl );
138 
139         void    validityChanged(
140                     const css::uno::Reference< css::awt::XControl >& _rxControl,
141                     const css::uno::Reference< css::form::validation::XValidatableFormComponent >& _rxValidatable
142                 );
143 
144         /// enables dynamic border color for the controls
145         void    enableDynamicBorderColor( );
146         /// disables dynamic border color for the controls
147         void    disableDynamicBorderColor( );
148 
149         /** sets a color to be used for a given status
150             @param _nStatus
151                 the status which the color should be applied for. Must not be ControlStatus::NONE
152             @param _nColor
153                 the color to apply for the given status
154         */
155         void    setStatusColor( ControlStatus _nStatus, Color _nColor );
156 
157         /** restores all colors of all controls where we possibly changed them
158         */
159         void    restoreAll();
160 
161     private:
162         /** called when a control got one of the two possible statuses (focused, and hovered with the mouse)
163             @param _rxControl
164                 the control which gained the status
165             @param _rControlData
166                 the control's status data, as a reference to our respective member
167         */
168         void    controlStatusGained(
169                     const css::uno::Reference< css::uno::XInterface >& _rxControl,
170                     ControlData& _rControlData
171                 );
172 
173         /** called when a control lost one of the two possible statuses (focused, and hovered with the mouse)
174             @param _rxControl
175                 the control which lost the status
176             @param _rControlData
177                 the control's status data, as a reference to our respective member
178         */
179         void    controlStatusLost( const css::uno::Reference< css::uno::XInterface >& _rxControl, ControlData& _rControlData );
180 
181         /** determines whether the border of a given peer can be colored
182             @param _rxPeer
183                 the peer to examine. Must not be <NULL/>
184         */
185         bool    canColorBorder( const css::uno::Reference< css::awt::XVclWindowPeer >& _rxPeer );
186 
187         /** determines the status of the given control
188         */
189         ControlStatus   getControlStatus( const css::uno::Reference< css::awt::XControl >& _rxControl );
190 
191         /** retrieves the color associated with a given ControlStatus
192             @param _eStatus
193                 the status of the control. Must not be <member>ControlStatus::none</member>
194         */
195         Color       getControlColorByStatus( ControlStatus _eStatus );
196 
197         /** sets the border color for a given control, depending on its status
198             @param _rxControl
199                 the control to set the border color for. Must not be <NULL/>
200             @param _rxPeer
201                 the peer of the control, to be passed herein for optimization the caller usually needs it, anyway).
202                 Must not be <NULL/>
203             @param _rFallback
204                 the color/type to use when the control has the status ControlStatus::NONE
205         */
206         void            updateBorderStyle(
207                             const css::uno::Reference< css::awt::XControl >& _rxControl,
208                             const css::uno::Reference< css::awt::XVclWindowPeer >& _rxPeer,
209                             const BorderDescriptor& _rFallback
210                         );
211 
212         /** determines the to-be-remembered original border color and type for a control
213 
214             The method also takes into account that the control may currently have an overwritten
215             border style
216 
217             @param _rxControl
218                 the control to examine. Must not be <NULL/>, and have a non-<NULL/> peer
219         */
220         void determineOriginalBorderStyle(
221                     const css::uno::Reference< css::awt::XControl >& _rxControl,
222                     BorderDescriptor& _rData
223                 ) const;
224     };
225 
226 
227 }
228 
229 
230 #endif // INCLUDED_SVX_SOURCE_INC_FMCONTROLBORDERMANAGER_HXX
231 
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
233