File indexing completed on 2024-04-28 05:50:56
0001 /* 0002 SPDX-FileCopyrightText: 2006-2008 Robert Knight <robertknight@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef VIEWSPLITTER_H 0008 #define VIEWSPLITTER_H 0009 0010 // Qt 0011 #include <QSplitter> 0012 #include <QSplitterHandle> 0013 0014 // Konsole 0015 #include "konsoleprivate_export.h" 0016 0017 class QDragMoveEvent; 0018 class QDragEnterEvent; 0019 class QDropEvent; 0020 class QDragLeaveEvent; 0021 0022 namespace Konsole 0023 { 0024 class TerminalDisplay; 0025 0026 class ViewSplitterHandle : public QSplitterHandle 0027 { 0028 Q_OBJECT 0029 public: 0030 ViewSplitterHandle(Qt::Orientation orientation, QSplitter *parent); 0031 0032 protected: 0033 void mousePressEvent(QMouseEvent *ev) override; 0034 void mouseReleaseEvent(QMouseEvent *ev) override; 0035 void mouseMoveEvent(QMouseEvent *ev) override; 0036 void mouseDoubleClickEvent(QMouseEvent *ev) override; 0037 0038 private: 0039 /* For some reason, the first time we double-click on the splitter handle 0040 * the second mouse press event is not fired, nor is the double click event. 0041 * We use this counter to detect a double click. */ 0042 int mouseReleaseEventCounter; 0043 }; 0044 0045 /** 0046 * A splitter which holds a number of ViewContainer objects and allows 0047 * the user to control the size of each view container by dragging a splitter 0048 * bar between them. 0049 * 0050 * Each splitter can also contain child ViewSplitter widgets, allowing 0051 * for a hierarchy of view splitters and containers. 0052 * 0053 * The addContainer() method is used to split the existing view and 0054 * insert a new view container. 0055 * Containers can only be removed from the hierarchy by deleting them. 0056 */ 0057 class KONSOLEPRIVATE_EXPORT ViewSplitter : public QSplitter 0058 { 0059 Q_OBJECT 0060 0061 public: 0062 explicit ViewSplitter(QWidget *parent = nullptr); 0063 0064 enum class AddBehavior { 0065 AddBefore, 0066 AddAfter, 0067 }; 0068 /** 0069 * Locates the child ViewSplitter widget which currently has the focus 0070 * and inserts the container into it. 0071 * 0072 * @param terminalDisplay The container to insert 0073 * @param containerOrientation Specifies whether the view should be split 0074 * horizontally or vertically. If the orientation 0075 * is the same as the ViewSplitter into which the 0076 * container is to be inserted, or if the splitter 0077 * has fewer than two child widgets then the container 0078 * will be added to that splitter. If the orientation 0079 * is different, then a new child splitter 0080 * will be created, into which the container will 0081 * be inserted. 0082 * @param behavior Specifies whether to add new terminal after current 0083 * tab or at end. 0084 */ 0085 void addTerminalDisplay(TerminalDisplay *terminalDisplay, Qt::Orientation containerOrientation, AddBehavior behavior = AddBehavior::AddAfter); 0086 0087 void addTerminalDisplay(TerminalDisplay *terminalDisplay, int index = -1); 0088 0089 void addSplitter(ViewSplitter *splitter, int index = -1); 0090 0091 /** Returns the child ViewSplitter widget which currently has the focus */ 0092 ViewSplitter *activeSplitter(); 0093 0094 /** 0095 * Returns the container which currently has the focus or 0 if none 0096 * of the immediate child containers have the focus. This does not 0097 * search through child splitters. activeSplitter() can be used 0098 * to search recursively through child splitters for the splitter 0099 * which currently has the focus. 0100 * 0101 * To find the currently active container, use 0102 * mySplitter->activeSplitter()->activeTerminalDisplay() where 0103 * mySplitter is the ViewSplitter widget at the top of the hierarchy. 0104 */ 0105 TerminalDisplay *activeTerminalDisplay() const; 0106 0107 /** Makes the current TerminalDisplay expanded to 100% of the view 0108 */ 0109 void toggleMaximizeCurrentTerminal(); 0110 0111 /** Makes the current TerminalDisplay expanded to 100% of the view, while 0112 * scaling the font size 0113 */ 0114 void toggleZoomMaximizeCurrentTerminal(); 0115 0116 /** 0117 * Can be called on any ViewSplitter to find the top level splitter and ensure 0118 * the active display isn't maximized. Do nothing if it's not maximized. 0119 * 0120 * Useful for ViewManager and TabbedViewContainer when removing or adding a 0121 * display to the hierarchy so that the layout is reflowed correctly. 0122 */ 0123 void clearMaximized(); 0124 0125 /** returns the splitter that has no splitter as a parent. */ 0126 ViewSplitter *getToplevelSplitter(); 0127 0128 ViewSplitter *getChildSplitter(int id); 0129 0130 QString getChildWidgetsLayout(); 0131 0132 /** 0133 * Changes the size of the specified @p container by a given @p percentage. 0134 * @p percentage may be positive ( in which case the size of the container 0135 * is increased ) or negative ( in which case the size of the container 0136 * is decreased ). 0137 * 0138 * The sizes of the remaining containers are increased or decreased 0139 * uniformly to maintain the width of the splitter. 0140 */ 0141 void adjustActiveTerminalDisplaySize(int percentage); 0142 0143 void focusUp(); 0144 void focusDown(); 0145 void focusLeft(); 0146 void focusRight(); 0147 0148 void handleFocusDirection(Qt::Orientation orientation, int direction); 0149 0150 void childEvent(QChildEvent *event) override; 0151 bool terminalMaximized() const 0152 { 0153 return m_terminalMaximized; 0154 } 0155 0156 QSplitterHandle *createHandle() override; 0157 0158 QPoint mapToTopLevel(const QPoint &p); 0159 QPoint mapFromTopLevel(const QPoint &p); 0160 0161 int id() const 0162 { 0163 return _id; 0164 } 0165 0166 protected: 0167 void dragEnterEvent(QDragEnterEvent *ev) override; 0168 void dragMoveEvent(QDragMoveEvent *ev) override; 0169 void dragLeaveEvent(QDragLeaveEvent *event) override; 0170 void dropEvent(QDropEvent *ev) override; 0171 void showEvent(QShowEvent *) override; 0172 0173 Q_SIGNALS: 0174 void terminalDisplayDropped(TerminalDisplay *terminalDisplay); 0175 0176 private: 0177 /** recursively walks the object tree looking for Splitters and 0178 * TerminalDisplays, hiding the ones that should be hidden. 0179 * If a terminal display is not hidden in a subtree, we cannot 0180 * hide the whole tree. 0181 * 0182 * @p currentTerminalDisplay the only terminal display that will still be visible. 0183 */ 0184 bool hideRecurse(TerminalDisplay *currentTerminalDisplay); 0185 0186 /** other classes should use clearmMaximized() */ 0187 void handleMinimizeMaximize(bool maximize, bool zoom); 0188 0189 void updateSizes(); 0190 bool m_terminalMaximized = false; 0191 qreal fontSizeBeforeMaximization = 0; 0192 bool m_blockPropagatedDeletion = false; 0193 0194 int _id; 0195 0196 static bool m_drawTopLevelHandler; 0197 static Qt::Orientation m_topLevelHandlerDrawnOrientation; 0198 static int lastSplitterId; 0199 }; 0200 } 0201 #endif // VIEWSPLITTER_H