Advertisement
Guest User

Untitled

a guest
Feb 24th, 2013
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 34.32 KB | None | 0 0
  1. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // TGUI - Texus's Graphical User Interface
  4. // Copyright (C) 2012 Bruno Van de Velde (vdv_b@tgui.eu)
  5. //
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it freely,
  11. // subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented;
  14. //    you must not claim that you wrote the original software.
  15. //    If you use this software in a product, an acknowledgment
  16. //    in the product documentation would be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such,
  19. //    and must not be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source distribution.
  22. //
  23. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  24.  
  25.  
  26. #include <TGUI/Objects.hpp>
  27. #include <TGUI/GroupObject.hpp>
  28. #include <TGUI/ClickableObject.hpp>
  29. #include <TGUI/Button.hpp>
  30. #include <TGUI/Panel.hpp>
  31. #include <TGUI/ChildWindow.hpp>
  32.  
  33. #include <SFML/OpenGL.hpp>
  34.  
  35. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  36.  
  37. namespace tgui
  38. {
  39.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  40.  
  41.     ChildWindow::ChildWindow() :
  42.     m_Title            (""),
  43.     m_TitleColor       (sf::Color(255,255,255)),
  44.     m_TitleBarHeight   (0),
  45.     m_LoadedPathname   (""),
  46.     m_SplitImage       (false),
  47.     m_Opacity          (255),
  48.     m_DistanceToSide   (5),
  49.     m_TitleAlignment   (TitleAlignmentCentered),
  50.     m_BorderColor      (0, 0, 0),
  51.     m_TextureTitleBar_L(NULL),
  52.     m_TextureTitleBar_M(NULL),
  53.     m_TextureTitleBar_R(NULL)
  54.     {
  55.         m_Callback.objectType = Type_ChildWindow;
  56.         m_CloseButton = new tgui::Button();
  57.     }
  58.  
  59.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  60.  
  61.     ChildWindow::ChildWindow(const ChildWindow& childWindowToCopy) :
  62.     GroupObject       (childWindowToCopy),
  63.     ObjectBorders     (childWindowToCopy),
  64.     m_Title           (childWindowToCopy.m_Title),
  65.     m_TitleBarHeight  (childWindowToCopy.m_TitleBarHeight),
  66.     m_LoadedPathname  (childWindowToCopy.m_LoadedPathname),
  67.     m_SplitImage      (childWindowToCopy.m_SplitImage),
  68.     m_DraggingPosition(childWindowToCopy.m_DraggingPosition),
  69.     m_Opacity         (childWindowToCopy.m_Opacity),
  70.     m_DistanceToSide  (childWindowToCopy.m_DistanceToSide),
  71.     m_TitleAlignment  (childWindowToCopy.m_TitleAlignment),
  72.     m_BorderColor     (childWindowToCopy.m_BorderColor)
  73.     {
  74.         // Copy the textures
  75.         if (TGUI_TextureManager.copyTexture(childWindowToCopy.m_TextureTitleBar_L, m_TextureTitleBar_L))   m_SpriteTitleBar_L.setTexture(*m_TextureTitleBar_L);
  76.         if (TGUI_TextureManager.copyTexture(childWindowToCopy.m_TextureTitleBar_M, m_TextureTitleBar_M))   m_SpriteTitleBar_M.setTexture(*m_TextureTitleBar_M);
  77.         if (TGUI_TextureManager.copyTexture(childWindowToCopy.m_TextureTitleBar_R, m_TextureTitleBar_R))   m_SpriteTitleBar_R.setTexture(*m_TextureTitleBar_R);
  78.  
  79.         // Copy the button
  80.         m_CloseButton = new tgui::Button(*childWindowToCopy.m_CloseButton);
  81.     }
  82.  
  83.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84.  
  85.     ChildWindow::~ChildWindow()
  86.     {
  87.         if (m_TextureTitleBar_L != NULL)   TGUI_TextureManager.removeTexture(m_TextureTitleBar_L);
  88.         if (m_TextureTitleBar_M != NULL)   TGUI_TextureManager.removeTexture(m_TextureTitleBar_M);
  89.         if (m_TextureTitleBar_R != NULL)   TGUI_TextureManager.removeTexture(m_TextureTitleBar_R);
  90.  
  91.         delete m_CloseButton;
  92.     }
  93.  
  94.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95.  
  96.     ChildWindow& ChildWindow::operator= (const ChildWindow& right)
  97.     {
  98.         // Make sure it is not the same object
  99.         if (this != &right)
  100.         {
  101.             ChildWindow temp(right);
  102.             this->GroupObject::operator=(right);
  103.             this->ObjectBorders::operator=(right);
  104.  
  105.             // Delete the old close button
  106.             delete m_CloseButton;
  107.  
  108.             std::swap(m_Title,             temp.m_Title);
  109.             std::swap(m_TitleBarHeight,    temp.m_TitleBarHeight);
  110.             std::swap(m_LoadedPathname,    temp.m_LoadedPathname);
  111.             std::swap(m_SplitImage,        temp.m_SplitImage);
  112.             std::swap(m_DraggingPosition,  temp.m_DraggingPosition);
  113.             std::swap(m_Opacity,           temp.m_Opacity);
  114.             std::swap(m_DistanceToSide,    temp.m_DistanceToSide);
  115.             std::swap(m_TitleAlignment,    temp.m_TitleAlignment);
  116.             std::swap(m_BorderColor,       temp.m_BorderColor);
  117.             std::swap(m_TextureTitleBar_L, temp.m_TextureTitleBar_L);
  118.             std::swap(m_TextureTitleBar_M, temp.m_TextureTitleBar_M);
  119.             std::swap(m_TextureTitleBar_R, temp.m_TextureTitleBar_R);
  120.             std::swap(m_SpriteTitleBar_L,  temp.m_SpriteTitleBar_L);
  121.             std::swap(m_SpriteTitleBar_M,  temp.m_SpriteTitleBar_M);
  122.             std::swap(m_SpriteTitleBar_R,  temp.m_SpriteTitleBar_R);
  123.             std::swap(m_CloseButton,       temp.m_CloseButton);
  124.         }
  125.  
  126.         return *this;
  127.     }
  128.  
  129.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  130.  
  131.     ChildWindow* ChildWindow::clone()
  132.     {
  133.         return new ChildWindow(*this);
  134.     }
  135.  
  136.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  137.  
  138.     bool ChildWindow::load(const std::string& pathname, float width, float height, const sf::Color& bkgColor)
  139.     {
  140.         // Until the loading succeeds, the child window will be marked as unloaded
  141.         m_Loaded = false;
  142.  
  143.         // Make sure that the pathname isn't empty
  144.         if (pathname.empty())
  145.             return false;
  146.  
  147.         // Set the background color of the child window
  148.         m_BackgroundColor = bkgColor;
  149.  
  150.         // Store the filename
  151.         m_LoadedPathname = pathname;
  152.  
  153.         // Set the size of the child window
  154.         m_Size.x = width;
  155.         m_Size.y = height;
  156.  
  157.         // When the pathname does not end with a "/" then we will add it
  158.         if (m_LoadedPathname[m_LoadedPathname.length()-1] != '/')
  159.             m_LoadedPathname.push_back('/');
  160.  
  161.         // Open the info file
  162.         InfoFileParser infoFile;
  163.         if (infoFile.openFile(m_LoadedPathname + "info.txt") == false)
  164.         {
  165.             TGUI_OUTPUT("TGUI error: Failed to open " + m_LoadedPathname + "info.txt");
  166.             return false;
  167.         }
  168.  
  169.         std::string property;
  170.         std::string value;
  171.  
  172.         // Set some default settings
  173.         m_SplitImage = false;
  174.         m_DistanceToSide = 5;
  175.         std::string imageExtension = "png";
  176.  
  177.         // Read untill the end of the file
  178.         while (infoFile.readProperty(property, value))
  179.         {
  180.             // Check what the property is
  181.             if (property.compare("splitimage") == 0)
  182.             {
  183.                 if ((value.compare("true") == 0) || (value.compare("1") == 0))
  184.                 {
  185.                     /// TODO: Support SplitImage
  186.                     TGUI_OUTPUT("TGUI fixme: SplitImage is not supported yet.");
  187. //                    m_SplitImage = true;
  188.                 }
  189.                 else
  190.                 {
  191.                     if ((value.compare("false") != 0) && (value.compare("0") != 0))
  192.                         TGUI_OUTPUT("TGUI warning: Wrong value passed to SplitImage: \"" + value + "\".");
  193.                 }
  194.             }
  195.             else if (property.compare("extension") == 0)
  196.             {
  197.                 imageExtension = value;
  198.             }
  199.             else if (property.compare("borders") == 0)
  200.             {
  201.                 // Get the borders
  202.                 Vector4u borders;
  203.                 if (extractVector4u(value, borders))
  204.                     setBorders(borders.x1, borders.x2, borders.x3, borders.x4);
  205.             }
  206.             else if (property.compare("distancetoside") == 0)
  207.             {
  208.                 m_DistanceToSide = atoi(value.c_str());
  209.             }
  210.         }
  211.  
  212.         // Close the info file
  213.         infoFile.closeFile();
  214.  
  215.         // Remove the textures when they were loaded before
  216.         if (m_TextureTitleBar_L != NULL)   TGUI_TextureManager.removeTexture(m_TextureTitleBar_L);
  217.         if (m_TextureTitleBar_M != NULL)   TGUI_TextureManager.removeTexture(m_TextureTitleBar_M);
  218.         if (m_TextureTitleBar_R != NULL)   TGUI_TextureManager.removeTexture(m_TextureTitleBar_R);
  219.  
  220.         // Check if the title bar image is split
  221.         if (m_SplitImage)
  222.         {
  223.             /// TODO: Support SplitImage
  224.             return false;
  225.         }
  226.         else // The title bar image isn't split
  227.         {
  228.             // Load the required texture
  229.             if ((TGUI_TextureManager.getTexture(m_LoadedPathname + "TitleBar." + imageExtension, m_TextureTitleBar_M)))
  230.             {
  231.                  m_SpriteTitleBar_M.setTexture(*m_TextureTitleBar_M, true);
  232.                  m_TitleBarHeight = m_TextureTitleBar_M->getSize().y;
  233.             }
  234.             else
  235.                 return false;
  236.  
  237.             // Load the close button
  238.             if (m_CloseButton->load(m_LoadedPathname + "/Close") == false)
  239.                 return false;
  240.         }
  241.  
  242.         // When there is no error we will return true
  243.         return m_Loaded = true;
  244.     }
  245.  
  246.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  247.  
  248.     void ChildWindow::setSize(float width, float height)
  249.     {
  250.         // A negative size is not allowed for this object
  251.         if (width  < 0) width  = -width;
  252.         if (height < 0) height = -height;
  253.  
  254.         // Set the size of the window
  255.         m_Size.x = width;
  256.         m_Size.y = height;
  257.  
  258.         // If there is a background texture then resize it
  259.         if (m_Texture)
  260.             m_Sprite.setScale(m_Size.x / m_Texture->getSize().x, m_Size.y / m_Texture->getSize().y);
  261.     }
  262.  
  263.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  264.  
  265.     Vector2f ChildWindow::getSize() const
  266.     {
  267.         return Vector2f(m_Size.x, m_Size.y);
  268.     }
  269.  
  270.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  271.  
  272.     std::string ChildWindow::getLoadedPathname() const
  273.     {
  274.         return m_LoadedPathname;
  275.     }
  276.  
  277.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  278.  
  279.     void ChildWindow::setBackgroundTexture(sf::Texture *const texture)
  280.     {
  281.         // Store the texture
  282.         m_Texture = texture;
  283.  
  284.         // Set the texture for the sprite
  285.         if (m_Texture)
  286.         {
  287.             m_Sprite.setTexture(*m_Texture, true);
  288.             m_Sprite.setScale(m_Size.x / m_Texture->getSize().x, m_Size.y / m_Texture->getSize().y);
  289.         }
  290.     }
  291.  
  292.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  293.  
  294.     sf::Texture* ChildWindow::getBackgroundTexture()
  295.     {
  296.         return m_Texture;
  297.     }
  298.  
  299.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  300.  
  301.     void ChildWindow::setTitlebarHeight(unsigned int height)
  302.     {
  303.         // Don't continue when the child window has not been loaded yet
  304.         if (m_Loaded == false)
  305.             return;
  306.  
  307.         // Remember the new title bar height
  308.         m_TitleBarHeight = height;
  309.  
  310.         // Set the size of the close button
  311.         m_CloseButton->setSize(static_cast<float>(height) / m_TextureTitleBar_M->getSize().y * m_CloseButton->getSize().x,
  312.                                static_cast<float>(height) / m_TextureTitleBar_M->getSize().y * m_CloseButton->getSize().y);
  313.     }
  314.  
  315.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  316.  
  317.     unsigned int ChildWindow::getTitleBarHeight() const
  318.     {
  319.         return m_TitleBarHeight;
  320.     }
  321.  
  322.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  323.  
  324.     void ChildWindow::setBackgroundColor(const sf::Color& backgroundColor)
  325.     {
  326.         m_BackgroundColor = backgroundColor;
  327.     }
  328.  
  329.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  330.  
  331.     const sf::Color& ChildWindow::getBackgroundColor() const
  332.     {
  333.         return m_BackgroundColor;
  334.     }
  335.  
  336.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  337.  
  338.     void ChildWindow::setTransparency(unsigned char transparency)
  339.     {
  340.         // Store the new transparency
  341.         m_Opacity = transparency;
  342.  
  343.         m_SpriteTitleBar_L.setColor(sf::Color(255, 255, 255, m_Opacity));
  344.         m_SpriteTitleBar_M.setColor(sf::Color(255, 255, 255, m_Opacity));
  345.         m_SpriteTitleBar_R.setColor(sf::Color(255, 255, 255, m_Opacity));
  346.  
  347.         m_CloseButton->m_SpriteNormal_L.setColor(sf::Color(255, 255, 255, m_Opacity));
  348.         m_CloseButton->m_SpriteNormal_M.setColor(sf::Color(255, 255, 255, m_Opacity));
  349.         m_CloseButton->m_SpriteNormal_R.setColor(sf::Color(255, 255, 255, m_Opacity));
  350.  
  351.         m_CloseButton->m_SpriteMouseHover_L.setColor(sf::Color(255, 255, 255, m_Opacity));
  352.         m_CloseButton->m_SpriteMouseHover_M.setColor(sf::Color(255, 255, 255, m_Opacity));
  353.         m_CloseButton->m_SpriteMouseHover_R.setColor(sf::Color(255, 255, 255, m_Opacity));
  354.  
  355.         m_CloseButton->m_SpriteMouseDown_L.setColor(sf::Color(255, 255, 255, m_Opacity));
  356.         m_CloseButton->m_SpriteMouseDown_M.setColor(sf::Color(255, 255, 255, m_Opacity));
  357.         m_CloseButton->m_SpriteMouseDown_R.setColor(sf::Color(255, 255, 255, m_Opacity));
  358.     }
  359.  
  360.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  361.  
  362.     unsigned char ChildWindow::getTransparency() const
  363.     {
  364.         return m_Opacity;
  365.     }
  366.  
  367.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  368.  
  369.     void ChildWindow::setTitle(const sf::String& title)
  370.     {
  371.         m_Title = title;
  372.     }
  373.  
  374.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  375.  
  376.     const sf::String& ChildWindow::getTitle() const
  377.     {
  378.         return m_Title;
  379.     }
  380.  
  381.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  382.  
  383.     void ChildWindow::setTitleColor(const sf::Color & titleColor)
  384.     {
  385.         m_TitleColor = titleColor;
  386.     }
  387.  
  388.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  389.  
  390.     const sf::Color& ChildWindow::getTitleColor() const
  391.     {
  392.         return m_TitleColor;
  393.     }
  394.    
  395.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  396.  
  397.     void ChildWindow::setBorderColor(const sf::Color& borderColor)
  398.     {
  399.         m_BorderColor = borderColor;
  400.     }
  401.  
  402.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  403.  
  404.     const sf::Color& ChildWindow::getBorderColor() const
  405.     {
  406.         return m_BorderColor;
  407.     }
  408.  
  409.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  410.  
  411.     void ChildWindow::setBorders(unsigned int leftBorder, unsigned int topBorder, unsigned int rightBorder, unsigned int bottomBorder)
  412.     {
  413.         // Set the new border size
  414.         m_LeftBorder   = leftBorder;
  415.         m_TopBorder    = topBorder;
  416.         m_RightBorder  = rightBorder;
  417.         m_BottomBorder = bottomBorder;
  418.     }
  419.  
  420.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  421.  
  422.     void ChildWindow::handleEvent(sf::Event& event, float mouseX, float mouseY)
  423.     {
  424.         // Don't continue when the child window has not been loaded yet
  425.         if (m_Loaded == false)
  426.             return;
  427.  
  428.         // Check if something has to be done differently with the event
  429.         if ((event.type == sf::Event::MouseMoved) || (event.type == sf::Event::MouseButtonPressed) || (event.type == sf::Event::MouseButtonReleased))
  430.         {
  431.             // Check if you are dragging the child window
  432.             if ((event.type == sf::Event::MouseMoved) && (m_MouseDown == true))
  433.             {
  434.                 // Move the child window
  435.                 Vector2f position = getPosition();
  436.                 setPosition(position.x + (mouseX - position.x - m_DraggingPosition.x), position.y + (mouseY - position.y - m_DraggingPosition.y));
  437.  
  438.                 // Add the callback (if the user requested it)
  439.                 if (m_CallbackFunctions[Moved].empty() == false)
  440.                 {
  441.                     m_Callback.trigger = Moved;
  442.                     m_Callback.position = getPosition();
  443.                     addCallback();
  444.                 }
  445.             }
  446.  
  447.             // Move the childwindow to the front when clicking on it
  448.             if (event.type == sf::Event::MouseButtonPressed)
  449.             {
  450.                 m_Parent->focusObject(this);
  451.                 m_Parent->moveObjectToFront(this);
  452.             }
  453.  
  454.             // Check if the mouse is on top of the title bar
  455.             if (getTransform().transformRect(sf::FloatRect(0, 0, m_Size.x + m_LeftBorder + m_RightBorder, static_cast<float>(m_TitleBarHeight))).contains(mouseX, mouseY))
  456.             {
  457.                 // Get the current position and scale
  458.                 Vector2f position = getPosition();
  459.                 Vector2f curScale = getScale();
  460.  
  461.                 // Temporary set the close button to the correct position
  462.                 m_CloseButton->setPosition(position.x + ((m_Size.x + m_LeftBorder + m_RightBorder - m_DistanceToSide - m_CloseButton->getSize().x) * curScale.x), position.y + ((m_TitleBarHeight / 2.f) - (m_CloseButton->getSize().x / 2.f)) * curScale.y);
  463.  
  464.                 // Set the scale of the close button
  465.                 m_CloseButton->setScale(curScale);
  466.  
  467.                 // Call the correct function of the button
  468.                 if (event.type == sf::Event::MouseMoved)
  469.                 {
  470.                     // Send the hover event to the close button
  471.                     if (m_CloseButton->mouseOnObject(mouseX, mouseY))
  472.                         m_CloseButton->mouseMoved(mouseX, mouseY);
  473.                 }
  474.                 else if (event.type == sf::Event::MouseButtonPressed)
  475.                 {
  476.                     // Send the mouse press event to the close button
  477.                     if (m_CloseButton->mouseOnObject(mouseX, mouseY))
  478.                         m_CloseButton->leftMousePressed(mouseX, mouseY);
  479.                     else
  480.                     {
  481.                         // The mouse went down on the title bar
  482.                         m_MouseDown = true;
  483.  
  484.                         // Remember where we are dragging the title bar
  485.                         m_DraggingPosition.x = mouseX - position.x;
  486.                         m_DraggingPosition.y = mouseY - position.y;
  487.                     }
  488.                 }
  489.                 else if (event.type == sf::Event::MouseButtonReleased)
  490.                 {
  491.                      m_MouseDown = false;
  492.  
  493.                     // Check if the close button was clicked
  494.                     if (m_CloseButton->m_MouseDown == true)
  495.                     {
  496.                         m_CloseButton->m_MouseDown = false;
  497.  
  498.                         // Check if the mouse is still on the close button
  499.                         if (m_CloseButton->mouseOnObject(mouseX, mouseY))
  500.                         {
  501.                             // If a callback was requested then send it
  502.                             if (m_CallbackFunctions[Closed].empty() == false)
  503.                             {
  504.                                 m_Callback.trigger = Closed;
  505.                                 addCallback();
  506.                             }
  507.                             else // The user won't stop the closing, so destroy the window
  508.                             {
  509.                                 destroy();
  510.                                 return;
  511.                             }
  512.                         }
  513.                     }
  514.                 }
  515.  
  516.                 // Reset the position and scale of the button
  517.                 m_CloseButton->setPosition(0, 0);
  518.                 m_CloseButton->setScale(1, 1);
  519.  
  520.                 // Tell the objects that the mouse is no longer down
  521.                 m_EventManager.mouseNoLongerDown();
  522.                 return;
  523.             }
  524.             else // The mouse is not on top of the titlebar
  525.             {
  526.                 // When the mouse went up then change the mouse down flag
  527.                 if (event.type == sf::Event::MouseButtonReleased)
  528.                 {
  529.                     m_MouseDown = false;
  530.                     m_CloseButton->mouseNoLongerDown();
  531.                 }
  532.  
  533.                 // Check if the mouse is on top of the borders
  534.                 if ((getTransform().transformRect(sf::FloatRect(0, 0, m_Size.x + m_LeftBorder + m_RightBorder, m_Size.y + m_TopBorder + m_BottomBorder + m_TitleBarHeight)).contains(mouseX, mouseY))
  535.                 &&  (getTransform().transformRect(sf::FloatRect(static_cast<float>(m_LeftBorder), static_cast<float>(m_TitleBarHeight + m_TopBorder), m_Size.x, m_Size.y)).contains(mouseX, mouseY) == false))
  536.                 {
  537.                     // If the mouse was released then tell the objects about it
  538.                     if (event.type == sf::Event::MouseButtonReleased)
  539.                         m_EventManager.mouseNoLongerDown();
  540.  
  541.                     // Don't send the event to the objects
  542.                     return;
  543.                 }
  544.             }
  545.         }
  546.  
  547.         // Let the child window handle the rest
  548.         GroupObject::handleEvent(event, mouseX - (m_LeftBorder * getScale().x), mouseY - ((m_TitleBarHeight + m_TopBorder) * getScale().y));
  549.     }
  550.  
  551.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  552.  
  553.     void ChildWindow::setDistanceToSide(unsigned int distanceToSide)
  554.     {
  555.         m_DistanceToSide = distanceToSide;
  556.     }
  557.  
  558.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  559.  
  560.     unsigned int ChildWindow::getDistanceToSide() const
  561.     {
  562.         return m_DistanceToSide;
  563.     }
  564.  
  565.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  566.  
  567.     void ChildWindow::setTitleAlignment(TitleAlignment alignment)
  568.     {
  569.         m_TitleAlignment = alignment;
  570.     }
  571.  
  572.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  573.  
  574.     ChildWindow::TitleAlignment ChildWindow::getTitleAlignment() const
  575.     {
  576.         return m_TitleAlignment;
  577.     }
  578.  
  579.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  580.  
  581.     void ChildWindow::destroy()
  582.     {
  583.         m_Parent->remove(this);
  584.     }
  585.  
  586.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  587.  
  588.     Vector2f ChildWindow::getDisplaySize()
  589.     {
  590.         return m_Size;
  591.     }
  592.  
  593.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  594.  
  595.     bool ChildWindow::mouseOnObject(float x, float y)
  596.     {
  597.         // Don't continue when the child window has not been loaded yet
  598.         if (m_Loaded == false)
  599.             return false;
  600.  
  601.         // Check if the mouse is on top of the title bar
  602.         if (getTransform().transformRect(sf::FloatRect(0, 0, m_Size.x + m_LeftBorder + m_RightBorder, static_cast<float>(m_TitleBarHeight + m_TopBorder))).contains(x, y))
  603.         {
  604.             m_EventManager.mouseNotOnObject();
  605.             return true;
  606.         }
  607.         else
  608.         {
  609.             // Check if the mouse is inside the child window
  610.             if (getTransform().transformRect(sf::FloatRect(0, 0, m_Size.x + m_LeftBorder + m_RightBorder, m_Size.y + m_TopBorder + m_BottomBorder)).contains(x, y - m_TitleBarHeight))
  611.                 return true;
  612.             else
  613.             {
  614.                 if (m_MouseHover)
  615.                     mouseLeftObject();
  616.  
  617.                 // Tell the objects inside the child window that the mouse is no longer on top of them
  618.                 m_EventManager.mouseNotOnObject();
  619.                 m_MouseHover = false;
  620.                 return false;
  621.             }
  622.         }
  623.     }
  624.  
  625.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  626.  
  627.     void ChildWindow::draw(sf::RenderTarget& target, sf::RenderStates states) const
  628.     {
  629.         // Don't draw when the child window wasn't created
  630.         if (m_Loaded == false)
  631.             return;
  632.  
  633.         // Get the current position and scale
  634.         Vector2f position = getPosition();
  635.         Vector2f curScale = getScale();
  636.  
  637.         // Calculate the scale factor of the view
  638.         float scaleViewX = target.getSize().x / target.getView().getSize().x;
  639.         float scaleViewY = target.getSize().y / target.getView().getSize().y;
  640.  
  641.         Vector2f viewPosition = (target.getView().getSize() / 2.f) - target.getView().getCenter();
  642.  
  643.         // Get the global position
  644.         Vector2f topLeftPanelPosition = states.transform.transformPoint(position.x + (m_LeftBorder * curScale.x) + viewPosition.x,
  645.                                                                         position.y + ((m_TitleBarHeight + m_TopBorder) * curScale.y) + viewPosition.y);
  646.         Vector2f bottomRightPanelPosition = states.transform.transformPoint(position.x + ((m_Size.x + m_LeftBorder) * curScale.x) + viewPosition.x,
  647.                                                                             position.y + ((m_TitleBarHeight + m_Size.y + m_TopBorder) * curScale.y) + viewPosition.y);
  648.         Vector2f topLeftTitleBarPosition;
  649.         Vector2f bottomRightTitleBarPosition;
  650.  
  651.         topLeftTitleBarPosition = states.transform.transformPoint(position.x + m_DistanceToSide + viewPosition.x,
  652.                                                                   position.y + viewPosition.y);
  653.         bottomRightTitleBarPosition = states.transform.transformPoint(position.x + ((m_Size.x + m_LeftBorder + m_RightBorder - (2*m_DistanceToSide) - m_CloseButton->getScaledSize().x) * curScale.x) + viewPosition.x,
  654.                                                                       position.y + (m_TitleBarHeight * curScale.y) + viewPosition.y);
  655.  
  656.         // Adjust the transformation
  657.         states.transform *= getTransform();
  658.  
  659.         sf::Transform oldTransform = states.transform;
  660.  
  661.         // Check if the title bar image is split
  662.         if (m_SplitImage)
  663.         {
  664.             // Split image is not supported yet
  665.             return;
  666.         }
  667.         else // The title bar image isn't split
  668.         {
  669.             // Scale the title bar
  670.             states.transform.scale((m_Size.x + m_LeftBorder + m_RightBorder) / m_TextureTitleBar_M->getSize().x, static_cast<float>(m_TitleBarHeight) / m_TextureTitleBar_M->getSize().y);
  671.  
  672.             // Draw the title bar
  673.             target.draw(m_SpriteTitleBar_M, states);
  674.  
  675.             // Undo the scaling
  676.             states.transform.scale(static_cast<float>(m_TextureTitleBar_M->getSize().x) / (m_Size.x + m_LeftBorder + m_RightBorder), static_cast<float>(m_TextureTitleBar_M->getSize().y) / m_TitleBarHeight);
  677.         }
  678.  
  679.         // Get the old clipping area
  680.         GLint scissor[4];
  681.         glGetIntegerv(GL_SCISSOR_BOX, scissor);
  682.  
  683.         // Check if there is a title
  684.         if (m_Title.isEmpty() == false)
  685.         {
  686. ///!!!  TODO: Instead of storing the title string, store the sf::Text object to avoid recreating every frame.
  687.  
  688.             // Create the text object
  689.             sf::Text text(m_Title, getGlobalFont());
  690.             text.setCharacterSize(m_TitleBarHeight * 8 / 10);
  691.             text.setColor(m_TitleColor);
  692.            
  693.             // Calculate the clipping area
  694.             GLint scissorLeft = TGUI_MAXIMUM(static_cast<GLint>(topLeftTitleBarPosition.x * scaleViewX), scissor[0]);
  695.             GLint scissorTop = TGUI_MAXIMUM(static_cast<GLint>(topLeftTitleBarPosition.y * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1] - scissor[3]);
  696.             GLint scissorRight = TGUI_MINIMUM(static_cast<GLint>(bottomRightTitleBarPosition.x * scaleViewX), scissor[0] + scissor[2]);
  697.             GLint scissorBottom = TGUI_MINIMUM(static_cast<GLint>(bottomRightTitleBarPosition.y * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1]);
  698.  
  699.             // If the object outside the window then don't draw anything
  700.             if (scissorRight < scissorLeft)
  701.                 scissorRight = scissorLeft;
  702.             else if (scissorBottom < scissorTop)
  703.                 scissorTop = scissorBottom;
  704.  
  705.             // Set the clipping area
  706.             glScissor(scissorLeft, target.getSize().y - scissorBottom, scissorRight - scissorLeft, scissorBottom - scissorTop);
  707.  
  708.             // Draw the text, depending on the alignment
  709.             if (m_TitleAlignment == TitleAlignmentLeft)
  710.             {
  711.                 states.transform.translate(static_cast<float>(m_DistanceToSide), 0);
  712.                 target.draw(text, states);
  713.                 states.transform.translate(-static_cast<float>(m_DistanceToSide), 0);
  714.             }
  715.             else if (m_TitleAlignment == TitleAlignmentCentered)
  716.             {
  717.                 states.transform.translate(m_DistanceToSide + (((m_Size.x + m_LeftBorder + m_RightBorder) - 3*m_DistanceToSide - m_CloseButton->getScaledSize().x - text.getGlobalBounds().width) / 2.0f), 0);
  718.                 target.draw(text, states);
  719.                 states.transform.translate(-(m_DistanceToSide + (((m_Size.x + m_LeftBorder + m_RightBorder) - 3*m_DistanceToSide - m_CloseButton->getScaledSize().x - text.getGlobalBounds().width) / 2.0f)), 0);
  720.             }
  721.             else // if (m_TitleAlignment == TitleAlignmentRight)
  722.             {
  723.                 states.transform.translate((m_Size.x + m_LeftBorder + m_RightBorder) - 2*m_DistanceToSide - m_CloseButton->getScaledSize().x - text.getGlobalBounds().width, 0);
  724.                 target.draw(text, states);
  725.                 states.transform.translate(-(m_Size.x + m_LeftBorder + m_RightBorder) + 2*m_DistanceToSide + m_CloseButton->getScaledSize().x + text.getGlobalBounds().width, 0);
  726.             }
  727.  
  728.             // Reset the old clipping area
  729.             glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  730.         }
  731.  
  732.         // Move the close button to the correct position
  733.         states.transform.translate((m_Size.x + m_LeftBorder + m_RightBorder) - m_DistanceToSide - m_CloseButton->getSize().x, (m_TitleBarHeight - m_CloseButton->getSize().y) / 2.f);
  734.  
  735.         // Draw the close button
  736.         target.draw(*m_CloseButton, states);
  737.  
  738.         // Set the correct transformation
  739.         states.transform = oldTransform.translate(0, static_cast<float>(m_TitleBarHeight));
  740.  
  741.         // Draw the borders
  742.         sf::RectangleShape borders(Vector2f(m_Size.x + m_LeftBorder + m_RightBorder, m_Size.y + m_TopBorder + m_BottomBorder));
  743.         borders.setFillColor(m_BorderColor);
  744.         target.draw(borders, states);
  745.  
  746.         // Make room for the borders
  747.         states.transform.translate(static_cast<float>(m_LeftBorder), static_cast<float>(m_TopBorder));
  748.  
  749.         // Draw the background
  750.         if (m_BackgroundColor != sf::Color::Transparent)
  751.         {
  752.             sf::RectangleShape background(Vector2f(m_Size.x, m_Size.y));
  753.             background.setFillColor(m_BackgroundColor);
  754.             target.draw(background, states);
  755.         }
  756.  
  757.         // Draw the background image if there is one
  758.         if (m_Texture != NULL)
  759.             target.draw(m_Sprite, states);
  760.  
  761.         // Calculate the clipping area
  762.         GLint scissorLeft = TGUI_MAXIMUM(static_cast<GLint>(topLeftPanelPosition.x * scaleViewX), scissor[0]);
  763.         GLint scissorTop = TGUI_MAXIMUM(static_cast<GLint>(topLeftPanelPosition.y * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1] - scissor[3]);
  764.         GLint scissorRight = TGUI_MINIMUM(static_cast<GLint>(bottomRightPanelPosition.x * scaleViewX), scissor[0] + scissor[2]);
  765.         GLint scissorBottom = TGUI_MINIMUM(static_cast<GLint>(bottomRightPanelPosition.y * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1]);
  766.  
  767.         // If the object outside the window then don't draw anything
  768.         if (scissorRight < scissorLeft)
  769.             scissorRight = scissorLeft;
  770.         else if (scissorBottom < scissorTop)
  771.             scissorTop = scissorBottom;
  772.  
  773.         // Set the clipping area
  774.         glScissor(scissorLeft, target.getSize().y - scissorBottom, scissorRight - scissorLeft, scissorBottom - scissorTop);
  775.  
  776.         // Draw the objects in the child window
  777.         drawObjectGroup(&target, states);
  778.  
  779.         // Reset the old clipping area
  780.         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  781.     }
  782.  
  783.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  784. }
  785.  
  786. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement