summaryrefslogtreecommitdiff
path: root/src/gui/guiHyperText.h
diff options
context:
space:
mode:
authorPierre-Yves Rollo <dev@pyrollo.com>2019-09-10 15:11:26 +0200
committerSmallJoker <SmallJoker@users.noreply.github.com>2019-11-03 11:45:33 +0100
commit72416a6a1f75d56abfad0f486e57fd32579b3604 (patch)
tree2ff2978c1aec4ee6548474b8c65d3c96bab5b05f /src/gui/guiHyperText.h
parent8697090b3564b508af50d40068a61db280f714a6 (diff)
downloadminetest-72416a6a1f75d56abfad0f486e57fd32579b3604.tar.gz
minetest-72416a6a1f75d56abfad0f486e57fd32579b3604.tar.bz2
minetest-72416a6a1f75d56abfad0f486e57fd32579b3604.zip
Formspec: add hypertext element
Diffstat (limited to 'src/gui/guiHyperText.h')
-rw-r--r--src/gui/guiHyperText.h229
1 files changed, 229 insertions, 0 deletions
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 <dev@pyrollo.com>
+
+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<std::string, std::string> StyleList;
+ typedef std::unordered_map<std::string, std::string> AttrsList;
+
+ struct Tag
+ {
+ std::string name;
+ AttrsList attrs;
+ StyleList style;
+ };
+
+ struct Element
+ {
+ std::list<Tag *> tags;
+ ElementType type;
+ core::stringw text = "";
+
+ core::dimension2d<u32> dim;
+ core::position2d<s32> 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<Element> elements;
+ HalignType halign;
+ s32 margin = 10;
+
+ void setStyle(StyleList &style);
+ };
+
+ std::vector<Paragraph> 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<std::string, StyleList> m_elementtags;
+ std::unordered_map<std::string, StyleList> m_paragraphtags;
+
+ std::vector<Tag *> m_tags;
+ std::list<Tag *> 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<s32> &dest_rect);
+ inline s32 getHeight() { return m_height; };
+ void draw(const core::rect<s32> &dest_rect,
+ const core::position2d<s32> &dest_offset);
+ ParsedText::Element *getElementAt(core::position2d<s32> pos);
+ ParsedText::Tag *m_hovertag;
+
+protected:
+ struct RectWithMargin
+ {
+ core::rect<s32> rect;
+ s32 margin;
+ };
+
+ ParsedText m_text;
+ Client *m_client;
+ gui::IGUIEnvironment *m_environment;
+ s32 m_height;
+ s32 m_voffset;
+ std::vector<RectWithMargin> 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<s32> &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<s32> m_display_text_rect;
+ core::position2d<s32> m_text_scrollpos;
+
+ ParsedText::Element *getElementAt(s32 X, s32 Y);
+ void checkHover(s32 X, s32 Y);
+};