xref: /trunk/main/sfx2/source/sidebar/TabBar.cxx (revision ff12d537)
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 "ControlFactory.hxx"
27 #include "DeckDescriptor.hxx"
28 #include "Paint.hxx"
29 #include "Theme.hxx"
30 #include "sfx2/imagemgr.hxx"
31 
32 #include <vcl/gradient.hxx>
33 #include <vcl/image.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/componentcontext.hxx>
36 #include <comphelper/namedvaluecollection.hxx>
37 #include <tools/SvBorder.hxx>
38 
39 #include <com/sun/star/graphic/XGraphicProvider.hpp>
40 
41 
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 
45 
46 
47 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
48 
49 
50 namespace sfx2 { namespace sidebar {
51 
52 TabBar::TabBar (
53     Window* pParentWindow,
54     const Reference<frame::XFrame>& rxFrame,
55     const ::boost::function<void(const DeckDescriptor&)>& rDeckActivationFunctor,
56     const ::boost::function<void(const Rectangle&)>& rPopupMenuProvider)
57     : Window(pParentWindow),
58       mxFrame(rxFrame),
59       mpMenuButton(ControlFactory::CreateMenuButton(this)),
60       maItems(),
61       maDeckActivationFunctor(rDeckActivationFunctor),
62       maPopupMenuProvider(rPopupMenuProvider)
63 {
64     SetBackground(Theme::GetTabBarBackground().GetWallpaper());
65 
66     mpMenuButton->SetHelpText(A2S("This is the menu button"));
67     mpMenuButton->SetQuickHelpText(A2S("This is the menu button"));
68     mpMenuButton->SetModeImage(
69         Theme::GetMenuImage(),
70         Theme::IsHighContrastMode()
71             ? BMP_COLOR_HIGHCONTRAST
72             : BMP_COLOR_NORMAL);
73     mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
74 }
75 
76 
77 
78 
79 TabBar::~TabBar (void)
80 {
81 }
82 
83 
84 
85 
86 void TabBar::Paint (const Rectangle& rUpdateArea)
87 {
88     Window::Paint(rUpdateArea);
89 
90     const sal_Int32 nVerticalPadding (Theme::GetTabMenuPadding());
91     const sal_Int32 nHorizontalPadding (Theme::GetTabMenuSeparatorPadding());
92     SetLineColor(Theme::GetTabMenuSeparatorColor());
93     DrawLine(
94         Point(nHorizontalPadding, mnMenuSeparatorY),
95         Point(GetSizePixel().Width()-nHorizontalPadding, mnMenuSeparatorY));
96 }
97 
98 
99 
100 
101 sal_Int32 TabBar::GetDefaultWidth (void)
102 {
103     const SvBorder aPadding (Theme::GetTabBarPadding());
104     return Theme::GetTabItemSize().Width() + aPadding.Left() + aPadding.Right();
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::GetMenuImage(), 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 (Theme::GetTabBarPadding());
176     sal_Int32 nX (aPadding.Top());
177     sal_Int32 nY (aPadding.Left());
178 
179     if (mpMenuButton != NULL)
180     {
181         mpMenuButton->SetPosSizePixel(
182             Point(nX,nY),
183             Theme::GetTabItemSize());
184         mpMenuButton->Show();
185         nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetTabMenuPadding();
186         mnMenuSeparatorY = nY - Theme::GetTabMenuPadding()/2 - 1;
187     }
188 
189     for(ItemContainer::const_iterator
190             iItem(maItems.begin()), iEnd(maItems.end());
191         iItem!=iEnd;
192         ++iItem)
193     {
194         if (iItem->mbIsHidden)
195             continue;
196 
197         Button& rButton (*iItem->mpButton);
198 
199         // Place and size the icon.
200         rButton.SetPosSizePixel(
201             Point(nX,nY),
202             Theme::GetTabItemSize());
203         rButton.Show();
204 
205         nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
206     }
207     Invalidate();
208 }
209 
210 
211 
212 
213 void TabBar::HighlightDeck (const ::rtl::OUString& rsDeckId)
214 {
215     for (ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
216          iItem!=iEnd;
217          ++iItem)
218     {
219         if (iItem->maDeckDescriptor.msId.equals(rsDeckId))
220         {
221             iItem->mpButton->Check();
222             break;
223         }
224     }
225 }
226 
227 
228 
229 
230 void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
231 {
232     if  (rDataChangedEvent.GetType() == DATACHANGED_SETTINGS
233         &&  (rDataChangedEvent.GetFlags() & SETTINGS_STYLE)!= 0)
234     {
235         UpdateButtonIcons();
236         Invalidate();
237     }
238     else
239         Window::DataChanged(rDataChangedEvent);
240 }
241 
242 
243 
244 
245 RadioButton* TabBar::CreateTabItem (const DeckDescriptor& rDeckDescriptor)
246 {
247     RadioButton* pItem = ControlFactory::CreateTabItem(this);
248     pItem->SetHelpText(rDeckDescriptor.msHelpText);
249     pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
250 
251     return pItem;
252 }
253 
254 
255 
256 
257 Image TabBar::GetItemImage (const DeckDescriptor& rDeckDescriptor) const
258 {
259     const bool bIsHighContrastModeActive (Theme::IsHighContrastMode());
260     const ::rtl::OUString sIconURL (
261         bIsHighContrastModeActive
262             ? rDeckDescriptor.msHighContrastIconURL
263             : rDeckDescriptor.msIconURL);
264     if (sIconURL.getLength() > 0)
265     {
266         static const sal_Char* sCommandImagePrefix = "private:commandimage/";
267         static const sal_Int32 nCommandImagePrefixLen = strlen(sCommandImagePrefix);
268         if (sIconURL.compareToAscii(sCommandImagePrefix, nCommandImagePrefixLen) == 0)
269         {
270             ::rtl::OUStringBuffer aCommandName;
271             aCommandName.appendAscii(".uno:");
272             aCommandName.append(sIconURL.copy(nCommandImagePrefixLen));
273             const ::rtl::OUString sCommandName (aCommandName.makeStringAndClear());
274 
275             const Image aPanelImage (GetImage(mxFrame, sCommandName, sal_False, bIsHighContrastModeActive));
276             return aPanelImage;
277         }
278         else
279         {
280             const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
281             const Reference<graphic::XGraphicProvider> xGraphicProvider (
282                 aContext.createComponent("com.sun.star.graphic.GraphicProvider"),
283                 UNO_QUERY);
284             if ( xGraphicProvider.is())
285             {
286                 ::comphelper::NamedValueCollection aMediaProperties;
287                 aMediaProperties.put("URL", sIconURL);
288                 const Reference<graphic::XGraphic> xGraphic (
289                     xGraphicProvider->queryGraphic(aMediaProperties.getPropertyValues()),
290                     UNO_QUERY);
291                 if (xGraphic.is())
292                     return Image(xGraphic);
293             }
294         }
295     }
296     return Image();
297 }
298 
299 
300 
301 
302 IMPL_LINK(TabBar::Item, HandleClick, Button*, pButton)
303 {
304     maDeckActivationFunctor(maDeckDescriptor);
305     return 1;
306 }
307 
308 
309 
310 
311 void TabBar::AddPopupMenuEntries (
312     PopupMenu& rMenu,
313     const sal_Int32 nFirstIndex)
314 {
315     sal_Int32 nIndex (nFirstIndex);
316     for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
317         iItem!=iEnd;
318         ++iItem)
319     {
320         rMenu.InsertItem(nIndex, iItem->maDeckDescriptor.msTitle, MIB_RADIOCHECK);
321         rMenu.CheckItem(nIndex, iItem->mpButton->IsChecked());
322         ++nIndex;
323     }
324 }
325 
326 
327 
328 
329 void TabBar::AddCustomizationMenuEntries (
330     PopupMenu& rMenu,
331     const sal_Int32 nFirstIndex)
332 {
333     sal_Int32 nIndex (nFirstIndex);
334     for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
335         iItem!=iEnd;
336         ++iItem)
337     {
338         rMenu.InsertItem(nIndex, iItem->maDeckDescriptor.msTitle, MIB_CHECKABLE);
339         rMenu.CheckItem(nIndex, !iItem->mbIsHidden);
340         ++nIndex;
341     }
342 }
343 
344 
345 
346 
347 const DeckDescriptor& TabBar::GetDeckDescriptorForIndex (const sal_Int32 nIndex) const
348 {
349     if (nIndex<0 || nIndex>=maItems.size())
350         throw RuntimeException();
351     else
352         return maItems[nIndex].maDeckDescriptor;
353 }
354 
355 
356 
357 
358 void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
359 {
360     if (nIndex<0 || nIndex>=maItems.size())
361         throw RuntimeException();
362     else
363     {
364         maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
365         Layout();
366     }
367 }
368 
369 
370 
371 
372 void TabBar::RestoreHideFlags (void)
373 {
374     bool bNeedsLayout (false);
375     for(ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
376         iItem!=iEnd;
377         ++iItem)
378     {
379         if (iItem->mbIsHidden != iItem->mbIsHiddenByDefault)
380         {
381             iItem->mbIsHidden = iItem->mbIsHiddenByDefault;
382             bNeedsLayout = true;
383         }
384     }
385     if (bNeedsLayout)
386         Layout();
387 }
388 
389 
390 
391 
392 IMPL_LINK(TabBar, OnToolboxClicked, void*, pToolBox)
393 {
394     //    mpMenuButton->EndSelection();
395     maPopupMenuProvider(
396         Rectangle(
397             mpMenuButton->GetPosPixel(),
398             mpMenuButton->GetSizePixel()));
399 
400     return 0;
401 }
402 
403 
404 
405 } } // end of namespace sfx2::sidebar
406