reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

tabbar.cpp (2712B)


      1 /* ReaPack: Package manager for REAPER
      2  * Copyright (C) 2015-2025  Christian Fillion
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU Lesser General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU Lesser General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Lesser General Public License
     15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16  */
     17 
     18 #include "tabbar.hpp"
     19 
     20 #include "dialog.hpp"
     21 #include "win32.hpp"
     22 
     23 #ifdef _WIN32
     24 #  include <commctrl.h>
     25 #endif
     26 
     27 TabBar::TabBar(HWND handle, Dialog *parent, const Tabs &tabs)
     28   : Control(handle), m_parent(parent), m_lastPage(-1)
     29 {
     30   for(const Tab &tab : tabs)
     31     addTab(tab);
     32 }
     33 
     34 int TabBar::addTab(const Tab &tab)
     35 {
     36   const int index = count();
     37 
     38   m_pages.push_back(tab.page);
     39 
     40   TCITEM item{};
     41   item.mask |= TCIF_TEXT;
     42   const auto &&wideText = Win32::widen(tab.text);
     43   item.pszText = const_cast<Win32::char_type *>(wideText.c_str());
     44 
     45   TabCtrl_InsertItem(handle(), index, &item);
     46 
     47   if(index == 0)
     48     switchPage();
     49 
     50   return index;
     51 }
     52 
     53 int TabBar::currentIndex() const
     54 {
     55   return TabCtrl_GetCurSel(handle());
     56 }
     57 
     58 void TabBar::setCurrentIndex(const int index)
     59 {
     60   if(index < 0 && index >= count())
     61     return;
     62 
     63   TabCtrl_SetCurSel(handle(), index);
     64   switchPage();
     65 }
     66 
     67 void TabBar::setFocus()
     68 {
     69   const int index = currentIndex();
     70 
     71   if(index > -1 && m_parent->hasFocus())
     72     SetFocus(m_pages[index].front());
     73 }
     74 
     75 int TabBar::count() const
     76 {
     77   return TabCtrl_GetItemCount(handle());
     78 }
     79 
     80 void TabBar::clear()
     81 {
     82   m_pages.clear();
     83   m_lastPage = -1;
     84 
     85 #ifdef TabCtrl_DeleteAllItems
     86   TabCtrl_DeleteAllItems(handle());
     87 #else
     88   for(int i = count(); i > 0; i--)
     89     TabCtrl_DeleteItem(handle(), i - 1);
     90 #endif
     91 }
     92 
     93 void TabBar::onNotify(LPNMHDR info, LPARAM)
     94 {
     95   switch(info->code) {
     96   case TCN_SELCHANGE:
     97     switchPage();
     98     break;
     99   };
    100 }
    101 
    102 void TabBar::switchPage()
    103 {
    104   InhibitControl block(m_parent->handle());
    105 
    106   if(m_lastPage > -1) {
    107     for(HWND control : m_pages[m_lastPage])
    108       ShowWindow(control, SW_HIDE);
    109   }
    110 
    111   const int index = currentIndex();
    112   onTabChange(index);
    113 
    114   if(index < 0 || static_cast<size_t>(index) >= m_pages.size()) {
    115     m_lastPage = -1;
    116     return;
    117   }
    118 
    119   const Page &page = m_pages[index];
    120   m_lastPage = index;
    121 
    122   if(page.empty())
    123     return;
    124 
    125   for(HWND control : page)
    126     ShowWindow(control, SW_SHOW);
    127 
    128   setFocus();
    129 }