6#include <fifechan/widgets/textbox.hpp>
13#include <utf8cpp/utf8.h>
16#include "fifechan/events/textinputevent.hpp"
17#include "fifechan/font.hpp"
18#include "fifechan/graphics.hpp"
19#include "fifechan/key.hpp"
20#include "fifechan/mouseinput.hpp"
21#include "fifechan/text.hpp"
22#include "fifechan/utf8stringeditor.hpp"
28 assert(
"mText is not null" &&
mText !=
nullptr);
29 assert(
"mStringEditor is not null" &&
mStringEditor !=
nullptr);
46 assert(
"text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
48 mText->setContent(text);
54 assert(
"font is not null" &&
getFont() !=
nullptr);
69 for (i = 0; i <
mText->getNumberOfRows(); i++) {
77 assert(
"font is not null" &&
getFont() !=
nullptr);
85 assert(
"font is not null" &&
getFont() !=
nullptr);
87 if (mouseEvent.
getButton() == MouseEvent::Button::Left) {
100 Key
const key = keyEvent.
getKey();
102 if (key.getValue() == fcn::Key::LEFT) {
112 }
else if (key.getValue() == fcn::Key::RIGHT) {
122 }
else if (key.getValue() == fcn::Key::DOWN) {
124 }
else if (key.getValue() == fcn::Key::UP) {
126 }
else if (key.getValue() == fcn::Key::HOME) {
128 }
else if (key.getValue() == fcn::Key::END) {
130 }
else if (key.getValue() == fcn::Key::KEY_RETURN &&
mEditable) {
152 key.getValue() == fcn::Key::KEY_DELETE &&
157 key.getValue() == fcn::Key::KEY_DELETE &&
163 }
else if (key.getValue() == fcn::Key::PAGEUP) {
167 if (par !=
nullptr) {
170 int const newCaretRow =
getCaretRow() - rowsPerPage;
171 if (newCaretRow >= 0) {
178 }
else if (key.getValue() == fcn::Key::PAGEDOWN) {
182 if (par !=
nullptr) {
193 }
else if (key.getValue() == fcn::Key::TAB &&
mEditable) {
195 int constexpr tabSize = 4;
196 int const spacesToInsert = tabSize - (
getCaretColumn() % tabSize);
207 assert(
"text row is valid utf8" && utf8::is_valid(row.begin(), row.end()));
208 assert(
"caret column position is valid" && utf8::is_valid(row.begin(), row.begin() +
getCaretColumn()));
215 std::string
const & text =
event.getText();
226 static_cast<void>(recursion);
237 assert(
"font is not null" &&
getFont() !=
nullptr);
242 int newWidth =
static_cast<int>(dim.
width);
243 int newHeight =
static_cast<int>(dim.
height);
265 assert(
"position is within bounds" && position <= mText->getContent().size());
266 mText->setCaretPosition(position);
271 return mText->getCaretPosition();
276 assert(
"row is non-negative" && row >= 0);
277 assert(
"column is non-negative" && column >= 0);
278 mText->setCaretRow(row);
279 mText->setCaretColumn(column);
284 assert(
"row is non-negative" && row >= 0);
285 mText->setCaretRow(row);
290 return mText->getCaretRow();
295 assert(
"column is non-negative" && column >= 0);
296 mText->setCaretColumn(column);
301 return mText->getCaretColumn();
306 assert(
"row is non-negative" && row >= 0);
307 assert(
"row is within bounds" &&
static_cast<unsigned>(row) <
getNumberOfRows());
309 return mText->getRow(row);
314 assert(
"row is non-negative" && row >= 0);
315 assert(
"row is within bounds" &&
static_cast<unsigned>(row) <
getNumberOfRows());
316 assert(
"text is valid utf8" && utf8::is_valid(text.begin(), text.end()));
318 mText->setRow(row, text);
324 return mText->getNumberOfRows();
329 return mText->getContent();
339 assert(
"font is not null" &&
getFont() !=
nullptr);
356 assert(
"row text is valid utf8" && utf8::is_valid(row.begin(), row.end()));
374 assert(
"column is non-negative" && column >= 0);
394 assert(
"row is non-negative" && row >= 0);
395 assert(
"column is non-negative" && column >= 0);
virtual int getHeight() const =0
Gets the height of the glyphs in the font.
Abstract interface providing primitive drawing functions (lines, rectangles, etc.).
void drawText(std::string const &text, int x, int y)
Draws text with a default left alignment.
virtual void setFont(Font *font)
Sets the font to use when drawing text.
virtual void drawLine(int x1, int y1, int x2, int y2)=0
Draws a line.
virtual void setColor(Color const &color)=0
Sets the color to use when drawing.
virtual void fillRectangle(Rectangle const &rectangle)=0
Draws a filled rectangle.
Key const & getKey() const
Gets the key of the event.
Represents a mouse event.
int getX() const
Gets the x coordinate of the mouse event.
int getY() const
Gets the y coordinate of the mouse event.
MouseEvent::Button getButton() const
Gets the button of the mouse event.
Represents a rectangular area (X, Y, Width, Height).
int width
Holds the width of the rectangle.
int height
Holds the height of the rectangle.
void fontChanged() override
Called when the font has changed.
virtual void scrollToCaret()
Scrolls the text to the caret if the text box is in a scroll area.
void setCaretColumnUTF8(int column)
Sets caret column (UTF-8 aware).
virtual void addRow(std::string const &row)
Adds a row of text to the end of the text.
void keyPressed(KeyEvent &keyEvent) override
Called if a key is pressed when the widget has keyboard focus.
std::string getTextRow(int row) const
Gets a certain row from the text.
Text * mText
Holds the text of the text box.
void setCaretRowColumn(int row, int column)
Sets the row and the column where the caret should be currently located.
void draw(Graphics *graphics) override
Draws the widget.
void textInput(TextInputEvent &event) override
Called when text input (IME, dead-key, paste) is received.
void setTextRow(int row, std::string const &text)
Sets the text of a certain row of the text.
bool mEditable
True if the text box is editable, false otherwise.
void adjustSizeImpl()
Adjusts the size of the button to fit the caption.
void resizeToContent(bool recursion=true) override
Resizes the widget's size to fit the content exactly, calls recursively all childs.
unsigned int getCaretPosition() const
Gets the caret position in the text.
virtual void drawCaret(Graphics *graphics, int x, int y)
Draws the caret.
bool mOpaque
True if the text box is opaque, false otherwise.
std::string getText() const
Gets the text of the text box.
void setCaretColumn(int column)
Sets the column where the caret should be currently located.
TextBox(std::string const &text="")
Constructor.
unsigned int getCaretColumn() const
Gets the column where the caret is currently located.
void setCaretRow(int row)
Sets the row where the caret should be currently located.
void mousePressed(MouseEvent &mouseEvent) override
Called when a mouse button has been pressed down on the widget area.
void setEditable(bool editable)
Sets the text box to be editable or not.
void adjustSize() override
Adjusts the text box's size to fit the text.
void setCaretRowUTF8(int row)
Sets caret row (UTF-8 aware).
void mouseDragged(MouseEvent &mouseEvent) override
Called when the mouse has moved and the mouse has previously been pressed on the widget.
unsigned int getCaretRow() const
Gets the row number where the caret is currently located.
void setText(std::string const &text)
Sets the text of the text box.
bool isOpaque() const
Checks if the text box is opaque.
void setOpaque(bool opaque)
Sets the text box to be opaque or not.
UTF8StringEditor * mStringEditor
UTF8StringEditor for UTF8 support.
unsigned int getNumberOfRows() const
Gets the number of rows in the text.
bool isEditable() const
Checks if the text box is editable.
void setCaretPosition(unsigned int position)
Sets the position of the caret in the text.
void setCaretRowColumnUTF8(int row, int column)
Sets the caret row and column (UTF-8 aware).
Text input event for IME (input method editor) composition, dead keys, and pasted text.
Helper class for text manipulation within widgets.
Utility for editing and handling UTF-8 encoded strings.
static int countChars(std::string const &text, int byteOffset)
Counts characters up to byteOffset.
static int eraseChar(std::string &text, int byteOffset)
Erase character at specified byte offset.
static int getOffset(std::string const &text, int charIndex)
Gets byte offset for character index.
static int nextChar(std::string const &text, int byteOffset)
Returns byte offset of the next character.
static int prevChar(std::string const &text, int byteOffset)
Returns byte offset of the previous character.
Used replacement tokens by configure_file():