xref: /trunk/main/sfx2/source/sidebar/TabBar.cxx (revision 7a32b0c8)
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 "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 <vcl/wrkwin.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/componentcontext.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 
48 namespace sfx2 { namespace sidebar {
49 
50 TabBar::TabBar (
51     Window* pParentWindow,
52     const Reference<frame::XFrame>& rxFrame,
53     const ::boost::function<void(const ::rtl::OUString&)>& rDeckActivationFunctor,
54     const PopupMenuProvider& rPopupMenuProvider)
55     : Window(pParentWindow),
56       mxFrame(rxFrame),
57       mpMenuButton(ControlFactory::CreateMenuButton(this)),
58       maItems(),
59       maDeckActivationFunctor(rDeckActivationFunctor),
60       maPopupMenuProvider(rPopupMenuProvider)
61 {
62     SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
63 
64     mpMenuButton->SetModeImage(
65         Theme::GetImage(Theme::Image_TabBarMenu),
66         Theme::IsHighContrastMode()
67             ? BMP_COLOR_HIGHCONTRAST
68             : BMP_COLOR_NORMAL);
69     mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
70     Layout();
71 
72 #ifdef DEBUG
73     SetText(A2S("TabBar"));
74 #endif
75 }
76 
77 
78 
79 
80 TabBar::~TabBar (void)
81 {
82 }
83 
84 
85 
86 
87 void TabBar::Paint (const Rectangle& rUpdateArea)
88 {
89     Window::Paint(rUpdateArea);
90 
91     const sal_Int32 nHorizontalPadding (Theme::GetInteger(Theme::Int_TabMenuSeparatorPadding));
92     SetLineColor(Theme::GetColor(Theme::Color_TabMenuSeparator));
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     return Theme::GetInteger(Theme::Int_TabItemWidth)
104         + Theme::GetInteger(Theme::Int_TabBarLeftPadding)
105         + Theme::GetInteger(Theme::Int_TabBarRightPadding);
106 }
107 
108 
109 
110 
111 void TabBar::SetDecks (
112     const ResourceManager::IdContainer& rDeckIds)
113 {
114     // Remove the current buttons.
115     {
116         for(ItemContainer::iterator
117                 iItem(maItems.begin()), iEnd(maItems.end());
118             iItem!=iEnd;
119             ++iItem)
120         {
121             iItem->mpButton.reset();
122         }
123         maItems.clear();
124     }
125 
126     maItems.resize(rDeckIds.size());
127     sal_Int32 nIndex (0);
128     for (ResourceManager::IdContainer::const_iterator
129              iDeckId(rDeckIds.begin()),
130              iEnd(rDeckIds.end());
131          iDeckId!=iEnd;
132          ++iDeckId)
133     {
134         const DeckDescriptor* pDescriptor = ResourceManager::Instance().GetDeckDescriptor(*iDeckId);
135         if (pDescriptor == NULL)
136         {
137             OSL_ASSERT(pDescriptor!=NULL);
138             continue;
139         }
140 
141         Item& rItem (maItems[nIndex++]);
142         rItem.msDeckId = pDescriptor->msId;
143         rItem.mpButton.reset(CreateTabItem(*pDescriptor));
144         rItem.mpButton->SetClickHdl(LINK(&rItem, TabBar::Item, HandleClick));
145         rItem.maDeckActivationFunctor = maDeckActivationFunctor;
146         rItem.mbIsHiddenByDefault = false;
147         rItem.mbIsHidden = ! pDescriptor->mbIsEnabled;
148     }
149 
150     UpdateButtonIcons();
151     Layout();
152 }
153 
154 
155 
156 
157 void TabBar::UpdateButtonIcons (void)
158 {
159     const BmpColorMode eColorMode (
160         Theme::IsHighContrastMode()
161             ? BMP_COLOR_HIGHCONTRAST
162             : BMP_COLOR_NORMAL);
163 
164     mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_TabBarMenu), eColorMode);
165 
166     for(ItemContainer::const_iterator
167             iItem(maItems.begin()), iEnd(maItems.end());
168         iItem!=iEnd;
169         ++iItem)
170     {
171         const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
172         if (pDeckDescriptor != NULL)
173             iItem->mpButton->SetModeImage(
174                 GetItemImage(*pDeckDescriptor),
175                 eColorMode);
176     }
177 
178     Invalidate();
179 }
180 
181 
182 
183 
184 void TabBar::Layout (void)
185 {
186     const SvBorder aPadding (
187         Theme::GetInteger(Theme::Int_TabBarLeftPadding),
188         Theme::GetInteger(Theme::Int_TabBarTopPadding),
189         Theme::GetInteger(Theme::Int_TabBarRightPadding),
190         Theme::GetInteger(Theme::Int_TabBarBottomPadding));
191     sal_Int32 nX (aPadding.Top());
192     sal_Int32 nY (aPadding.Left());
193     const Size aTabItemSize (
194         Theme::GetInteger(Theme::Int_TabItemWidth),
195         Theme::GetInteger(Theme::Int_TabItemHeight));
196 
197     // Place the menu button and the separator.
198     if (mpMenuButton != NULL)
199     {
200         mpMenuButton->SetPosSizePixel(
201             Point(nX,nY),
202             aTabItemSize);
203         mpMenuButton->Show();
204         nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetInteger(Theme::Int_TabMenuPadding);
205         mnMenuSeparatorY = nY - Theme::GetInteger(Theme::Int_TabMenuPadding)/2 - 1;
206     }
207 
208     // Place the deck selection buttons.
209     for(ItemContainer::const_iterator
210             iItem(maItems.begin()), iEnd(maItems.end());
211         iItem!=iEnd;
212         ++iItem)
213     {
214         Button& rButton (*iItem->mpButton);
215         rButton.Show( ! iItem->mbIsHidden);
216 
217         if (iItem->mbIsHidden)
218             continue;
219 
220         // Place and size the icon.
221         rButton.SetPosSizePixel(
222             Point(nX,nY),
223             aTabItemSize);
224         rButton.Show();
225 
226         nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
227     }
228     Invalidate();
229 }
230 
231 
232 
233 
234 void TabBar::HighlightDeck (const ::rtl::OUString& rsDeckId)
235 {
236     for (ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
237          iItem!=iEnd;
238          ++iItem)
239     {
240         if (iItem->msDeckId.equals(rsDeckId))
241         {
242             iItem->mpButton->Check();
243             break;
244         }
245     }
246 }
247 
248 
249 
250 
251 void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
252 {
253     SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
254     UpdateButtonIcons();
255 
256     Window::DataChanged(rDataChangedEvent);
257 }
258 
259 
260 
261 
262 RadioButton* TabBar::CreateTabItem (const DeckDescriptor& rDeckDescriptor)
263 {
264     RadioButton* pItem = ControlFactory::CreateTabItem(this);
265     pItem->SetHelpText(rDeckDescriptor.msHelpText);
266     pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
267 
268     return pItem;
269 }
270 
271 
272 
273 Image TabBar::GetItemImage (const DeckDescriptor& rDeckDescriptor) const
274 {
275     return Tools::GetImage(
276         rDeckDescriptor.msIconURL,
277         rDeckDescriptor.msHighContrastIconURL,
278         mxFrame);
279 }
280 
281 
282 
283 
284 
285 IMPL_LINK(TabBar::Item, HandleClick, Button*, EMPTYARG)
286 {
287     maDeckActivationFunctor(msDeckId);
288     return 1;
289 }
290 
291 
292 
293 
294 const ::rtl::OUString TabBar::GetDeckIdForIndex (const sal_Int32 nIndex) const
295 {
296     if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
297         throw RuntimeException();
298     else
299         return maItems[nIndex].msDeckId;
300 }
301 
302 
303 
304 
305 void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
306 {
307     if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
308         throw RuntimeException();
309     else
310     {
311         maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
312         ResourceManager::Instance().SetIsDeckEnabled(
313             maItems[nIndex].msDeckId,
314             maItems[nIndex].mbIsHidden);
315         Layout();
316     }
317 }
318 
319 
320 
321 
322 void TabBar::RestoreHideFlags (void)
323 {
324     bool bNeedsLayout (false);
325     for(ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
326         iItem!=iEnd;
327         ++iItem)
328     {
329         if (iItem->mbIsHidden != iItem->mbIsHiddenByDefault)
330         {
331             iItem->mbIsHidden = iItem->mbIsHiddenByDefault;
332             bNeedsLayout = true;
333         }
334     }
335     if (bNeedsLayout)
336         Layout();
337 }
338 
339 
340 
341 
342 IMPL_LINK(TabBar, OnToolboxClicked, void*, EMPTYARG)
343 {
344     ::std::vector<DeckMenuData> aSelectionData;
345     ::std::vector<DeckMenuData> aShowData;
346 
347     for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
348         iItem!=iEnd;
349         ++iItem)
350     {
351         const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
352         if (pDeckDescriptor != NULL)
353         {
354             if ( ! iItem->mbIsHidden)
355                 aSelectionData.push_back(
356                     DeckMenuData(
357                         pDeckDescriptor->msTitle,
358                         pDeckDescriptor->msId,
359                         iItem->mpButton->IsChecked()));
360 
361             aShowData.push_back(
362                 DeckMenuData(
363                     pDeckDescriptor->msTitle,
364                     pDeckDescriptor->msId,
365                     !iItem->mbIsHidden));
366         }
367     }
368 
369     maPopupMenuProvider(
370         Rectangle(
371             mpMenuButton->GetPosPixel(),
372             mpMenuButton->GetSizePixel()),
373         aSelectionData,
374         aShowData);
375 
376     return 0;
377 }
378 
379 
380 
381 } } // end of namespace sfx2::sidebar
382