diff options
-rw-r--r-- | src/graphics/text.cpp | 79 | ||||
-rw-r--r-- | src/graphics/text.h | 48 | ||||
-rw-r--r-- | src/graphics/textureFont.cpp | 48 | ||||
-rw-r--r-- | src/graphics/textureFont.h | 10 | ||||
-rw-r--r-- | src/states/titleState.cpp | 26 | ||||
-rw-r--r-- | src/ui.cpp | 21 | ||||
-rw-r--r-- | src/ui.h | 5 |
7 files changed, 156 insertions, 81 deletions
diff --git a/src/graphics/text.cpp b/src/graphics/text.cpp index 82b8811..43e8be1 100644 --- a/src/graphics/text.cpp +++ b/src/graphics/text.cpp @@ -2,36 +2,61 @@ using namespace Graphics; -Text::Text(TextureFont &font, const std::string &text) - : font_(font) - , text_(text) - , vertices_(sf::Quads, text.size()*4) -{ - unsigned int length = vertices_.getVertexCount(); - sf::Vector2f glyphSize = font_.getGlyphSize(); - // TODO: this is the simplest rendering way: everything in one line - // we should improve this to make it handle newlines or max witdths - for(unsigned int i=0; i < length; i=i+4){ - vertices_[i+0].position = sf::Vector2f(glyphSize.x * i/4, 0); - vertices_[i+1].position = sf::Vector2f(glyphSize.x * (i/4 + 1), 0); - vertices_[i+2].position = sf::Vector2f(glyphSize.x * (i/4 + 1), glyphSize.y); - vertices_[i+3].position = sf::Vector2f(glyphSize.x * i/4, glyphSize.y); +template <> +void Text<TextureFont>::arrange(TextureFont &font){ + // TODO: this is really awful rendering but works a little bit + unsigned int filledX = 0; + unsigned int row = 0; + unsigned int col = 0; - std::array<sf::Vector2f, 4> glyph = font_.getGlyphMapping(text_[i/4]); + for(unsigned int i=0; i < text_.length(); i++){ + sf::Glyph glyph = font.getGlyph( text_[i] ); + filledX += glyph.advance; + if (maxWidth_ != 0 && ( text_[i] == '\n' || filledX > maxWidth_)){ + row++; + filledX = 0; + col = 0; + if(text_[i] == '\n') continue; + } - vertices_[i+0].texCoords = glyph[0]; - vertices_[i+1].texCoords = glyph[1]; - vertices_[i+2].texCoords = glyph[2]; - vertices_[i+3].texCoords = glyph[3]; + vertices_[4*i+0].position = sf::Vector2f( + col*glyph.advance + glyph.bounds.left, + (glyph.bounds.top) + row * glyph.bounds.height + ); + vertices_[4*i+1].position = sf::Vector2f( + col*glyph.advance + glyph.bounds.left+glyph.bounds.width, + (glyph.bounds.top) + row * glyph.bounds.height + ); + vertices_[4*i+2].position = sf::Vector2f( + col*glyph.advance + glyph.bounds.left+glyph.bounds.width, + (glyph.bounds.top+glyph.bounds.height) + row * glyph.bounds.height + ); + vertices_[4*i+3].position = sf::Vector2f( + col*glyph.advance + glyph.bounds.left, + (glyph.bounds.top+glyph.bounds.height) + row * glyph.bounds.height + ); + col++; + + vertices_[4*i+0].texCoords = sf::Vector2f( + glyph.textureRect.left, + glyph.textureRect.top + ); + vertices_[4*i+1].texCoords = sf::Vector2f( + glyph.textureRect.left+glyph.textureRect.width, + glyph.textureRect.top + ); + vertices_[4*i+2].texCoords = sf::Vector2f( + glyph.textureRect.left+glyph.textureRect.width, + glyph.textureRect.top+glyph.textureRect.height + ); + vertices_[4*i+3].texCoords = sf::Vector2f( + glyph.textureRect.left, + glyph.textureRect.top+glyph.textureRect.height + ); } } -void Text::draw(sf::RenderTarget& target, sf::RenderStates states) const -{ - // TODO: only repaint if needed: when repainting is needed - // vertices_.clear() and fun - states.transform *= getTransform(); - states.texture = font_.getTexture(); - // you may also override states.shader or states.blendMode if you want - target.draw(vertices_, states); +template <> +void Text<sf::Font>::arrange(sf::Font &font){ + // TODO: Implement this function for a generic sf::Font } diff --git a/src/graphics/text.h b/src/graphics/text.h index 22179f5..f60980c 100644 --- a/src/graphics/text.h +++ b/src/graphics/text.h @@ -3,15 +3,59 @@ #include"textureFont.h" namespace Graphics { + + template<typename Font> class Text : public sf::Drawable, public sf::Transformable { private: - TextureFont &font_; + Font &font_; const std::string text_; sf::VertexArray vertices_; + unsigned int size_, maxWidth_, maxHeight_; + + void arrange(Font &font); // Specialize for sf::Font and TextureFont + public: - Text(TextureFont &font, const std::string &text); + Text(Font &font, const std::string &text, unsigned int maxWidth=0, + unsigned int maxHeight=0); + + void setFont(Font &font); + void setText(const std::string &text); + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; }; + + template <typename Font> + Text<Font>::Text(Font &font, const std::string &text, + unsigned int maxWidth, unsigned int maxHeight) + : font_(font) + , text_(text) + , vertices_(sf::Quads, text.size()*4) + , size_(0) + , maxWidth_(maxWidth) + , maxHeight_(maxHeight) + { + arrange(font); + } + + + template <typename Font> + void Text<Font>::draw(sf::RenderTarget& target, sf::RenderStates states) const + { + // TODO: only repaint if needed: when repainting is needed + // vertices_.clear() and fun + states.transform *= getTransform(); + states.texture = font_.getTexture(size_); + // you may also override states.shader or states.blendMode if you want + target.draw(vertices_, states); + } + + template <typename Font> + void Text<Font>::setFont(Font &font){ + font_ = font; + arrange(font); + } } + + #endif // GRAPHICS_TEXT_H diff --git a/src/graphics/textureFont.cpp b/src/graphics/textureFont.cpp index 29f9c71..3be2444 100644 --- a/src/graphics/textureFont.cpp +++ b/src/graphics/textureFont.cpp @@ -8,37 +8,35 @@ TextureFont::TextureFont(const sf::Texture &texture, , description_(description) { sf::Vector2u totalSize = tex_.getSize(); - sf::Vector2f totalSize_f (totalSize.x, totalSize.y); - glyphSize_ = sf::Vector2f( totalSize.x / description_.numcols, + glyphSize_ = sf::Vector2i( totalSize.x / description_.numcols, totalSize.y / description_.numrows ); -} -std::array<sf::Vector2f, 4> TextureFont::getGlyphMapping(const char ch){ - unsigned int pos = static_cast<unsigned int>( description_.mapping.find_first_of(ch)); - if (pos == std::string::npos){ - // TODO: Error handling! - pos = 0; + for(unsigned int i=0; i<description.mapping.size(); i++){ + sf::Glyph glyph; + glyph.advance = glyphSize_.x; + + unsigned int x = i % description_.numcols; + unsigned int y = (i - x) / description_.numcols; + + glyph.textureRect = sf::IntRect(x*glyphSize_.x, + y*glyphSize_.y, + glyphSize_.x, + glyphSize_.y); + + glyph.bounds = sf::FloatRect(0, + 0, + glyphSize_.x, + glyphSize_.y); + + glyphTable_.insert(std::make_pair(description.mapping[i], glyph)); } - unsigned int x = pos % description_.numcols; - unsigned int y = (pos - x) / description_.numcols; - - sf::Vector2f basePos(x*glyphSize_.x, y*glyphSize_.y); - - // 1 --- 2 - // | | - // 4 --- 3 - return std::array<sf::Vector2f,4> { - basePos, - basePos + sf::Vector2f( glyphSize_.x, 0 ), - basePos + glyphSize_, - basePos + sf::Vector2f( 0, glyphSize_.y ), - }; } -sf::Vector2f TextureFont::getGlyphSize(){ - return glyphSize_; +const sf::Glyph & TextureFont::getGlyph(char ch) const{ + auto pair = glyphTable_.find(ch); + return pair->second; } -const sf::Texture * TextureFont::getTexture(){ +const sf::Texture * TextureFont::getTexture(unsigned int _){ return &tex_; } diff --git a/src/graphics/textureFont.h b/src/graphics/textureFont.h index 5e78f9e..f3f194a 100644 --- a/src/graphics/textureFont.h +++ b/src/graphics/textureFont.h @@ -13,14 +13,16 @@ namespace Graphics { unsigned int numrows, numcols; }; private: + using GlyphTable = std::map<char, sf::Glyph>; + GlyphTable glyphTable_; + const sf::Texture &tex_; const Descr description_; - sf::Vector2f glyphSize_; + sf::Vector2i glyphSize_; public: TextureFont(const sf::Texture &texture, Descr desc); - std::array<sf::Vector2f,4> getGlyphMapping(const char ch); - sf::Vector2f getGlyphSize(); - const sf::Texture *getTexture(); + const sf::Glyph &getGlyph(char ch) const; + const sf::Texture *getTexture(unsigned int _); }; } diff --git a/src/states/titleState.cpp b/src/states/titleState.cpp index d96c840..fe78d45 100644 --- a/src/states/titleState.cpp +++ b/src/states/titleState.cpp @@ -8,7 +8,11 @@ TitleState::TitleState(StateStack &stack, State::Context context) // TODO: Initialize UI properly to zeros //, ui(0,0,false,false,0,0) { - + context.textures->load(Textures::Id::Base_Font, "assets/img/Font/Font.png"); + auto &fontTexture = context.textures->get(Textures::Id::Base_Font); + Graphics::TextureFont::Descr fontDescr {"abcdefghijklmnopqrstuvwxyz1234567890!?.,$ ", 6,7}; + auto font = new Graphics::TextureFont(fontTexture, fontDescr); + context.textureFonts->manage(Fonts::Id::Base_Font, font); } void TitleState::update(sf::Time dt){ @@ -20,22 +24,16 @@ void TitleState::render(){ ui.initImUI(); - if (ui.button(context_.window, 17, "Button 1", sf::Vector2i(0,0), sf::Vector2i(200,100)) ){ - printf("Button 1 pressed!!\n"); - } - if (ui.button(context_.window, 18, "Button 2", sf::Vector2i(0,200), sf::Vector2i(200,100)) ){ - printf("Button 2 pressed!!\n"); - } - if (ui.button(context_.window, 19, "Button 3", sf::Vector2i(0,400), sf::Vector2i(200,100)) ){ - printf("Button 3 pressed!!\n"); - } - + Graphics::TextureFont &font = context_.textureFonts->get(Fonts::Id::Base_Font); - radioState = ui.radioButton(context_.window, 21, "Radio", radioState, - sf::Vector2i(0,800), sf::Vector2i(200,100)); + radioState = ui.radioButton(context_.window, + font, 21, + "this is\nthe whole thing or maybe is just another bullshit code it doesn't work", + radioState, + sf::Vector2i(0,100), sf::Vector2i(200,50)); if (radioState){ - ui.button(context_.window, 20, "Hidden button", sf::Vector2i(0,600), sf::Vector2i(200,100)); + ui.button(context_.window, 20, "Hidden button", sf::Vector2i(0,200), sf::Vector2i(200,100)); } ui.finishImUI(); @@ -148,8 +148,9 @@ bool UI::button(sf::RenderWindow *win, int id, const std::string &text, return result; } -bool UI::radioButton(sf::RenderWindow *win, int id, const std::string &text, - bool state, sf::Vector2i pos, sf::Vector2i size){ +bool UI::radioButton(sf::RenderWindow *win, Graphics::TextureFont font, + int id, const std::string &text, bool state, sf::Vector2i pos, + sf::Vector2i size){ sf::IntRect rect {pos, size}; if( rect.contains( mousePosition() ) ){ @@ -170,18 +171,24 @@ bool UI::radioButton(sf::RenderWindow *win, int id, const std::string &text, } // Rendering: - sf::CircleShape radio{ 50 }; - radio.setPosition( sf::Vector2f(pos) ); - radio.setOutlineColor( sf::Color::Blue ); - radio.setOutlineThickness( 5 ); + sf::RectangleShape rectangle { sf::Vector2f(size) }; + rectangle.setPosition( sf::Vector2f(pos) ); + win->draw(rectangle); + sf::CircleShape radio{ 4 }; + radio.setPosition( sf::Vector2f(pos) + sf::Vector2f(10, size.y/2) ); + radio.setOutlineColor( sf::Color::Red ); + radio.setOutlineThickness( 1 ); if(state){ radio.setFillColor( sf::Color::Blue ); } else { } - win->draw(radio); + Graphics::Text textGraph {font, text, size.x - 30, size.y}; + textGraph.setPosition(sf::Vector2f(pos) + sf::Vector2f{30, size.y/2}); + win->draw(textGraph); + return state; } @@ -2,6 +2,7 @@ #define UI_H #include<SFML/Graphics.hpp> +#include"graphics/text.h" enum class MouseButton{ Left, @@ -37,8 +38,8 @@ class UI{ void finishImUI(); bool button(sf::RenderWindow *win, int id, const std::string &text, sf::Vector2i pos, sf::Vector2i size); - bool radioButton(sf::RenderWindow *win, int id, - const std::string &text, bool state, sf::Vector2i pos, + bool radioButton(sf::RenderWindow *win, Graphics::TextureFont font, + int id, const std::string &text, bool state, sf::Vector2i pos, sf::Vector2i size); }; |