xref: /trunk/main/sfx2/source/sidebar/TabBar.cxx (revision b9e67834)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "precompiled_sfx2.hxx"
23 
24 #include "TabBar.hxx"
25 #include "TabItem.hxx"
26 #include "sfx2/sidebar/ControlFactory.hxx"
27 #include "DeckDescriptor.hxx"
28 #include "Paint.hxx"
29 #include "sfx2/sidebar/Theme.hxx"
30 #include "Tools.hxx"
31 
32 #include <vcl/gradient.hxx>
33 #include <vcl/image.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/componentcontext.hxx>
36 #include <tools/SvBorder.hxx>
37 
38 #include <com/sun/star/graphic/XGraphicProvider.hpp>
39 
40 
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
43 
44 
45 
46 
47 namespace sfx2 { namespace sidebar {
48 
49 TabBar::TabBar (
50     Window* pParentWindow,
51     const Reference<frame::XFrame>& rxFrame,
52     const ::boost::function<void(const DeckDescriptor&)>& rDeckActivationFunctor,
53     const ::boost::function<void(const Rectangle&)>& rPopupMenuProvider)
54     : Window(pParentWindow),
55       mxFrame(rxFrame),
56       mpMenuButton(ControlFactory::CreateMenuButton(this)),
57       maItems(),
58       maDeckActivationFunctor(rDeckActivationFunctor),
59       maPopupMenuProvider(rPopupMenuProvider)
60 {
61     SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
62 
63     mpMenuButton->SetHelpText(A2S("This is the menu button"));
64     mpMenuButton->SetQuickHelpText(A2S("This is the menu button"));
65     mpMenuButton->SetModeImage(
66         Theme::GetImage(Theme::Image_Menu),
67         Theme::IsHighContrastMode()
68             ? BMP_COLOR_HIGHCONTRAST
69             : BMP_COLOR_NORMAL);
70     mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
71 
72     EnableClipSiblings();
73 }
74 
75 
76 
77 
78 TabBar::~TabBar (void)
79 {
80 }
81 
82 
83 
84 
85 void TabBar::Paint (const Rectangle& rUpdateArea)
86 {
87     Window::Paint(rUpdateArea);
88 
89     const sal_Int32 nVerticalPadding (Theme::GetTabMenuPadding());
90     const sal_Int32 nHorizontalPadding (Theme::GetInteger(Theme::Int_TabMenuSeparatorPadding));
91     SetLineColor(Theme::GetColor(Theme::Color_TabMenuSeparator));
92     DrawLine(
93         Point(nHorizontalPadding, mnMenuSeparatorY),
94         Point(GetSizePixel().Width()-nHorizontalPadding, mnMenuSeparatorY));
95 }
96 
97 
98 
99 
100 sal_Int32 TabBar::GetDefaultWidth (void)
101 {
102     return Theme::GetInteger(Theme::Int_TabItemWidth)
103         + Theme::GetInteger(Theme::Int_TabBarLeftPadding)
104         + Theme::GetInteger(Theme::Int_TabBarRightPadding);
105 }
106 
107 
108 
109 
110 void TabBar::SetDecks (
111     const ResourceManager::DeckContainer& rDeckDescriptors)
112 {
113     // Remove the current buttons.
114     {
115         Window aTemporaryParent (NULL,0);
116         for(ItemContainer::const_iterator
117                 iItem(maItems.begin()), iEnd(maItems.end());
118             iItem!=iEnd;
119             ++iItem)
120         {
121             removeWindow(iItem->mpButton, &aTemporaryParent);
122         }
123         maItems.clear();
124     }
125 
126     maItems.resize(rDeckDescriptors.size());
127     sal_Int32 nIndex (0);
128     for (ResourceManager::DeckContainer::const_iterator
129              iDeck(rDeckDescriptors.begin()),
130              iEnd(rDeckDescriptors.end());
131          iDeck!=iEnd;
132          ++iDeck)
133     {
134         Item& rItem (maItems[nIndex++]);
135         rItem.maDeckDescriptor = *iDeck;
136         rItem.mpButton = CreateTabItem(*iDeck);
137         rItem.mpButton->SetClickHdl(LINK(&rItem, TabBar::Item, HandleClick));
138         rItem.maDeckActivationFunctor = maDeckActivationFunctor;
139         rItem.mbIsHiddenByDefault = false;
140         rItem.mbIsHidden = rItem.mbIsHiddenByDefault;
141     }
142 
143     UpdateButtonIcons();
144     Layout();
145 }
146 
147 
148 
149 
150 void TabBar::UpdateButtonIcons (void)
151 {
152     const BmpColorMode eColorMode (
153         Theme::IsHighContrastMode()
154             ? BMP_COLOR_HIGHCONTRAST
155             : BMP_COLOR_NORMAL);
156 
157     mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_Menu), eColorMode);
158 
159     for(ItemContainer::const_iterator
160             iItem(maItems.begin()), iEnd(maItems.end());
161         iItem!=iEnd;
162         ++iItem)
163     {
164         iItem->mpButton->SetModeImage(
165             GetItemImage(iItem->maDeckDescriptor),
166             eColorMode);
167     }
168 }
169 
170 
171 
172 
173 void TabBar::Layout (void)
174 {
175     const SvBorder aPadding (
176         Theme::GetInteger(Theme::Int_TabBarLeftPadding),
177         Theme::GetInteger(Theme::Int_TabBarTopPadding),
178         Theme::GetInteger(Theme::Int_TabBarRightPadding),
179         Theme::GetInteger(Theme::Int_TabBarBottomPadding));
180     sal_Int32 nX (aPadding.Top());
181     sal_Int32 nY (aPadding.Left());
182     const Size aTabItemSize (
183         Theme::GetInteger(Theme::Int_TabItemWidth),
184         Theme::GetInteger(Theme::Int_TabItemHeight));
185 
186     if (mpMenuButton != NULL)
187     {
188         mpMenuButton->SetPosSizePixel(
189             Point(nX,nY),
190             aTabItemSize);
191         mpMenuButton->Show();
192         nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetInteger(Theme::Int_TabMenuPadding);
193         mnMenuSeparatorY = nY - Theme::GetInteger(Theme::Int_TabMenuPadding)/2 - 1;
194     }
195 
196     for(ItemContainer::const_iterator
197             iItem(maItems.begin()), iEnd(maItems.end());
198         iItem!=iEnd;
199         ++iItem)
200     {
201         if (iItem->mbIsHidden)
202             continue;
203 
204         Button& rButton (*iItem->mpButton);
205 
206         // Place and size the icon.
207         rButton.SetPosSizePixel(
208             Point(nX,nY),
209             aTabItemSize);
210         rButton.Show();
211 
212         nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
213     }
214     Invalidate();
215 }
216 
217 
218 
219 
220 void TabBar::HighlightDeck (const ::rtl::OUString& rsDeckId)
221 {
222     for (ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
223          iItem!=iEnd;
224          ++iItem)
225     {
226         if (iItem->maDeckDescriptor.msId.equals(rsDeckId))
227         {
228             iItem->mpButton->Check();
229             break;
230         }
231     }
232 }
233 
234 
235 
236 
237 void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
238 {
239     if  (rDataChangedEvent.GetType() == DATACHANGED_SETTINGS
240         &&  (rDataChangedEvent.GetFlags() & SETTINGS_STYLE)!= 0)
241     {
242         UpdateButtonIcons();
243         Invalidate();
244     }
245     else
246         Window::DataChanged(rDataChangedEvent);
247 }
248 
249 
250 
251 
252 RadioButton* TabBar::CreateTabItem (const DeckDescriptor& rDeckDescriptor)
253 {
254     RadioButton* pItem = ControlFactory::CreateTabItem(this);
255     pItem->SetHelpText(rDeckDescriptor.msHelpText);
256     pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
257 
258     return pItem;
259 }
260 
261 
262 
263 
264 Image TabBar::GetItemImage (const DeckDescriptor& rDeckDescriptor) const
265 {
266     return Tools::GetImage(
267         rDeckDescriptor.msIconURL,
268         rDeckDescriptor.msHighContrastIconURL,
269         mxFrame);
270 }
271 
272 
273 
274 
275 IMPL_LINK(TabBar::Item, HandleClick, Button*, pButton)
276 {
277     maDeckActivationFunctor(maDeckDescriptor);
278     return 1;
279 }
280 
281 
282 
283 
284 void TabBar::AddPopupMenuEntries (
285     PopupMenu& rMenu,
286     const sal_Int32 nFirstIndex)
287 {
288     sal_Int32 nIndex (nFirstIndex);
289     for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
290         iItem!=iEnd;
291         ++iItem)
292     {
293         rMenu.InsertItem(nIndex, iItem->maDeckDescriptor.msTitle, MIB_RADIOCHECK);
294         rMenu.CheckItem(nIndex, iItem->mpButton->IsChecked());
295         ++nIndex;
296     }
297 }
298 
299 
300 
301 
302 void TabBar::AddCustomizationMenuEntries (
303     PopupMenu& rMenu,
304     const sal_Int32 nFirstIndex)
305 {
306     sal_Int32 nIndex (nFirstIndex);
307     for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
308         iItem!=iEnd;
309         ++iItem)
310     {
311         rMenu.InsertItem(nIndex, iItem->maDeckDescriptor.msTitle, MIB_CHECKABLE);
312         rMenu.CheckItem(nIndex, !iItem->mbIsHidden);
313         ++nIndex;
314     }
315 }
316 
317 
318 
319 
320 const DeckDescriptor& TabBar::GetDeckDescriptorForIndex (const sal_Int32 nIndex) const
321 {
322     if (nIndex<0 || nIndex>=maItems.size())
323         throw RuntimeException();
324     else
325         return maItems[nIndex].maDeckDescriptor;
326 }
327 
328 
329 
330 
331 void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
332 {
333     if (nIndex<0 || nIndex>=maItems.size())
334         throw RuntimeException();
335     else
336     {
337         maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
338         Layout();
339     }
340 }
341 
342 
343 
344 
345 void TabBar::RestoreHideFlags (void)
346 {
347     bool bNeedsLayout (false);
348     for(ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
349         iItem!=iEnd;
350         ++iItem)
351     {
352         if (iItem->mbIsHidden != iItem->mbIsHiddenByDefault)
353         {
354             iItem->mbIsHidden = iItem->mbIsHiddenByDefault;
355             bNeedsLayout = true;
356         }
357     }
358     if (bNeedsLayout)
359         Layout();
360 }
361 
362 
363 
364 
365 IMPL_LINK(TabBar, OnToolboxClicked, void*, pToolBox)
366 {
367     //    mpMenuButton->EndSelection();
368     maPopupMenuProvider(
369         Rectangle(
370             mpMenuButton->GetPosPixel(),
371             mpMenuButton->GetSizePixel()));
372 
373     return 0;
374 }
375 
376 
377 
378 } } // end of namespace sfx2::sidebar
379