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