Line data Source code
1 : /** 2 : Copyright (c) 2023-2024 Stappler LLC <admin@stappler.dev> 3 : 4 : Permission is hereby granted, free of charge, to any person obtaining a copy 5 : of this software and associated documentation files (the "Software"), to deal 6 : in the Software without restriction, including without limitation the rights 7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 : copies of the Software, and to permit persons to whom the Software is 9 : furnished to do so, subject to the following conditions: 10 : 11 : The above copyright notice and this permission notice shall be included in 12 : all copies or substantial portions of the Software. 13 : 14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 : THE SOFTWARE. 21 : **/ 22 : 23 : #include "MaterialDecoratedLayout.h" 24 : #include "XLDirector.h" 25 : #include "XLView.h" 26 : 27 : namespace STAPPLER_VERSIONIZED stappler::xenolith::material2d { 28 : 29 52 : bool DecoratedLayout::init(ColorRole role) { 30 52 : if (!SceneLayout2d::init()) { 31 0 : return false; 32 : } 33 : 34 52 : _decorationMask = DecorationMask::All; 35 : 36 52 : _decorationRoot = addChild(Rc<Node>::create(), ZOrderMax); 37 : 38 52 : _decorationTop = _decorationRoot->addChild(Rc<LayerSurface>::create(SurfaceStyle(role, NodeStyle::Filled))); 39 52 : _decorationTop->setAnchorPoint(Anchor::TopLeft); 40 52 : _decorationTop->setVisible(false); 41 52 : _decorationTop->setStyleDirtyCallback([this] (const SurfaceStyleData &style) { 42 412 : updateStatusBar(style); 43 412 : }); 44 : 45 52 : _decorationBottom = _decorationRoot->addChild(Rc<LayerSurface>::create(SurfaceStyle(role, NodeStyle::Filled))); 46 52 : _decorationBottom->setAnchorPoint(Anchor::BottomLeft); 47 52 : _decorationBottom->setVisible(false); 48 : 49 52 : _decorationLeft = _decorationRoot->addChild(Rc<LayerSurface>::create(SurfaceStyle(role, NodeStyle::Filled))); 50 52 : _decorationLeft->setAnchorPoint(Anchor::BottomLeft); 51 52 : _decorationLeft->setVisible(false); 52 : 53 52 : _decorationRight = _decorationRoot->addChild(Rc<LayerSurface>::create(SurfaceStyle(role, NodeStyle::Filled))); 54 52 : _decorationRight->setAnchorPoint(Anchor::BottomRight); 55 52 : _decorationRight->setVisible(false); 56 : 57 52 : _background = addChild(Rc<LayerSurface>::create(SurfaceStyle(ColorRole::Background, NodeStyle::SurfaceTonal)), ZOrderMin); 58 52 : _background->setStyleDirtyCallback([this] (const SurfaceStyleData &data) { 59 412 : if (data.shadowValue > 0.0f) { 60 0 : setDepthIndex(data.shadowValue); 61 : } 62 412 : }); 63 52 : _background->setAnchorPoint(Anchor::Middle); 64 : 65 52 : return true; 66 : } 67 : 68 52 : void DecoratedLayout::onContentSizeDirty() { 69 52 : SceneLayout2d::onContentSizeDirty(); 70 : 71 52 : _decorationRoot->setContentSize(_contentSize); 72 52 : _decorationRoot->setDepthIndex(20.0f); 73 : 74 52 : if (_decorationPadding.left > 0.0f) { 75 52 : _decorationLeft->setPosition(Vec2::ZERO); 76 52 : _decorationLeft->setContentSize(Size2(_decorationPadding.left, _contentSize.height)); 77 52 : _decorationLeft->setVisible(true); 78 : } else { 79 0 : _decorationLeft->setVisible(false); 80 : } 81 : 82 52 : if (_decorationPadding.right > 0.0f) { 83 52 : _decorationRight->setPosition(Vec2(_contentSize.width, 0.0f)); 84 52 : _decorationRight->setContentSize(Size2(_decorationPadding.right, _contentSize.height)); 85 52 : _decorationRight->setVisible(true); 86 : } else { 87 0 : _decorationRight->setVisible(false); 88 : } 89 : 90 52 : if (_decorationPadding.top > 0.0f) { 91 52 : _decorationTop->setPosition(Vec2(_decorationPadding.left, _contentSize.height)); 92 52 : _decorationTop->setContentSize(Size2(_contentSize.width - _decorationPadding.horizontal(), _decorationPadding.top)); 93 52 : _decorationTop->setVisible(true); 94 : } else { 95 0 : _decorationTop->setVisible(false); 96 : } 97 : 98 52 : if (_decorationPadding.bottom > 0.0f) { 99 52 : _decorationBottom->setPosition(Vec2(_decorationPadding.left, 0.0f)); 100 52 : _decorationBottom->setContentSize(Size2(_contentSize.width - _decorationPadding.horizontal(), _decorationPadding.bottom)); 101 52 : _decorationBottom->setVisible(true); 102 : } else { 103 0 : _decorationBottom->setVisible(false); 104 : } 105 : 106 52 : _background->setPosition(_contentSize / 2.0f); 107 52 : _background->setContentSize(_contentSize); 108 : 109 52 : updateStatusBar(_decorationTop->getStyleCurrent()); 110 52 : } 111 : 112 9025 : bool DecoratedLayout::visitDraw(FrameInfo &info, NodeFlags parentFlags) { 113 9025 : if (!_visible) { 114 7368 : return false; 115 : } 116 : 117 1657 : auto maxDepth = getMaxDepthIndex(); 118 1657 : _decorationRoot->setDepthIndex(maxDepth); 119 : 120 1657 : return SceneLayout2d::visitDraw(info, parentFlags); 121 : } 122 : 123 0 : void DecoratedLayout::setDecorationColorRole(ColorRole role) { 124 0 : SurfaceStyle tmp; 125 : 126 0 : tmp = _decorationLeft->getStyleOrigin(); 127 0 : tmp.colorRole = role; 128 0 : _decorationLeft->setStyle(tmp); 129 0 : _decorationRight->setStyle(tmp); 130 0 : _decorationTop->setStyle(tmp); 131 0 : _decorationBottom->setStyle(tmp); 132 0 : } 133 : 134 0 : ColorRole DecoratedLayout::getDecorationColorRole() const { 135 0 : return _decorationLeft->getStyleTarget().colorRole; 136 : } 137 : 138 0 : void DecoratedLayout::setDecorationElevation(Elevation e) { 139 0 : SurfaceStyle tmp; 140 : 141 0 : tmp = _decorationLeft->getStyleOrigin(); 142 0 : tmp.elevation = e; 143 0 : _decorationLeft->setStyle(tmp); 144 0 : _decorationRight->setStyle(tmp); 145 0 : _decorationTop->setStyle(tmp); 146 0 : _decorationBottom->setStyle(tmp); 147 0 : } 148 : 149 0 : Elevation DecoratedLayout::getDecorationElevation() const { 150 0 : return _decorationLeft->getStyleTarget().elevation; 151 : } 152 : 153 52 : void DecoratedLayout::setViewDecorationFlags(ViewDecorationFlags value) { 154 52 : if (_viewDecoration != value) { 155 52 : _viewDecoration = value; 156 : } 157 52 : } 158 : 159 0 : ViewDecorationFlags DecoratedLayout::getViewDecorationFlags() const { 160 0 : return _viewDecoration; 161 : } 162 : 163 0 : void DecoratedLayout::onForeground(SceneContent2d *l, SceneLayout2d *overlay) { 164 0 : updateStatusBar(_decorationTop->getStyleCurrent()); 165 0 : } 166 : 167 464 : void DecoratedLayout::updateStatusBar(const SurfaceStyleData &style) { 168 464 : if (_director && (_viewDecoration & ViewDecorationFlags::Visible) != ViewDecorationFlags::None) { 169 464 : _director->getView()->setDecorationTone(style.colorOn.data.tone / 50.0f); 170 : } 171 464 : } 172 : 173 3314 : float DecoratedLayout::getMaxDepthIndex() const { 174 3314 : float maxIndex = _depthIndex; 175 46556 : for (auto &it : _children) { 176 43242 : if (it != _background && it != _decorationRoot) { 177 36614 : maxIndex = std::max(it->getMaxDepthIndex(), maxIndex); 178 : } 179 : } 180 3314 : return maxIndex; 181 : } 182 : 183 : }