171 lines
5.7 KiB
C++
171 lines
5.7 KiB
C++
/// Josh's User Interface Library
|
|
/// A C++20 Library for creating, styling, and rendering of a UI/UX widgets.
|
|
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
|
|
/// Special Thanks to William Tomasine II and Maxine Hayes.
|
|
/// (c) 2024 Redacted Software
|
|
/// This work is dedicated to the public domain.
|
|
|
|
/// @file TextInputForm.hpp
|
|
/// @desc A box that accepts user keyboard input.
|
|
/// @edit 2024-08-02
|
|
|
|
#pragma once
|
|
|
|
#include <set>
|
|
#include <JUI/Mixins/Clickable.hpp>
|
|
|
|
#include "TextRect.hpp"
|
|
|
|
namespace JUI {
|
|
|
|
// TODO: Text Selection
|
|
// TODO: Support Copy
|
|
// TODO: Support Paste
|
|
// TODO: Support Cut
|
|
// TODO: Support insert at cursor
|
|
// TODO: Simulate key repeat.
|
|
|
|
class TextInputForm : public TextRect, public Clickable {
|
|
public:
|
|
#pragma region Events
|
|
Event<> OnSelect;
|
|
Event<> OnDeselect;
|
|
Event<std::string> OnReturn;
|
|
#pragma endregion
|
|
public:
|
|
#pragma region Constructors
|
|
TextInputForm();
|
|
explicit TextInputForm(Widget* parent);
|
|
#pragma endregion
|
|
public:
|
|
#pragma region Methods
|
|
void Update(float elapsed) override;
|
|
void InnerDraw() override;
|
|
void Draw() override;
|
|
/// @return The number of characters the cursor is actually moved to the left by.
|
|
int MoveCursorLeft(int chars = 1);
|
|
/// @note The amount of
|
|
/// @return The number of characters the cursor is actually moved to the right by.
|
|
int MoveCursorRight(int chars = 1);
|
|
#pragma region Getters
|
|
|
|
#pragma endregion
|
|
#pragma region Setters
|
|
|
|
#pragma endregion
|
|
|
|
/// Returns the maximum position of the cursor, which is determined by the input buffer's length.
|
|
[[nodiscard]] unsigned int CursorMaxPosition() const;
|
|
|
|
void SetCursorPosition(unsigned int pos);
|
|
|
|
/// Fires the input event, clears the input buffer, and sets the state to be ready for further input.
|
|
void SendInput(bool clear_input);
|
|
|
|
/// Copy the contents of the input form, or the selection if active, into the the system's clipboard.
|
|
void Copy();
|
|
/// Paste the contents of the system's clipboard
|
|
void Paste();
|
|
|
|
void Cut();
|
|
|
|
void Backspace();
|
|
|
|
void Delete();
|
|
|
|
void PushStringToCurrentPlaceInInputBuffer(const std::string &snippet);
|
|
|
|
void PushKeyToCurrentPlaceInInputBuffer(const Key &key);
|
|
|
|
bool ObserveKeyInput(Key key, bool pressed) override;
|
|
|
|
void ShowNextHistory();
|
|
|
|
void ShowPrevHistory();
|
|
|
|
bool ObserveMouseInput(MouseButton btn, bool pressed) override;
|
|
bool ObserveMouseMovement(const Vector2 &latest_known_pos) override;
|
|
[[nodiscard]] std::string GetAutocompleteText() const;
|
|
void SetAutoCompleteText(const std::string& text);
|
|
[[nodiscard]] Color4 GetAutocompleteTextColor() const;
|
|
void SetAutocompleteTextColor(const Color4& color);
|
|
[[nodiscard]] bool HideAutocompleteOnSelect() const;
|
|
void SetHideAutocompleteOnSelect(bool hide);
|
|
[[nodiscard]] bool AutocompleteTextEnabled() const;
|
|
void SetAutocompleteTextEnabled(bool enabled);
|
|
|
|
[[nodiscard]] std::string InputBuffer() const;
|
|
void SetInputBuffer(const std::string& value);
|
|
void ClearInputBuffer();
|
|
|
|
|
|
[[nodiscard]] bool HasFocus() const;
|
|
void SetFocused(bool focused);
|
|
|
|
// TODO: Implement procedure to allow API consumer to validate the input, **before** clearing the buffer.
|
|
|
|
[[nodiscard]] bool ClearTextOnReturn() const;
|
|
void ClearTextOnReturn(bool value);
|
|
|
|
[[nodiscard]] bool DropFocusOnReturn() const;
|
|
void DropFocusOnReturn(bool value);
|
|
|
|
void GrabFocus();
|
|
void DropFocus();
|
|
|
|
[[nodiscard]] std::set<std::string> GetBlacklist() const;
|
|
void SetBlacklist(const std::set<std::string>& value);
|
|
void AddToBlacklist(const std::string& value);
|
|
|
|
// TODO: Implement selection of part of input text.
|
|
Color4 GetSelectionColor() const;
|
|
void SetSelectionColor(const Color4& color);
|
|
bool HasSelection() const;
|
|
std::string GetSelectedText() const;
|
|
|
|
[[nodiscard]] bool KeepInputHistory() const;
|
|
|
|
void KeepInputHistory(bool value);
|
|
|
|
std::string InputHistory(int index) const;
|
|
|
|
#pragma endregion
|
|
protected:
|
|
#pragma region Properties
|
|
bool keep_input_history = false;
|
|
bool clear_text_on_return = true;
|
|
bool drop_focus_on_return = false;
|
|
bool focused = false;
|
|
|
|
float cursor_blink_time = 0.f;
|
|
Color4 autocomplete_color = Style::InputForm::AutocompleteTextColor;
|
|
std::string autocomplete_text = "Hello World";
|
|
bool hide_autocomplete_on_select = true;
|
|
bool autocomplete_text_enabled = true;
|
|
std::set<std::string> blacklist;
|
|
bool selection_enabled;
|
|
#pragma endregion
|
|
#pragma region Working Variables
|
|
std::vector<std::string> history;
|
|
int history_index = -1;
|
|
bool selection_active;
|
|
int selection_start_index;
|
|
int selection_end_index;
|
|
unsigned int cursor_position = 0;
|
|
std::string input_buffer;
|
|
std::string saved_input_buffer;
|
|
|
|
|
|
/// Tracks the time (in seconds) since the TextInputForm was last opened.
|
|
/// @note This is used to circumvent a behavioral bug caused by how the input code is structured:
|
|
/// 1. User clicks a button that opens an InputForm.
|
|
/// 2. Grab InputForm Focus.
|
|
/// 3. User releases the button.
|
|
/// 4. The input form interprets this as "I am focused, but something else was just clicked".
|
|
/// 5. The input form drops its focus instantly, and it appears as if it was never focused.
|
|
float time_focused = 0.f;
|
|
#pragma endregion
|
|
|
|
private:
|
|
};
|
|
} |