PeriDyno 1.0.0
Loading...
Searching...
No Matches
TabToolbar.cpp
Go to the documentation of this file.
1/*
2 TabToolbar - a small utility library for Qt, providing tabbed toolbars
3 Copyright (C) 2018 Oleksii Sierov
4
5 TabToolbar is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TabToolbar is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with TabToolbar. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include <QPlainTextEdit>
19#include <QHBoxLayout>
20#include <QTabBar>
21#include <QVariant>
22#include <QToolButton>
23#include <QSignalBlocker>
24#include <QApplication>
25#include <QFrame>
26#include <QTimer>
27#include <QScreen>
28
29#include "TabToolbar.h"
30#include "Page.h"
31#include "Styles.h"
32#include "StyleTools.h"
33
34using namespace tt;
35
36TabToolbar::TabToolbar(QWidget* parent, unsigned _groupMaxHeight, unsigned _groupRowCount) :
37 QToolBar(parent),
38 groupRowCount(_groupRowCount),
39 groupMaxHeight(_groupMaxHeight)
40{
41 setObjectName("TabToolbar");
42 tempShowTimer.setSingleShot(true);
43 tempShowTimer.setInterval(QApplication::doubleClickInterval());
44
45 setProperty("TabToolbar", QVariant(true));
46 layout()->setContentsMargins(0, 0, 0, 0);
47 layout()->setSpacing(0);
48 setContentsMargins(0, 0, 0, 0);
49 setFloatable(false);
50 setMovable(false);
51 setAllowedAreas(Qt::TopToolBarArea);
52 tabBar = new QTabWidget(this);
53 tabBar->setProperty("TTWidget", QVariant(true));
54 tabBar->tabBar()->setProperty("TTTab", QVariant(true));
55
56 tabBarHandle = addWidget(tabBar);
57 tabBar->setUsesScrollButtons(true);
58
59 cornerActions = new QFrame(this);
60 cornerActions->setFrameShape(QFrame::NoFrame);
61 cornerActions->setLineWidth(0);
62 cornerActions->setContentsMargins(0, 0, 0, 0);
63 cornerActions->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
64 QHBoxLayout* cornerLayout = new QHBoxLayout(cornerActions);
65 cornerLayout->setContentsMargins(0, 0, 0, 0);
66 cornerLayout->setSpacing(0);
67 cornerLayout->setDirection(QBoxLayout::LeftToRight);
68 cornerActions->setLayout(cornerLayout);
69
70 hideAction = new QAction(this);
71 hideAction->setCheckable(true);
72 hideAction->setText("1");
73 hideButton = new QToolButton(tabBar);
74 hideButton->setProperty("TTHide", QVariant(true));
75 hideButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
76 hideButton->setDefaultAction(hideAction);
77 hideButton->setAutoRaise(true);
78 hideButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
79 QObject::connect(hideAction, &QAction::triggered, [this]()
80 {
81 tempShowTimer.start();
82 isMinimized = hideAction->isChecked();
83 hideAction->setText(isMinimized ? "2" : "1");
84 HideAt(tabBar->currentIndex());
85 if(isMinimized)
86 emit Minimized();
87 else
88 emit Maximized();
89 });
90 QObject::connect(tabBar, &QTabWidget::tabBarDoubleClicked, hideAction, &QAction::trigger);
91 QObject::connect(tabBar, &QTabWidget::tabBarClicked, this, &TabToolbar::TabClicked);
92 QObject::connect(tabBar, &QTabWidget::currentChanged, this, &TabToolbar::CurrentTabChanged);
93 QObject::connect((QApplication*)QApplication::instance(), &QApplication::focusChanged, this, &TabToolbar::FocusChanged);
94 cornerLayout->addWidget(hideButton);
95 tabBar->setCornerWidget(cornerActions);
96
97// SetStyle(GetDefaultStyle());
98}
99
103
105{
106// if(event->type() == QEvent::StyleChange && !ignoreStyleEvent)
107// QTimer::singleShot(0, this, [this]()
108// { // on KDE new palette is not ready yet, wait
109// const QString styleName = (style ? style->objectName() : GetDefaultStyle());
110// //SetStyle(styleName);
111// });
112 return QToolBar::event(event);
113}
114
115void TabToolbar::FocusChanged(QWidget* old, QWidget* now)
116{
117 (void)old;
118 if(now && now != this)
119 {
120 if(isMinimized && isShown)
121 {
122 QObject* parent = now;
123 do
124 {
125 parent = parent->parent();
126 if(parent == this)
127 return;
128 } while(parent);
129
131 }
132 }
133}
134
135unsigned TabToolbar::RowCount() const
136{
137 return groupRowCount;
138}
139
141{
142 return groupMaxHeight * GetScaleFactor(*this);
143}
144
145void TabToolbar::SetStyle(const QString& styleName)
146{
147 ignoreStyleEvent = true;
148 style.reset(CreateStyle(styleName).release());
149 setStyleSheet(GetSheetForStyle(*style));
150 ignoreStyleEvent = false;
151 emit StyleChanged();
152}
153
154QString TabToolbar::GetStyle() const
155{
156 if(style)
157 return style->objectName();
158 return "";
159}
160
161void TabToolbar::AddCornerAction(QAction* action)
162{
163 QToolButton* actionButton = new QToolButton(tabBar);
164 actionButton->setProperty("TTInternal", QVariant(true));
165 actionButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
166 actionButton->setDefaultAction(action);
167 actionButton->setAutoRaise(true);
168 actionButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
169 cornerActions->layout()->addWidget(actionButton);
170}
171
173{
174 hasSpecialTab = enabled;
175 tabBar->tabBar()->setProperty("TTSpecial", QVariant(enabled));
176 if(enabled && tabBar->count() > 0)
177 {
178 tabBar->setCurrentIndex(1);
179 }
180}
181
183{
184 return hideAction;
185}
186
188{
189 if(tempShowTimer.isActive() || (index == 0 && hasSpecialTab))
190 return;
191
192 if(isMinimized)
193 {
194 if(isShown && index != currentIndex)
195 return; //dont hide tab bar if just switching tabs
197 HideAt(index);
198 isMinimized = true;
199 }
200}
201
203{
204 QSignalBlocker blocker(tabBar);
205 if(index == 0 && hasSpecialTab)
206 {
207 tabBar->setCurrentIndex(currentIndex);
208 emit SpecialTabClicked();
209 }
210 else
211 {
212 currentIndex = index;
213 }
214}
215
217{
218 return currentIndex;
219}
220
222{
223 tabBar->setCurrentIndex(index);
224}
225
226void TabToolbar::HideAt(int index)
227{
228 if(isMinimized)
229 {
230 const int minHeight = tabBar->tabBar()->height() + 2;
231 tabBar->setMaximumHeight(minHeight);
232 tabBar->setMinimumHeight(minHeight);
233 setMaximumHeight(minHeight);
234 setMinimumHeight(minHeight);
235 isShown = false;
236 } else {
237 tabBar->setCurrentIndex(index);
238 if(!isShown)
239 {
240 tabBar->setMaximumHeight(maxHeight);
241 tabBar->setMinimumHeight(maxHeight);
242 setMaximumHeight(maxHeight);
243 setMinimumHeight(maxHeight);
244 tabBar->adjustSize();
245 }
246 setFocus();
247 isShown = true;
248 }
249}
250
251void TabToolbar::HideTab(int index)
252{
253 (void)index;
254 Page* page = static_cast<Page*>(sender());
255 QSignalBlocker blocker(page);
256 for(int i=0; i<tabBar->count(); i++)
257 {
258 if(tabBar->widget(i) == page)
259 {
260 tabBar->removeTab(i);
261 return;
262 }
263 }
264 currentIndex = tabBar->currentIndex();
265}
266
268{
269 QTimer::singleShot(0, this, [this, vSize]()
270 {
271 maxHeight = vSize + tabBar->tabBar()->height() + 6;
272 setMaximumHeight(maxHeight);
273 setMinimumHeight(maxHeight);
274 });
275}
276
277void TabToolbar::ShowTab(int index)
278{
279 Page* page = static_cast<Page*>(sender());
280 QSignalBlocker blocker(page);
281 tabBar->insertTab(index, page, page->objectName());
282 currentIndex = tabBar->currentIndex();
283}
284
285Page* TabToolbar::AddPage(const QString& pageName)
286{
287 Page* page = new Page(tabBar->count(), pageName);
288 QSignalBlocker blocker(page);
289 QObject::connect(page, &Page::Hiding, this, &TabToolbar::HideTab);
290 QObject::connect(page, &Page::Showing, this, &TabToolbar::ShowTab);
291 tabBar->addTab(page, pageName);
292 return page;
293}
294
295tt::Page* tt::TabToolbar::AddPage(const QIcon& icon, const QString &pageName)
296{
297 Page* page = new Page(tabBar->count(), pageName);
298 QSignalBlocker blocker(page);
299 QObject::connect(page, &Page::Hiding, this, &TabToolbar::HideTab);
300 QObject::connect(page, &Page::Showing, this, &TabToolbar::ShowTab);
301 tabBar->addTab(page, icon, pageName);
302 return page;
303}
304
305TabToolbar* tt::_FindTabToolbarParent(QWidget& startingWidget)
306{
307 QObject* par = &startingWidget;
308 do
309 {
310 par = par->parent();
311 if(auto* tt = dynamic_cast<TabToolbar*>(par))
312 return tt;
313 } while(par);
314
315 return nullptr;
316}
void Hiding(int index)
void Showing(int index)
void SetStyle(const QString &styleName)
TabToolbar(QWidget *parent=nullptr, unsigned _groupMaxHeight=75, unsigned _groupRowCount=3)
QAction * tabBarHandle
Definition TabToolbar.h:84
QTimer tempShowTimer
Definition TabToolbar.h:89
QAction * HideAction()
unsigned GroupMaxHeight() const
const unsigned groupMaxHeight
Definition TabToolbar.h:77
void ShowTab(int index)
const unsigned groupRowCount
Definition TabToolbar.h:76
void HideTab(int index)
void TabClicked(int index)
void CurrentTabChanged(int index)
QTabWidget * tabBar
Definition TabToolbar.h:85
void SetCurrentTab(int index)
void HideAt(int index=-1)
friend class Page
Definition TabToolbar.h:92
void StyleChanged()
bool event(QEvent *event) override
void SetSpecialTabEnabled(bool enabled)
unsigned maxHeight
Definition TabToolbar.h:80
int CurrentTab() const
Page * AddPage(const QString &pageName)
QToolButton * hideButton
Definition TabToolbar.h:83
virtual ~TabToolbar()
void FocusChanged(QWidget *old, QWidget *now)
QString GetStyle() const
unsigned RowCount() const
QAction * hideAction
Definition TabToolbar.h:82
QFrame * cornerActions
Definition TabToolbar.h:81
void SpecialTabClicked()
std::unique_ptr< StyleParams > style
Definition TabToolbar.h:90
void AdjustVerticalSize(unsigned vSize)
bool ignoreStyleEvent
Definition TabToolbar.h:86
void AddCornerAction(QAction *action)
Definition Builder.h:33
float GetScaleFactor(const QWidget &widget)
TabToolbar * _FindTabToolbarParent(QWidget &startingWidget)
QString GetSheetForStyle(const StyleParams &style)
std::unique_ptr< StyleParams > CreateStyle(const QString &styleName)