LCOV - code coverage report
Current view: top level - xenolith/renderer/material2d/components/menu - MaterialMenu.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 87 74.7 %
Date: 2024-05-12 00:16:13 Functions: 19 22 86.4 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2023 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 "MaterialMenu.h"
      24             : #include "MaterialMenuButton.h"
      25             : #include "MaterialMenuSeparator.h"
      26             : 
      27             : namespace STAPPLER_VERSIONIZED stappler::xenolith::material2d {
      28             : 
      29          40 : Menu::~Menu() { }
      30             : 
      31          20 : bool Menu::init() {
      32          20 :         if (!Surface::init(SurfaceStyle(
      33           0 :                         ShapeFamily::RoundedCorners,
      34           0 :                         ShapeStyle::ExtraSmall,
      35           0 :                         Elevation::Level2,
      36          40 :                         NodeStyle::SurfaceTonalElevated))) {
      37           0 :                 return false;
      38             :         }
      39             : 
      40          20 :         _menuListener = addComponent(Rc<DataListener<MenuSource>>::create([this] (SubscriptionFlags flags) {
      41          10 :                 handleSourceDirty();
      42          10 :         }));
      43             : 
      44          20 :         _scroll = addChild(Rc<ScrollView>::create(ScrollView::Vertical), ZOrder(1));
      45          20 :         _scroll->setAnchorPoint(Vec2(0, 1));
      46          20 :         _scroll->enableScissor(Padding(-2.0f));
      47             : 
      48          20 :         _controller = _scroll->setController(Rc<ScrollController>::create());
      49             : 
      50          20 :         return true;
      51             : }
      52             : 
      53          10 : bool Menu::init(MenuSource *source) {
      54          10 :         if (!init()) {
      55           0 :                 return false;
      56             :         }
      57             : 
      58          10 :         setMenuSource(source);
      59             : 
      60          10 :         return true;
      61             : }
      62             : 
      63          10 : void Menu::setMenuSource(MenuSource *source) {
      64          10 :         _menuListener->setSubscription(source);
      65          10 : }
      66             : 
      67          10 : MenuSource *Menu::getMenuSource() const {
      68          10 :         return _menuListener->getSubscription();
      69             : }
      70             : 
      71          20 : void Menu::setEnabled(bool value) {
      72          20 :         _scroll->setEnabled(value);
      73          20 :         auto nodes = _controller->getNodes();
      74          20 :         if (!nodes.empty()) {
      75           0 :                 for (auto it : nodes) {
      76           0 :                         if (auto button = dynamic_cast<MenuButton *>(it.get())) {
      77           0 :                                 button->setEnabled(value);
      78             :                         }
      79           0 :                 }
      80             :         }
      81          20 : }
      82             : 
      83           0 : bool Menu::isEnabled() const {
      84           0 :         return _scroll->isEnabled();
      85             : }
      86             : 
      87          10 : void Menu::rebuildMenu() {
      88          10 :         _controller->clear();
      89          10 :         if (!_menuListener->getSubscription()) {
      90           0 :                 return;
      91             :         }
      92             : 
      93          10 :         _controller->addPlaceholder(MenuLeadingHeight);
      94             : 
      95          10 :         auto &menuItems = _menuListener->getSubscription()->getItems();
      96          60 :         for (auto &item : menuItems) {
      97          50 :                 if (item->getType() == MenuSourceItem::Type::Separator) {
      98          10 :                         _controller->addItem([this, item] (const ScrollController::Item &) -> Rc<Node> {
      99          20 :                                 return createSeparator(this, item);
     100             :                         }, MenuVerticalPadding);
     101          40 :                 } else if (item->getType() == MenuSourceItem::Type::Button) {
     102          40 :                         _controller->addItem([this, item] (const ScrollController::Item &) -> Rc<Node> {
     103          80 :                                 return createButton(this, static_cast<MenuSourceButton *>(item.get()));
     104             :                         }, MenuItemHeight);
     105           0 :                 } else if (item->getType() == MenuSourceItem::Type::Custom) {
     106           0 :                         auto customItem = static_cast<MenuSourceCustom *>(item.get());
     107           0 :                         const auto &func = customItem->getFactoryFunction();
     108           0 :                         if (func) {
     109           0 :                                 float height = customItem->getHeight(this, _contentSize.width);
     110           0 :                                 _controller->addItem([this, func, item, customItem] (const ScrollController::Item &) -> Rc<Node> {
     111           0 :                                         return func(this, customItem);
     112             :                                 }, height);
     113             :                         }
     114             :                 }
     115             :         }
     116          10 :         _controller->addPlaceholder(MenuTrailingHeight);
     117          10 :         _scroll->setScrollDirty(true);
     118             : }
     119             : 
     120          40 : Rc<MenuButton> Menu::createButton(Menu *m, MenuSourceButton *btn) {
     121          40 :         return Rc<MenuButton>::create(m, btn);
     122             : }
     123             : 
     124          10 : Rc<MenuSeparator> Menu::createSeparator(Menu *m, MenuSourceItem *item) {
     125          10 :         return Rc<MenuSeparator>::create(m, item);
     126             : }
     127             : 
     128          10 : void Menu::onContentSizeDirty() {
     129          10 :         Surface::onContentSizeDirty();
     130          10 :         layoutSubviews();
     131          10 : }
     132             : 
     133          10 : void Menu::layoutSubviews() {
     134          10 :         auto &size = getContentSize();
     135          10 :         _scroll->setPosition(Vec2(0, size.height));
     136          10 :         _scroll->setContentSize(Size2(size.width, size.height));
     137          10 : }
     138             : 
     139          10 : void Menu::setMenuButtonCallback(const ButtonCallback &cb) {
     140          10 :         _callback = cb;
     141          10 : }
     142             : 
     143           0 : const Menu::ButtonCallback & Menu::getMenuButtonCallback() {
     144           0 :         return _callback;
     145             : }
     146             : 
     147          10 : void Menu::onMenuButtonPressed(MenuButton *button) {
     148          10 :         if (_callback) {
     149           0 :                 _callback(button);
     150             :         }
     151          10 : }
     152             : 
     153          10 : ScrollView *Menu::getScroll() const {
     154          10 :         return _scroll;
     155             : }
     156             : 
     157          10 : void Menu::handleSourceDirty() {
     158          10 :         _controller->clear();
     159          10 :         rebuildMenu();
     160          10 : }
     161             : 
     162             : }

Generated by: LCOV version 1.14