text: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //
  // TGUI - Texus' Graphical User Interface
  // Copyright (C) 2012-2019 Bruno Van de Velde (vdv_b@tgui.eu)
  //
  // This software is provided 'as-is', without any express or implied warranty.
  // In no event will the authors be held liable for any damages arising from the use of this software.
  //
  // Permission is granted to anyone to use this software for any purpose,
  // including commercial applications, and to alter it and redistribute it freely,
  // subject to the following restrictions:
  //
  // 1. The origin of this software must not be misrepresented;
  //    you must not claim that you wrote the original software.
  //    If you use this software in a product, an acknowledgment
  //    in the product documentation would be appreciated but is not required.
  //
  // 2. Altered source versions must be plainly marked as such,
  //    and must not be misrepresented as being the original software.
  //
  // 3. This notice may not be removed or altered from any source distribution.
  //
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  
  #include <TGUI/Widgets/Panel.hpp>
  #include <TGUI/Clipping.hpp>
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  namespace tgui
  {
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      Panel::Panel(const Layout2d& size)
      {
          m_type = "Panel";
          m_isolatedFocus = true;
  
          m_renderer = aurora::makeCopied<PanelRenderer>();
          setRenderer(Theme::getDefault()->getRendererNoThrow(m_type));
  
          setSize(size);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      Panel::Ptr Panel::create(Layout2d size)
      {
          return std::make_shared<Panel>(size);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      Panel::Ptr Panel::copy(Panel::ConstPtr panel)
      {
          if (panel)
              return std::static_pointer_cast<Panel>(panel->clone());
          else
              return nullptr;
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      PanelRenderer* Panel::getSharedRenderer()
      {
          return aurora::downcast<PanelRenderer*>(Widget::getSharedRenderer());
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      const PanelRenderer* Panel::getSharedRenderer() const
      {
          return aurora::downcast<const PanelRenderer*>(Widget::getSharedRenderer());
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      PanelRenderer* Panel::getRenderer()
      {
          return aurora::downcast<PanelRenderer*>(Widget::getRenderer());
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      const PanelRenderer* Panel::getRenderer() const
      {
          return aurora::downcast<const PanelRenderer*>(Widget::getRenderer());
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      void Panel::setSize(const Layout2d& size)
      {
          m_bordersCached.updateParentSize(size.getValue());
  
          Group::setSize(size);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      Vector2f Panel::getInnerSize() const
      {
          return {getSize().x - m_bordersCached.getLeft() - m_bordersCached.getRight() - m_paddingCached.getLeft() - m_paddingCached.getRight(),
                  getSize().y - m_bordersCached.getTop() - m_bordersCached.getBottom() - m_paddingCached.getTop() - m_paddingCached.getBottom()};
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      Vector2f Panel::getChildWidgetsOffset() const
      {
          return {m_paddingCached.getLeft() + m_bordersCached.getLeft(),
                  m_paddingCached.getTop() + m_bordersCached.getTop()};
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      bool Panel::mouseOnWidget(Vector2f pos) const
      {
          return FloatRect{getPosition().x, getPosition().y, getSize().x, getSize().y}.contains(pos);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      void Panel::leftMousePressed(Vector2f pos)
      {
          m_mouseDown = true;
  
          onMousePress.emit(this, pos - getPosition());
  
          Container::leftMousePressed(pos);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      void Panel::leftMouseReleased(Vector2f pos)
      {
          onMouseRelease.emit(this, pos - getPosition());
  
          if (m_mouseDown)
              onClick.emit(this, pos - getPosition());
  
          m_mouseDown = false;
  
          Container::leftMouseReleased(pos);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      Signal& Panel::getSignal(std::string signalName)
      {
          if (signalName == toLower(onMousePress.getName()))
              return onMousePress;
          else if (signalName == toLower(onMouseRelease.getName()))
              return onMouseRelease;
          else if (signalName == toLower(onClick.getName()))
              return onClick;
          else
              return Group::getSignal(std::move(signalName));
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      void Panel::rendererChanged(const std::string& property)
      {
          if (property == "borders")
          {
              m_bordersCached = getSharedRenderer()->getBorders();
              setSize(m_size);
          }
          else if (property == "bordercolor")
          {
              m_borderColorCached = getSharedRenderer()->getBorderColor();
          }
          else if (property == "backgroundcolor")
          {
              m_backgroundColorCached = getSharedRenderer()->getBackgroundColor();
          }
          else
              Group::rendererChanged(property);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      void Panel::draw(sf::RenderTarget& target, sf::RenderStates states) const
      {
          states.transform.translate(getPosition());
  
          // Draw the borders
          if (m_bordersCached != Borders{0})
          {
              drawBorders(target, states, m_bordersCached, getSize(), m_borderColorCached);
              states.transform.translate({m_bordersCached.getLeft(), m_bordersCached.getTop()});
          }
  
          // Draw the background
          const Vector2f innerSize = {getSize().x - m_bordersCached.getLeft() - m_bordersCached.getRight(),
                                      getSize().y - m_bordersCached.getTop() - m_bordersCached.getBottom()};
          drawRectangleShape(target, states, innerSize, m_backgroundColorCached);
  
          states.transform.translate(m_paddingCached.getLeft(), m_paddingCached.getTop());
          const Vector2f contentSize = {innerSize.x - m_paddingCached.getLeft() - m_paddingCached.getRight(),
                                        innerSize.y - m_paddingCached.getTop() - m_paddingCached.getBottom()};
  
          // Draw the child widgets
          const Clipping clipping{target, states, {}, contentSize};
          drawWidgetContainer(&target, states);
      }
  
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  }
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  