File indexing completed on 2024-11-10 04:57:21
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2022 Marco Martin <mart@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "quicktile.h" 0011 0012 namespace KWin 0013 { 0014 0015 QuickRootTile::QuickRootTile(TileManager *tiling, Tile *parentItem) 0016 : Tile(tiling, parentItem) 0017 { 0018 setPadding(0.0); 0019 setRelativeGeometry(QRectF(0, 0, 1, 1)); 0020 setQuickTileMode(QuickTileFlag::Maximize); 0021 0022 auto createTile = [this, &tiling](const QRectF &geometry, QuickTileMode tileMode) { 0023 Tile *tile = new Tile(tiling, this); 0024 tile->setPadding(0.0); 0025 tile->setQuickTileMode(tileMode); 0026 tile->setRelativeGeometry(geometry); 0027 0028 connect(tile, &Tile::relativeGeometryChanged, this, [this, tile]() { 0029 relayoutToFit(tile); 0030 }); 0031 0032 return std::unique_ptr<Tile>(tile); 0033 }; 0034 0035 m_leftVerticalTile = createTile(QRectF(0, 0, 0.5, 1), QuickTileFlag::Left); 0036 m_rightVerticalTile = createTile(QRectF(0.5, 0, 0.5, 1), QuickTileFlag::Right); 0037 m_topHorizontalTile = createTile(QRectF(0, 0, 1, 0.5), QuickTileFlag::Top); 0038 m_bottomHorizontalTile = createTile(QRectF(0, 0.5, 1, 0.5), QuickTileFlag::Bottom); 0039 0040 m_topLeftTile = createTile(QRectF(0, 0, 0.5, 0.5), QuickTileFlag::Top | QuickTileFlag::Left); 0041 m_topRightTile = createTile(QRectF(0.5, 0, 0.5, 0.5), QuickTileFlag::Top | QuickTileFlag::Right); 0042 m_bottomLeftTile = createTile(QRectF(0, 0.5, 0.5, 0.5), QuickTileFlag::Bottom | QuickTileFlag::Left); 0043 m_bottomRightTile = createTile(QRectF(0.5, 0.5, 0.5, 0.5), QuickTileFlag::Bottom | QuickTileFlag::Right); 0044 } 0045 0046 QuickRootTile::~QuickRootTile() 0047 { 0048 } 0049 0050 void QuickRootTile::relayoutToFit(Tile *tile) 0051 { 0052 if (m_resizedTile) { 0053 return; 0054 } 0055 0056 m_resizedTile = tile; 0057 0058 const QRectF geometry = tile->relativeGeometry(); 0059 0060 if (m_topHorizontalTile.get() == tile) { 0061 setVerticalSplit(geometry.bottom()); 0062 } else if (m_bottomHorizontalTile.get() == tile) { 0063 setVerticalSplit(geometry.top()); 0064 } else if (m_leftVerticalTile.get() == tile) { 0065 setHorizontalSplit(geometry.right()); 0066 } else if (m_rightVerticalTile.get() == tile) { 0067 setHorizontalSplit(geometry.left()); 0068 } else if (m_topLeftTile.get() == tile) { 0069 setHorizontalSplit(geometry.right()); 0070 setVerticalSplit(geometry.bottom()); 0071 } else if (m_topRightTile.get() == tile) { 0072 setHorizontalSplit(geometry.left()); 0073 setVerticalSplit(geometry.bottom()); 0074 } else if (m_bottomRightTile.get() == tile) { 0075 setHorizontalSplit(geometry.left()); 0076 setVerticalSplit(geometry.top()); 0077 } else if (m_bottomLeftTile.get() == tile) { 0078 setHorizontalSplit(geometry.right()); 0079 setVerticalSplit(geometry.top()); 0080 } 0081 0082 m_resizedTile = nullptr; 0083 } 0084 0085 Tile *QuickRootTile::tileForMode(QuickTileMode mode) 0086 { 0087 switch (mode) { 0088 case QuickTileMode(QuickTileFlag::Left): 0089 return m_leftVerticalTile.get(); 0090 case QuickTileMode(QuickTileFlag::Right): 0091 return m_rightVerticalTile.get(); 0092 case QuickTileMode(QuickTileFlag::Top): 0093 return m_topHorizontalTile.get(); 0094 case QuickTileMode(QuickTileFlag::Bottom): 0095 return m_bottomHorizontalTile.get(); 0096 case QuickTileMode(QuickTileFlag::Left | QuickTileFlag::Top): 0097 return m_topLeftTile.get(); 0098 case QuickTileMode(QuickTileFlag::Right | QuickTileFlag::Top): 0099 return m_topRightTile.get(); 0100 case QuickTileMode(QuickTileFlag::Left | QuickTileFlag::Bottom): 0101 return m_bottomLeftTile.get(); 0102 case QuickTileMode(QuickTileFlag::Right | QuickTileFlag::Bottom): 0103 return m_bottomRightTile.get(); 0104 case QuickTileMode(QuickTileFlag::Maximize): 0105 case QuickTileMode(QuickTileFlag::Horizontal): 0106 case QuickTileMode(QuickTileFlag::Vertical): 0107 return this; 0108 default: 0109 return nullptr; 0110 } 0111 } 0112 0113 Tile *QuickRootTile::tileForBorder(ElectricBorder border) 0114 { 0115 switch (border) { 0116 case ElectricTop: 0117 return m_topHorizontalTile.get(); 0118 case ElectricTopRight: 0119 return m_topRightTile.get(); 0120 case ElectricRight: 0121 return m_rightVerticalTile.get(); 0122 case ElectricBottomRight: 0123 return m_bottomRightTile.get(); 0124 case ElectricBottom: 0125 return m_bottomHorizontalTile.get(); 0126 case ElectricBottomLeft: 0127 return m_bottomLeftTile.get(); 0128 case ElectricLeft: 0129 return m_leftVerticalTile.get(); 0130 case ElectricTopLeft: 0131 return m_topLeftTile.get(); 0132 case ElectricNone: 0133 default: 0134 return nullptr; 0135 } 0136 } 0137 0138 qreal QuickRootTile::horizontalSplit() const 0139 { 0140 return m_leftVerticalTile->relativeGeometry().right(); 0141 } 0142 0143 void QuickRootTile::setHorizontalSplit(qreal split) 0144 { 0145 const QSizeF minSize = minimumSize(); // minimum size is the same for all tiles 0146 const qreal effectiveSplit = std::clamp(split, minSize.width(), 1.0 - minSize.width()); 0147 0148 auto geom = m_leftVerticalTile->relativeGeometry(); 0149 geom.setRight(effectiveSplit); 0150 m_leftVerticalTile->setRelativeGeometry(geom); 0151 0152 geom = m_rightVerticalTile->relativeGeometry(); 0153 geom.setLeft(effectiveSplit); 0154 m_rightVerticalTile->setRelativeGeometry(geom); 0155 0156 geom = m_topLeftTile->relativeGeometry(); 0157 geom.setRight(effectiveSplit); 0158 m_topLeftTile->setRelativeGeometry(geom); 0159 0160 geom = m_topRightTile->relativeGeometry(); 0161 geom.setLeft(effectiveSplit); 0162 m_topRightTile->setRelativeGeometry(geom); 0163 0164 geom = m_bottomLeftTile->relativeGeometry(); 0165 geom.setRight(effectiveSplit); 0166 m_bottomLeftTile->setRelativeGeometry(geom); 0167 0168 geom = m_bottomRightTile->relativeGeometry(); 0169 geom.setLeft(effectiveSplit); 0170 m_bottomRightTile->setRelativeGeometry(geom); 0171 } 0172 0173 qreal QuickRootTile::verticalSplit() const 0174 { 0175 return m_topHorizontalTile->relativeGeometry().bottom(); 0176 } 0177 0178 void QuickRootTile::setVerticalSplit(qreal split) 0179 { 0180 const QSizeF minSize = minimumSize(); // minimum size is the same for all tiles 0181 const qreal effectiveSplit = std::clamp(split, minSize.height(), 1.0 - minSize.height()); 0182 0183 auto geom = m_topHorizontalTile->relativeGeometry(); 0184 geom.setBottom(effectiveSplit); 0185 m_topHorizontalTile->setRelativeGeometry(geom); 0186 0187 geom = m_bottomHorizontalTile->relativeGeometry(); 0188 geom.setTop(effectiveSplit); 0189 m_bottomHorizontalTile->setRelativeGeometry(geom); 0190 0191 geom = m_topLeftTile->relativeGeometry(); 0192 geom.setBottom(effectiveSplit); 0193 m_topLeftTile->setRelativeGeometry(geom); 0194 0195 geom = m_topRightTile->relativeGeometry(); 0196 geom.setBottom(effectiveSplit); 0197 m_topRightTile->setRelativeGeometry(geom); 0198 0199 geom = m_bottomLeftTile->relativeGeometry(); 0200 geom.setTop(effectiveSplit); 0201 m_bottomLeftTile->setRelativeGeometry(geom); 0202 0203 geom = m_bottomRightTile->relativeGeometry(); 0204 geom.setTop(effectiveSplit); 0205 m_bottomRightTile->setRelativeGeometry(geom); 0206 } 0207 0208 } // namespace KWin 0209 0210 #include "moc_quicktile.cpp"