File: TextControls.h

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (170 lines) | stat: -rw-r--r-- 5,481 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * TextControls.h, part of VCMI engine
 *
 * Authors: listed in file AUTHORS in main folder
 *
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */
#pragma once

#include "../gui/CIntObject.h"
#include "../gui/TextAlignment.h"
#include "../render/Colors.h"
#include "../render/EFont.h"
#include "../../lib/filesystem/ResourcePath.h"

class IImage;
class CSlider;

/// Base class for all text-related widgets.
/// Controls text blitting-related options
class CTextContainer : public virtual CIntObject
{
protected:
	/// returns size of border, for left- or right-aligned text
	virtual Point getBorderSize() = 0;
	/// do actual blitting of line. Text "what" will be placed at "where" and aligned according to alignment
	void blitLine(Canvas & to, Rect where, std::string what);

	CTextContainer(ETextAlignment alignment, EFonts font, ColorRGBA color);

public:
	ETextAlignment alignment;
	EFonts font;
	ColorRGBA color; // default font color. Can be overridden by placing "{}" into the string
};

/// Label which shows text
class CLabel : public CTextContainer
{
protected:
	Point getBorderSize() override;
	virtual std::string visibleText();
	virtual void trimText();

	std::shared_ptr<CIntObject> background;
	std::string text;
	int maxWidth;
	bool autoRedraw;  //whether control will redraw itself on setTxt

public:

	std::string getText();
	virtual void setAutoRedraw(bool option);
	virtual void setText(const std::string & Txt);
	virtual void setMaxWidth(int width);
	virtual void setColor(const ColorRGBA & Color);
	void clear();
	size_t getWidth();

	CLabel(int x = 0, int y = 0, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT,
		const ColorRGBA & Color = Colors::WHITE, const std::string & Text = "", int maxWidth = 0);
	void showAll(Canvas & to) override; //shows statusbar (with current text)
};

/// Small helper class to manage group of similar labels
class CLabelGroup : public CIntObject
{
	std::vector<std::shared_ptr<CLabel>> labels;
	EFonts font;
	ETextAlignment align;
	ColorRGBA color;
public:
	CLabelGroup(EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT, const ColorRGBA & Color = Colors::WHITE);
	void add(int x = 0, int y = 0, const std::string & text = "");
	size_t currentSize() const;
};

/// Multi-line label that can display multiple lines of text
/// If text is too big to fit into requested area remaining part will not be visible
class CMultiLineLabel : public CLabel
{
	// text to blit, split into lines that are no longer than widget width
	std::vector<std::string> lines;

	// area of text that actually will be printed, default is widget size
	Rect visibleSize;

	void splitText(const std::string & Txt, bool redrawAfter);
	Rect getTextLocation();
public:
	// total size of text, x = longest line of text, y = total height of lines
	Point textSize;

	CMultiLineLabel(Rect position, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT, const ColorRGBA & Color = Colors::WHITE, const std::string & Text = "");

	void setText(const std::string & Txt) override;
	std::vector<std::string> getLines();
	void showAll(Canvas & to) override;

	void setVisibleSize(Rect visibleSize, bool redrawElement = true);
	// scrolls text visible in widget. Positive value will move text up
	void scrollTextTo(int distance, bool redrawAfterScroll = true);
	void scrollTextBy(int distance);
};

/// a multi-line label that tries to fit text with given available width and height;
/// if not possible, it creates a slider for scrolling text
class CTextBox : public CIntObject
{
	int sliderStyle;
public:
	std::shared_ptr<CMultiLineLabel> label;
	std::shared_ptr<CSlider> slider;

	CTextBox(std::string Text, const Rect & rect, int SliderStyle, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT, const ColorRGBA & Color = Colors::WHITE);

	void resize(Point newSize);
	/// Resizes text box to minimal size needed to fit current text
	/// No effect if text is too large to fit and requires slider
	void trimToFit();
	void setText(const std::string & Txt);
	void sliderMoved(int to);
};

/// Status bar which is shown at the bottom of the in-game screens
class CGStatusBar : public CLabel, public std::enable_shared_from_this<CGStatusBar>, public IStatusBar
{
	std::string hoverText;
	std::string consoleText;
	bool enteringText;

	CGStatusBar(std::shared_ptr<CIntObject> background_, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::CENTER, const ColorRGBA & Color = Colors::WHITE);
	CGStatusBar(int x, int y, const ImagePath & name, int maxw = -1);
	CGStatusBar(int x, int y);

	//make CLabel API private
	using CLabel::getText;
	using CLabel::setAutoRedraw;
	using CLabel::setText;
	using CLabel::setColor;
	using CLabel::getWidth;

protected:
	Point getBorderSize() override;

	void clickPressed(const Point & cursorPosition) override;

public:
	~CGStatusBar();

	template<typename ...Args>
	static std::shared_ptr<CGStatusBar> create(Args... args)
	{
		std::shared_ptr<CGStatusBar> ret{new CGStatusBar{args...}};
		return ret;
	}

	void show(Canvas & to) override;
	void activate() override;
	void deactivate() override;

	// IStatusBar interface
	void write(const std::string & Text) override;
	void clearIfMatching(const std::string & Text) override;
	void clear() override;
	void setEnteringMode(bool on) override;
	void setEnteredText(const std::string & text) override;
};