#pragma once #include #include #include #include namespace geode { enum class CommonFilter { // Allow an unsigned integer Uint, // Allow a signed integer Int, // Allow a floating point number Float, // Allow letters, numbers, dashes, underscores, and dots ID, // Allow word-like characters & spaces Name, // Allows basically anything possible to type in an input Any, // Allow a hexadecimal number Hex, // Allow a non-URL-safe Base64 number Base64Normal, // Allow a URL-safe Base64 number Base64URL, }; GEODE_DLL const char* getCommonFilterAllowedChars(CommonFilter filter); enum class TextInputAlign { Center, Left, }; /** * A single-line text input node */ class GEODE_DLL TextInput : public cocos2d::CCNode, public TextInputDelegate { protected: cocos2d::extension::CCScale9Sprite* m_bgSprite; CCTextInputNode* m_input; std::function m_onInput = nullptr; cocos2d::CCLabelBMFont* m_label = nullptr; bool init(float width, std::string const& placeholder, std::string const& font); void textChanged(CCTextInputNode* input) override; public: /** * Create a single-line text input with a background. * Can either be used in delegate or callback mode; * with callback mode, you don't need to deal with adding * TextInputDelegate to your class' base list, you just install a * callback function directly to the input itself * @param width The width of the input * @param placeholder Placeholder text for the input * @param font The font to use */ static TextInput* create(float width, std::string const& placeholder, std::string const& font = "bigFont.fnt"); /** * Set the placeholder label for this input */ void setPlaceholder(std::string const& placeholder); /** * Set a label on this input that shows up on the top. Set an empty * string to remove the label */ void setLabel(std::string const& label); /** * Set the filter (allowed characters) for this input * @param allowedChars String of allowed characters; each character in * the string represents one allowed character */ void setFilter(std::string const& allowedChars); /** * Set a commonly used filter (number, text, etc.) */ void setCommonFilter(CommonFilter filter); /** * Set the maximum amount of characters for this input. Use 0 for * infinite length */ void setMaxCharCount(size_t length); /** * Enable/disable password mode (all input characters are rendered as * dots rather than the actual characters) */ void setPasswordMode(bool enable); /** * Set the width of the label. This does not set the maximum character * count; use `setMaxCharCount` for that */ void setWidth(float width); /** * Install a delegate that handles input events. Removes any currently * set direct callbacks * @param delegate The delegate to install * @param tag Some legacy delegates use a tag to distinguish between * inputs; this is a convenience parameter for setting the tag of the * internal CCTextInputNode for those cases */ void setDelegate(TextInputDelegate* delegate, std::optional tag = std::nullopt); /** * Set a direct callback function that is called when the user types in * the input. Overrides any delegate that is currently installed * @param onInput Function to call when the user changes the value of * the text input */ void setCallback(std::function onInput); /** * Enable/disable the input */ void setEnabled(bool enabled); /** * Align the button's content to the left. If false, aligns to the center */ void setTextAlign(TextInputAlign align); /** * Hides the background of this input. Shorthand for * `input->getBGSprite()->setVisible(false)` */ void hideBG(); /** * Set the value of the input * @param str The new text of the input * @param triggerCallback Whether this should trigger the callback * function / delegate's textChanged event or not */ void setString(std::string const& str, bool triggerCallback = false); /** * Get the current value of the input */ std::string getString() const; CCTextInputNode* getInputNode() const; cocos2d::extension::CCScale9Sprite* getBGSprite() const; }; }