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