wut/include/nn/swkbd/swkbd_cpp.h

565 lines
13 KiB
C
Raw Normal View History

2018-06-13 12:12:22 +01:00
#pragma once
#include <wut.h>
#include <coreinit/filesystem.h>
#include <nn/result.h>
#include <padscore/kpad.h>
#include <vpad/input.h>
#include <string.h>
/**
2018-06-14 13:34:39 +01:00
* \defgroup nn_swkbd_swkbd Software Keyboard
2018-06-13 12:12:22 +01:00
* \ingroup nn_swkbd
* See \link nn::swkbd \endlink.
*
2018-06-13 12:12:22 +01:00
* @{
*/
#ifdef __cplusplus
namespace nn
{
/**
* Graphical software keyboard, supporting several languages and configurations.
* Applications should first call \link Create \endlink to initialise the
* library, followed by \link AppearInputForm \endlink to show a text area and
* virtual keyboard. Input should be forwarded to the keyboard via
* \link Calc \endlink, along with calls to \link CalcSubThreadFont \endlink and
* \link CalcSubThreadPredict \endlink. Finally, the keyboard can be rendered
* with \link DrawTV \endlink and \link DrawDRC \endlink. The user's interaction
* with the keyboard can be tracked with \link GetInputFormString \endlink,
* \link IsDecideOkButton \endlink and \link IsDecideCancelButton \endlink; and
* once satisfied the application can dismiss the keyboard with
* \link DisappearInputForm \endlink. Don't forget \link Destroy \endlink!
*/
2018-06-13 12:12:22 +01:00
namespace swkbd
{
enum class ControllerType
{
Unknown0 = 0,
};
enum class LanguageType
{
Japanese = 0,
English = 1,
};
enum class RegionType
{
Japan = 0,
USA = 1,
Europe = 2,
};
enum class State
{
//! The input form / keyboard is completely hidden.
Hidden = 0,
//! The input form / keyboard is drawing the fade in animation.
FadeIn = 1,
//! The input form / keyboard is done drawing the fade in animation and completely visible.
Visible = 2,
//! The input form / keyboard is drawing the fade out animation.
FadeOut = 3,
2018-06-13 12:12:22 +01:00
};
//! Configuration options for the virtual keyboard.
2018-06-13 12:12:22 +01:00
struct ConfigArg
{
ConfigArg()
{
memset(this, 0, sizeof(*this));
languageType = LanguageType::English;
unk_0x04 = 4;
unk_0x0C = 0x7FFFF;
unk_0x10 = 19;
unk_0x14 = -1;
unk_0x9C = 1;
unk_0xA4 = -1;
}
//! The language to use for input
2018-06-13 12:12:22 +01:00
LanguageType languageType;
uint32_t unk_0x04;
uint32_t unk_0x08;
uint32_t unk_0x0C;
uint32_t unk_0x10;
int32_t unk_0x14;
2018-06-20 10:31:53 +01:00
WUT_UNKNOWN_BYTES(0x9C - 0x18);
2018-06-13 12:12:22 +01:00
uint32_t unk_0x9C;
2018-06-20 10:31:53 +01:00
WUT_UNKNOWN_BYTES(4);
2018-06-13 12:12:22 +01:00
int32_t unk_0xA4;
};
WUT_CHECK_OFFSET(ConfigArg, 0x00, languageType);
WUT_CHECK_OFFSET(ConfigArg, 0x04, unk_0x04);
WUT_CHECK_OFFSET(ConfigArg, 0x08, unk_0x08);
WUT_CHECK_OFFSET(ConfigArg, 0x0C, unk_0x0C);
WUT_CHECK_OFFSET(ConfigArg, 0x10, unk_0x10);
WUT_CHECK_OFFSET(ConfigArg, 0x14, unk_0x14);
WUT_CHECK_OFFSET(ConfigArg, 0x9C, unk_0x9C);
WUT_CHECK_OFFSET(ConfigArg, 0xA4, unk_0xA4);
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(ConfigArg, 0xA8);
2018-06-13 12:12:22 +01:00
struct ReceiverArg
{
uint32_t unk_0x00 = 0;
uint32_t unk_0x04 = 0;
uint32_t unk_0x08 = 0;
int32_t unk_0x0C = -1;
uint32_t unk_0x10 = 0;
int32_t unk_0x14 = -1;
};
WUT_CHECK_OFFSET(ReceiverArg, 0x00, unk_0x00);
WUT_CHECK_OFFSET(ReceiverArg, 0x04, unk_0x04);
WUT_CHECK_OFFSET(ReceiverArg, 0x08, unk_0x08);
WUT_CHECK_OFFSET(ReceiverArg, 0x0C, unk_0x0C);
WUT_CHECK_OFFSET(ReceiverArg, 0x10, unk_0x10);
WUT_CHECK_OFFSET(ReceiverArg, 0x14, unk_0x14);
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(ReceiverArg, 0x18);
2018-06-13 12:12:22 +01:00
//! Arguments for the swkbd keyboard
2018-06-13 12:12:22 +01:00
struct KeyboardArg
{
//! Configuration for the keyboard itself
2018-06-13 12:12:22 +01:00
ConfigArg configArg;
ReceiverArg receiverArg;
};
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(KeyboardArg, 0xC0);
2018-06-13 12:12:22 +01:00
//! Arguments for swkbd the input form (text area).
2018-06-13 12:12:22 +01:00
struct InputFormArg
{
uint32_t unk_0x00 = 1;
int32_t unk_0x04 = -1;
uint32_t unk_0x08 = 0;
uint32_t unk_0x0C = 0;
//! The maximum number of characters that can be entered, -1 for unlimited.
2018-06-13 12:12:22 +01:00
int32_t maxTextLength = -1;
uint32_t unk_0x14 = 0;
uint32_t unk_0x18 = 0;
bool unk_0x1C = false;
bool unk_0x1D = false;
bool unk_0x1E = false;
2018-06-20 10:31:53 +01:00
WUT_PADDING_BYTES(1);
2018-06-13 12:12:22 +01:00
};
WUT_CHECK_OFFSET(InputFormArg, 0x00, unk_0x00);
WUT_CHECK_OFFSET(InputFormArg, 0x04, unk_0x04);
WUT_CHECK_OFFSET(InputFormArg, 0x08, unk_0x08);
WUT_CHECK_OFFSET(InputFormArg, 0x0C, unk_0x0C);
WUT_CHECK_OFFSET(InputFormArg, 0x10, maxTextLength);
WUT_CHECK_OFFSET(InputFormArg, 0x14, unk_0x14);
WUT_CHECK_OFFSET(InputFormArg, 0x18, unk_0x18);
WUT_CHECK_OFFSET(InputFormArg, 0x1C, unk_0x1C);
WUT_CHECK_OFFSET(InputFormArg, 0x1D, unk_0x1D);
WUT_CHECK_OFFSET(InputFormArg, 0x1E, unk_0x1E);
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(InputFormArg, 0x20);
2018-06-13 12:12:22 +01:00
//! Arguments for the swkbd input form and keyboard.
2018-06-13 12:12:22 +01:00
struct AppearArg
{
//! Arguments for the virtual keyboard
2018-06-13 12:12:22 +01:00
KeyboardArg keyboardArg;
//! Arguments for the input form (text area)
2018-06-13 12:12:22 +01:00
InputFormArg inputFormArg;
};
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(AppearArg, 0xE0);
2018-06-13 12:12:22 +01:00
//!The arguments used to initialise swkbd and pass in its required resources.
2018-06-13 12:12:22 +01:00
struct CreateArg
{
//! A pointer to a work memory buffer; see \link GetWorkMemorySize \endlink.
2018-06-13 12:12:22 +01:00
void *workMemory = nullptr;
//! The swkbd region to use.
2018-06-13 12:12:22 +01:00
RegionType regionType = RegionType::Europe;
uint32_t unk_0x08 = 0;
//! An FSClient for swkbd to use while loading resources.
2018-06-13 12:12:22 +01:00
FSClient *fsClient = nullptr;
};
2018-06-20 10:31:53 +01:00
WUT_CHECK_OFFSET(CreateArg, 0x00, workMemory);
WUT_CHECK_OFFSET(CreateArg, 0x04, regionType);
WUT_CHECK_OFFSET(CreateArg, 0x08, unk_0x08);
WUT_CHECK_OFFSET(CreateArg, 0x0C, fsClient);
WUT_CHECK_SIZE(CreateArg, 0x10);
2018-06-13 12:12:22 +01:00
//! Input and controller information for swkbd.
2018-06-13 12:12:22 +01:00
struct ControllerInfo
{
//! DRC input information, see \link VPADRead \endlink.
2018-06-13 12:12:22 +01:00
VPADStatus *vpad = nullptr;
//! Wiimote and extension controller inputs, see \link KPADRead \endlink.
2018-06-13 12:12:22 +01:00
KPADStatus *kpad[4] = { nullptr, nullptr, nullptr, nullptr };
};
2018-06-20 10:31:53 +01:00
WUT_CHECK_OFFSET(ControllerInfo, 0x00, vpad);
WUT_CHECK_OFFSET(ControllerInfo, 0x04, kpad);
WUT_CHECK_SIZE(ControllerInfo, 0x14);
2018-06-13 12:12:22 +01:00
struct DrawStringInfo
{
DrawStringInfo()
{
memset(this, 0, sizeof(*this));
}
2018-06-20 10:31:53 +01:00
WUT_UNKNOWN_BYTES(0x1C);
2018-06-13 12:12:22 +01:00
};
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(DrawStringInfo, 0x1C);
2018-06-13 12:12:22 +01:00
struct KeyboardCondition
{
uint32_t unk_0x00 = 0;
uint32_t unk_0x04 = 0;
};
WUT_CHECK_OFFSET(KeyboardCondition, 0x00, unk_0x00);
WUT_CHECK_OFFSET(KeyboardCondition, 0x04, unk_0x04);
2018-06-20 10:31:53 +01:00
WUT_CHECK_SIZE(KeyboardCondition, 0x8);
2018-06-13 12:12:22 +01:00
struct IEventReceiver;
struct IControllerEventObj;
struct ISoundObj;
/**
* Show an input form (keyboard with text area) with the given configuration.
*
* \param args
* An \link nn::swkbd::AppearArg AppearArg \endlink struct with the desired
* configuration for the keyboard and input form.
*
* \return
* \c true on success, or \c false on error.
*
* \sa
* - \link DisappearInputForm \endlink
* - \link GetInputFormString \endlink
* - \link IsDecideOkButton \endlink
* - \link IsDecideCancelButton \endlink
*/
2018-06-13 12:12:22 +01:00
bool
AppearInputForm(const AppearArg& args);
/**
* Show a keyboard with the given configuration.
*
* \param args
* An \link nn::swkbd::KeyboardArg KeyboardArg \endlink struct with the desired
* configuration for the keyboard.
*
* \return
* \c true on success, or \c false on error.
*
* \sa
* - \link DisappearKeyboard \endlink
* - \link IsDecideOkButton \endlink
* - \link IsDecideCancelButton \endlink
*/
2018-06-13 12:12:22 +01:00
bool
AppearKeyboard(const KeyboardArg& args);
/**
* Calculate font data. Call in response to
* \link IsNeedCalcSubThreadFont \endlink.
*
* \sa
* - \link CalcSubThreadPredict \endlink
* - \link Calc \endlink
*/
2018-06-13 12:12:22 +01:00
void
CalcSubThreadFont();
/**
* Calculate word prediction data. Call in response to
* \link IsNeedCalcSubThreadPredict \endlink.
*
* \sa
* - \link CalcSubThreadFont \endlink
* - \link Calc \endlink
*/
2018-06-13 12:12:22 +01:00
void
CalcSubThreadPredict();
/**
* Respond to user inputs and calculate the state of input buffers and graphics.
*
* \param controllerInfo
* A \link nn::swkbd::ControllerInfo ControllerInfo \endlink structure
* containing fresh data from the controllers (see \link VPADRead \endlink
* and \link KPADRead \endlink). Each controller can also be \c nullptr if data
* is not available.
*
* \sa
* - \link CalcSubThreadFont \endlink
* - \link CalcSubThreadPredict \endlink
*/
2018-06-13 12:12:22 +01:00
void
Calc(const ControllerInfo &controllerInfo);
void
ConfirmUnfixAll();
/**
* Initialise the swkbd library and create the keyboard and input form.
*
* \param args
* A \link nn::swkbd::CreateArg CreateArg \endlink structure containing the
* desired keyboard region, a pointer to work memory, and an
* \link FSClient \endlink. See \link nn::swkbd::CreateArg CreateArg\endlink.
*
* \return
* \c true on success, \c false otherwise.
*
* \sa
* - \link Destroy \endlink
* - \link GetWorkMemorySize \endlink
*/
2018-06-13 12:12:22 +01:00
bool
Create(const CreateArg &args);
/**
* Clean up and shut down the swkbd library.
*
* \note
* Resources passed into \link Create \endlink (work memory, filesystem client)
* must be manually freed by the application <em>after</em> calling this
* function.
*
* \sa
* - \link Create \endlink
*/
2018-06-13 12:12:22 +01:00
void
Destroy();
/**
* Hide a previously shown input form.
*
* \return
* \c true on success, \c false otherwise.
*
* \sa
* - \link AppearInputForm \endlink
* - \link GetInputFormString \endlink
*/
2018-06-13 12:12:22 +01:00
bool
DisappearInputForm();
/**
* Hide a previously shown keyboard.
*
* \return
* \c true on success, \c false otherwise.
*
* \sa
* - \link AppearKeyboard \endlink
*/
2018-06-13 12:12:22 +01:00
bool
DisappearKeyboard();
/**
* Draw the keyboard to the DRC. Must be called inside a valid GX2 rendering
* context, after rendering all other DRC graphics (to appear under the
* keyboard)
*/
2018-06-13 12:12:22 +01:00
void
DrawDRC();
/**
* Draw the keyboard to the TV. Must be called inside a valid GX2 rendering
* context, after rendering all other TV graphics (to appear under the
* keyboard)
*/
2018-06-13 12:12:22 +01:00
void
DrawTV();
void
GetDrawStringInfo(DrawStringInfo *drawStringInfo);
/**
* Get the string the user typed into the input form.
*
* \returns
* The user's text, as a null-terminated UTF-16 string.
*
* \sa
* - \link SetInputFormString \endlink
*/
2018-06-13 12:12:22 +01:00
const char16_t *
GetInputFormString();
void
GetKeyboardCondition(KeyboardCondition *keyboardCondition);
/**
* Get the current state of the input form.
*
* \returns
* The current \link nn::swkbd::State State \endlink of the input form.
*/
2018-06-13 12:12:22 +01:00
State
GetStateInputForm();
State
GetStateKeyboard();
/**
* Get the required size for swkbd's work memory buffer. The application must
* allocate a buffer of this size and pass it into \link Create \endlink.
*
* \param unk
* Unknown. A value of 0 seems to work.
*
* \return
* The required size of the work buffer, in bytes.
*
* \sa
* - \link Create \endlink
*/
2018-06-13 12:12:22 +01:00
uint32_t
GetWorkMemorySize(uint32_t unk);
void
InactivateSelectCursor();
bool
InitLearnDic(void *dictionary);
bool
IsCoveredWithSubWindow();
/**
* Gets the current status of the Cancel button on the keyboard.
*
* \param outIsSelected
* Pointer to a boolean to write the button status to, or \c nullptr if the
* return value is enough.
*
* \return
* \c true if the Cancel button has been pressed, or \c false otherwise.
*
* \sa
* - \link IsDecideOkButton \endlink
*/
2018-06-13 12:12:22 +01:00
bool
IsDecideCancelButton(bool *outIsSelected);
/**
* Gets the current status of the OK button on the keyboard.
*
* \param outIsSelected
* Pointer to a boolean to write the button status to, or \c nullptr if the
* return value is enough.
*
* \return
* \c true if the OK button has been pressed, or \c false otherwise.
*
* \sa
* - \link IsDecideCancelButton \endlink
*/
2018-06-13 12:12:22 +01:00
bool
IsDecideOkButton(bool *outIsSelected);
bool
IsKeyboardTarget(IEventReceiver *eventReceiver);
/**
* Determines whether the font data needs calculating. If it does, a call to
* \link CalcSubThreadFont \endlink is required.
*
* \return
* \c true if the font data needs calculating, \c false otherwise.
*
* \sa
* - \link IsNeedCalcSubThreadPredict \endlink
*/
2018-06-13 12:12:22 +01:00
bool
IsNeedCalcSubThreadFont();
/**
* Determines whether the prediction data needs calculating. If it does, a call
* to \link CalcSubThreadPredict \endlink is required.
*
* \return
* \c true if the prediction data needs calculating, \c false otherwise.
*
* \sa
* - \link IsNeedCalcSubThreadFont \endlink
*/
2018-06-13 12:12:22 +01:00
bool
IsNeedCalcSubThreadPredict();
/**
* Determines whether the selection cursor is active.
*
* \return
* \c true if the selection cursor is active, \c false otherwise.
*/
2018-06-13 12:12:22 +01:00
bool
IsSelectCursorActive();
/**
* Mutes or unmutes the sounds generated by the keyboard.
*
* \param muted
* \c true to disable all sounds, or \c false to enable them.
*/
2018-06-13 12:12:22 +01:00
void
MuteAllSound(bool muted);
void
SetControllerRemo(ControllerType type);
/**
* Set the character at which the cursor is positioned.
*
* \param pos
* The position at which to move the cursor, with 0 corresponding to the start
* of the string (before the first character).
*
* <!--
* TODO: check factual accuracy?
* Does one need to account for multiword UTF-16 characters?
* -->
*/
2018-06-13 12:12:22 +01:00
void
SetCursorPos(int pos);
2018-06-13 12:12:22 +01:00
/**
* Enables and disables the OK button on the keyboard. When disabled, the button
* cannot be pressed.
*
* \param enable
* \c true to enable the button, or \c false to disable it.
*/
2018-06-13 12:12:22 +01:00
void
SetEnableOkButton(bool enable);
2018-06-13 12:12:22 +01:00
/**
* Sets the text in the input form.
*
* \param str
* The UTF-16 string to set the input form to.
*
* \sa
* - \link GetInputFormString \endlink
*/
2018-06-13 12:12:22 +01:00
void
SetInputFormString(const char16_t *str);
void
SetReceiver(const ReceiverArg &receiver);
void
SetSelectFrom(int);
void
SetUserControllerEventObj(IControllerEventObj *controllerEventObj);
void
SetUserSoundObj(ISoundObj *soundObj);
} // namespace swkbd
} // namespace nn
#endif // ifdef __cplusplus
/** @} */