From 72416a6a1f75d56abfad0f486e57fd32579b3604 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 10 Sep 2019 15:11:26 +0200 Subject: Formspec: add hypertext element --- src/gui/guiHyperText.h | 229 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 src/gui/guiHyperText.h (limited to 'src/gui/guiHyperText.h') diff --git a/src/gui/guiHyperText.h b/src/gui/guiHyperText.h new file mode 100644 index 000000000..e3ad0e747 --- /dev/null +++ b/src/gui/guiHyperText.h @@ -0,0 +1,229 @@ +/* +Minetest +Copyright (C) 2019 EvicenceBKidscode / Pierre-Yves Rollo + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "config.h" // for USE_FREETYPE + +using namespace irr; + +class ISimpleTextureSource; +class Client; + +#if USE_FREETYPE +#include "irrlicht_changes/CGUITTFont.h" +#endif + +class ParsedText +{ +public: + ParsedText(const wchar_t *text); + ~ParsedText(); + + enum ElementType + { + ELEMENT_TEXT, + ELEMENT_SEPARATOR, + ELEMENT_IMAGE, + ELEMENT_ITEM + }; + + enum BackgroundType + { + BACKGROUND_NONE, + BACKGROUND_COLOR + }; + + enum FloatType + { + FLOAT_NONE, + FLOAT_RIGHT, + FLOAT_LEFT + }; + + enum HalignType + { + HALIGN_CENTER, + HALIGN_LEFT, + HALIGN_RIGHT, + HALIGN_JUSTIFY + }; + + enum ValignType + { + VALIGN_MIDDLE, + VALIGN_TOP, + VALIGN_BOTTOM + }; + + typedef std::unordered_map StyleList; + typedef std::unordered_map AttrsList; + + struct Tag + { + std::string name; + AttrsList attrs; + StyleList style; + }; + + struct Element + { + std::list tags; + ElementType type; + core::stringw text = ""; + + core::dimension2d dim; + core::position2d pos; + s32 drawwidth; + + FloatType floating = FLOAT_NONE; + + ValignType valign; + +#if USE_FREETYPE + gui::CGUITTFont *font; +#else + gui::IGUIFont *font; +#endif + + irr::video::SColor color; + irr::video::SColor hovercolor; + bool underline; + + s32 baseline = 0; + + // img & item specific attributes + std::string name; + v3s16 angle{0, 0, 0}; + v3s16 rotation{0, 0, 0}; + + s32 margin = 10; + + void setStyle(StyleList &style); + }; + + struct Paragraph + { + std::vector elements; + HalignType halign; + s32 margin = 10; + + void setStyle(StyleList &style); + }; + + std::vector m_paragraphs; + + // Element style + s32 margin = 3; + ValignType valign = VALIGN_TOP; + BackgroundType background_type = BACKGROUND_NONE; + irr::video::SColor background_color; + + Tag m_root_tag; + +protected: + // Parser functions + void enterElement(ElementType type); + void endElement(); + void enterParagraph(); + void endParagraph(); + void pushChar(wchar_t c); + ParsedText::Tag *newTag(const std::string &name, const AttrsList &attrs); + ParsedText::Tag *openTag(const std::string &name, const AttrsList &attrs); + bool closeTag(const std::string &name); + void parseGenericStyleAttr(const std::string &name, const std::string &value, + StyleList &style); + void parseStyles(const AttrsList &attrs, StyleList &style); + void globalTag(const ParsedText::AttrsList &attrs); + u32 parseTag(const wchar_t *text, u32 cursor); + void parse(const wchar_t *text); + + std::unordered_map m_elementtags; + std::unordered_map m_paragraphtags; + + std::vector m_tags; + std::list m_active_tags; + + // Current values + StyleList m_style; + Element *m_element; + Paragraph *m_paragraph; +}; + +class TextDrawer +{ +public: + TextDrawer(const wchar_t *text, Client *client, gui::IGUIEnvironment *environment, + ISimpleTextureSource *tsrc); + + void place(const core::rect &dest_rect); + inline s32 getHeight() { return m_height; }; + void draw(const core::rect &dest_rect, + const core::position2d &dest_offset); + ParsedText::Element *getElementAt(core::position2d pos); + ParsedText::Tag *m_hovertag; + +protected: + struct RectWithMargin + { + core::rect rect; + s32 margin; + }; + + ParsedText m_text; + Client *m_client; + gui::IGUIEnvironment *m_environment; + s32 m_height; + s32 m_voffset; + std::vector m_floating; +}; + +class GUIHyperText : public gui::IGUIElement +{ +public: + //! constructor + GUIHyperText(const wchar_t *text, gui::IGUIEnvironment *environment, + gui::IGUIElement *parent, s32 id, + const core::rect &rectangle, Client *client, + ISimpleTextureSource *tsrc); + + //! destructor + virtual ~GUIHyperText(); + + //! draws the element and its children + virtual void draw(); + + core::dimension2du getTextDimension(); + + bool OnEvent(const SEvent &event); + +protected: + // GUI members + Client *m_client; + GUIScrollBar *m_vscrollbar; + TextDrawer m_drawer; + + // Positioning + u32 m_scrollbar_width; + core::rect m_display_text_rect; + core::position2d m_text_scrollpos; + + ParsedText::Element *getElementAt(s32 X, s32 Y); + void checkHover(s32 X, s32 Y); +}; -- cgit v1.2.3