File indexing completed on 2024-05-12 04:58:23
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2013-2014 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com> 0004 * Copyright (C) 2014-2018 David Rosca <nowrep@gmail.com> 0005 * 0006 * This program is free software: you can redistribute it and/or modify 0007 * it under the terms of the GNU General Public License as published by 0008 * the Free Software Foundation, either version 3 of the License, or 0009 * (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 * ============================================================ */ 0019 #ifndef COMBOTABBAR_H 0020 #define COMBOTABBAR_H 0021 0022 #include "qzcommon.h" 0023 #include "wheelhelper.h" 0024 0025 #include <QTabBar> 0026 #include <QScrollBar> 0027 #include <QAbstractButton> 0028 #include <QEasingCurve> 0029 #include <QStyleOption> 0030 0031 class QScrollArea; 0032 class QPropertyAnimation; 0033 class QHBoxLayout; 0034 0035 class TabBarScrollWidget; 0036 class TabBarHelper; 0037 class ToolButton; 0038 0039 class FALKON_EXPORT ComboTabBar : public QWidget 0040 { 0041 Q_OBJECT 0042 Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged) 0043 Q_PROPERTY(int count READ count) 0044 0045 public: 0046 enum SizeType { 0047 PinnedTabWidth, 0048 ActiveTabMinimumWidth, 0049 NormalTabMinimumWidth, 0050 NormalTabMaximumWidth, 0051 OverflowedTabWidth, 0052 ExtraReservedWidth 0053 }; 0054 0055 enum DropIndicatorPosition { 0056 BeforeTab, 0057 AfterTab 0058 }; 0059 0060 explicit ComboTabBar(QWidget* parent = nullptr); 0061 0062 int addTab(const QString &text); 0063 int addTab(const QIcon &icon, const QString &text); 0064 0065 int insertTab(int index, const QString &text); 0066 int insertTab(int index, const QIcon &icon, const QString &text, bool pinned = false); 0067 0068 void removeTab(int index); 0069 void moveTab(int from, int to); 0070 0071 bool isTabEnabled(int index) const; 0072 void setTabEnabled(int index, bool enabled); 0073 0074 QColor tabTextColor(int index) const; 0075 void setTabTextColor(int index, const QColor &color); 0076 0077 QRect tabRect(int index) const; 0078 QRect draggedTabRect() const; 0079 QPixmap tabPixmap(int index) const; 0080 0081 // Returns tab index at pos, or -1 0082 int tabAt(const QPoint &pos) const; 0083 0084 // Returns true if there is an empty area at pos 0085 // (returns false if there are buttons or other widgets on the pos) 0086 bool emptyArea(const QPoint &pos) const; 0087 0088 int mainTabBarCurrentIndex() const; 0089 int currentIndex() const; 0090 int count() const; 0091 0092 void setDrawBase(bool drawTheBase); 0093 bool drawBase() const; 0094 0095 Qt::TextElideMode elideMode() const; 0096 void setElideMode(Qt::TextElideMode elide); 0097 0098 QString tabText(int index) const; 0099 void setTabText(int index, const QString &text); 0100 0101 void setTabToolTip(int index, const QString &tip); 0102 QString tabToolTip(int index) const; 0103 0104 bool tabsClosable() const; 0105 void setTabsClosable(bool closable); 0106 0107 void setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget); 0108 QWidget* tabButton(int index, QTabBar::ButtonPosition position) const; 0109 0110 QTabBar::SelectionBehavior selectionBehaviorOnRemove() const; 0111 void setSelectionBehaviorOnRemove(QTabBar::SelectionBehavior behavior); 0112 0113 bool expanding() const; 0114 void setExpanding(bool enabled); 0115 0116 bool isMovable() const; 0117 void setMovable(bool movable); 0118 0119 bool documentMode() const; 0120 void setDocumentMode(bool set); 0121 0122 int pinnedTabsCount() const; 0123 int normalTabsCount() const; 0124 bool isPinned(int index) const; 0125 0126 void setFocusPolicy(Qt::FocusPolicy policy); 0127 void setObjectName(const QString &name); 0128 void setMouseTracking(bool enable); 0129 0130 void insertCloseButton(int index); 0131 void setCloseButtonsToolTip(const QString &tip); 0132 0133 QTabBar::ButtonPosition iconButtonPosition() const; 0134 QTabBar::ButtonPosition closeButtonPosition() const; 0135 0136 QSize iconButtonSize() const; 0137 QSize closeButtonSize() const; 0138 0139 bool validIndex(int index) const; 0140 void setCurrentNextEnabledIndex(int offset); 0141 0142 bool usesScrollButtons() const; 0143 void setUsesScrollButtons(bool useButtons); 0144 0145 void showDropIndicator(int index, DropIndicatorPosition position); 0146 void clearDropIndicator(); 0147 0148 bool isDragInProgress() const; 0149 bool isScrollInProgress() const; 0150 bool isMainBarOverflowed() const; 0151 0152 // Width of all widgets in the corner 0153 int cornerWidth(Qt::Corner corner) const; 0154 // Add widget to the left/right corner 0155 void addCornerWidget(QWidget* widget, Qt::Corner corner); 0156 0157 // Duration of tab slide animation when releasing dragged tab 0158 static int slideAnimationDuration(); 0159 0160 public Q_SLOTS: 0161 void setUpLayout(); 0162 void ensureVisible(int index = -1, int xmargin = -1); 0163 void setCurrentIndex(int index); 0164 0165 Q_SIGNALS: 0166 void overFlowChanged(bool overFlow); 0167 void currentChanged(int index); 0168 void tabCloseRequested(int index); 0169 void tabMoved(int from, int to); 0170 void scrollBarValueChanged(int value); 0171 0172 private Q_SLOTS: 0173 void setMinimumWidths(); 0174 void slotCurrentChanged(int index); 0175 void slotTabCloseRequested(int index); 0176 void slotTabMoved(int from, int to); 0177 void closeTabFromButton(); 0178 void updateTabBars(); 0179 void emitOverFlowChanged(); 0180 0181 protected: 0182 int mainTabBarWidth() const; 0183 int pinTabBarWidth() const; 0184 0185 bool event(QEvent *event) override; 0186 void wheelEvent(QWheelEvent* event) override; 0187 bool eventFilter(QObject* obj, QEvent* ev) override; 0188 void paintEvent(QPaintEvent* ev) override; 0189 0190 virtual int comboTabBarPixelMetric(SizeType sizeType) const; 0191 virtual QSize tabSizeHint(int index, bool fast = false) const; 0192 virtual void tabInserted(int index); 0193 virtual void tabRemoved(int index); 0194 0195 private: 0196 TabBarHelper* mainTabBar() const; 0197 TabBarHelper* localTabBar(int index = -1) const; 0198 0199 int toLocalIndex(int globalIndex) const; 0200 QRect mapFromLocalTabRect(const QRect &rect, QWidget *tabBar) const; 0201 void updatePinnedTabBarVisibility(); 0202 0203 QHBoxLayout* m_mainLayout; 0204 QHBoxLayout* m_leftLayout; 0205 QHBoxLayout* m_rightLayout; 0206 QWidget* m_leftContainer; 0207 QWidget* m_rightContainer; 0208 0209 TabBarHelper* m_mainTabBar; 0210 TabBarHelper* m_pinnedTabBar; 0211 0212 TabBarScrollWidget* m_mainTabBarWidget; 0213 TabBarScrollWidget* m_pinnedTabBarWidget; 0214 0215 QString m_closeButtonsToolTip; 0216 bool m_mainBarOverFlowed; 0217 bool m_lastAppliedOverflow; 0218 bool m_usesScrollButtons; 0219 bool m_blockCurrentChangedSignal; 0220 0221 WheelHelper m_wheelHelper; 0222 0223 friend class TabBarHelper; 0224 friend class TabStackedWidget; 0225 }; 0226 0227 class FALKON_EXPORT TabBarHelper : public QTabBar 0228 { 0229 Q_OBJECT 0230 Q_PROPERTY(int tabPadding READ tabPadding WRITE setTabPadding) 0231 Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor) 0232 0233 public: 0234 explicit TabBarHelper(bool isPinnedTabBar, ComboTabBar* comboTabBar); 0235 0236 int tabPadding() const; 0237 void setTabPadding(int padding); 0238 0239 QColor baseColor() const; 0240 void setBaseColor(const QColor &color); 0241 0242 void setTabButton(int index, QTabBar::ButtonPosition position, QWidget* widget); 0243 0244 QSize tabSizeHint(int index) const override; 0245 QSize baseClassTabSizeHint(int index) const; 0246 0247 QRect draggedTabRect() const; 0248 QPixmap tabPixmap(int index) const; 0249 0250 bool isActiveTabBar(); 0251 void setActiveTabBar(bool activate); 0252 0253 void removeTab(int index); 0254 0255 void setScrollArea(QScrollArea* scrollArea); 0256 void useFastTabSizeHint(bool enabled); 0257 0258 void showDropIndicator(int index, ComboTabBar::DropIndicatorPosition position); 0259 void clearDropIndicator(); 0260 0261 bool isDisplayedOnViewPort(int globalLeft, int globalRight); 0262 bool isDragInProgress() const; 0263 0264 static void initStyleBaseOption(QStyleOptionTabBarBase* optTabBase, QTabBar* tabbar, QSize size); 0265 0266 public Q_SLOTS: 0267 void setCurrentIndex(int index); 0268 0269 private: 0270 bool event(QEvent* ev) override; 0271 void paintEvent(QPaintEvent* event) override; 0272 void mousePressEvent(QMouseEvent* event) override; 0273 void mouseMoveEvent(QMouseEvent *event) override; 0274 void mouseReleaseEvent(QMouseEvent* event) override; 0275 0276 int dragOffset(QStyleOptionTab *option, int tabIndex) const; 0277 void initStyleOption(QStyleOptionTab* option, int tabIndex) const; 0278 0279 ComboTabBar* m_comboTabBar; 0280 QScrollArea* m_scrollArea; 0281 0282 int m_tabPadding = -1; 0283 QColor m_baseColor; 0284 int m_pressedIndex; 0285 bool m_dragInProgress; 0286 QPoint m_dragStartPosition; 0287 class QMovableTabWidget *m_movingTab = nullptr; 0288 bool m_activeTabBar; 0289 bool m_isPinnedTabBar; 0290 bool m_useFastTabSizeHint; 0291 int m_dropIndicatorIndex = -1; 0292 ComboTabBar::DropIndicatorPosition m_dropIndicatorPosition; 0293 }; 0294 0295 class FALKON_EXPORT TabScrollBar : public QScrollBar 0296 { 0297 Q_OBJECT 0298 public: 0299 explicit TabScrollBar(QWidget* parent = nullptr); 0300 ~TabScrollBar(); 0301 0302 bool isScrolling() const; 0303 0304 void animateToValue(int to, QEasingCurve::Type type = QEasingCurve::OutQuad); 0305 0306 private: 0307 QPropertyAnimation* m_animation; 0308 }; 0309 0310 0311 class FALKON_EXPORT TabBarScrollWidget : public QWidget 0312 { 0313 Q_OBJECT 0314 public: 0315 explicit TabBarScrollWidget(QTabBar* tabBar, QWidget* parent = nullptr); 0316 0317 QTabBar* tabBar(); 0318 QScrollArea* scrollArea(); 0319 TabScrollBar* scrollBar(); 0320 0321 void scrollByWheel(QWheelEvent* event); 0322 0323 int scrollButtonsWidth() const; 0324 bool usesScrollButtons() const; 0325 void setUsesScrollButtons(bool useButtons); 0326 0327 bool isOverflowed() const; 0328 int tabAt(const QPoint &pos) const; 0329 0330 public Q_SLOTS: 0331 void ensureVisible(int index = -1, int xmargin = 132); 0332 void scrollToLeft(int n = 5, QEasingCurve::Type type = QEasingCurve::OutQuad); 0333 void scrollToRight(int n = 5, QEasingCurve::Type type = QEasingCurve::OutQuad); 0334 void scrollToLeftEdge(); 0335 void scrollToRightEdge(); 0336 void setUpLayout(); 0337 0338 private Q_SLOTS: 0339 void overFlowChanged(bool overflowed); 0340 void scrollStart(); 0341 void updateScrollButtonsState(); 0342 0343 private: 0344 void mouseMoveEvent(QMouseEvent* event) override; 0345 void resizeEvent(QResizeEvent* event) override; 0346 0347 QTabBar* m_tabBar; 0348 QScrollArea* m_scrollArea; 0349 TabScrollBar* m_scrollBar; 0350 ToolButton* m_rightScrollButton; 0351 ToolButton* m_leftScrollButton; 0352 bool m_usesScrollButtons; 0353 int m_totalVerticalDeltas; 0354 }; 0355 0356 // Class for close button on tabs 0357 // * taken from qtabbar.cpp 0358 class CloseButton : public QAbstractButton 0359 { 0360 Q_OBJECT 0361 0362 public: 0363 CloseButton(QWidget *parent = nullptr); 0364 0365 QSize sizeHint() const override; 0366 0367 void enterEvent(QEnterEvent *event) override; 0368 void leaveEvent(QEvent *event) override; 0369 void paintEvent(QPaintEvent *event) override; 0370 }; 0371 #endif // COMBOTABBAR_H