Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/demo/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) {
Widgets::button(7, RootPanelId, "Quit", Rect(100, 250, 100, ButtonHeight), dynamicQuitCallback);
Widgets::progressBar(8, RootPanelId, Rect(100, 300, 100, ButtonHeight), 50, dynamicUpdateProgressBarCallback);

Widgets::inputText(9, RootPanelId, Rect(100, 350, 100, ButtonHeight), Alignment::Left);
Widgets::inputText(9, RootPanelId, Rect(100, 350, 100, ButtonHeight), Alignment::Left, KeyInputType::Character, "");

Widgets::treeView(10, RootPanelId, "tree", Rect(100, 400, 100, ButtonHeight));
Widgets::treeItem(11, 10, "Item 1");
Expand Down
4 changes: 4 additions & 0 deletions src/backends/sdl2_iodevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ uint32_t IODevice::getTicks() {
return SDL_GetTicks();
}

void IODevice::delay(uint32_t ms) {
SDL_Delay(ms);
}

} // namespace tinyui
4 changes: 4 additions & 0 deletions src/backends/sdl2_iodevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ struct IODevice {
/// @brief Get the current ticks from the io-device.
/// @return The current ticks.
static uint32_t getTicks();

/// @brief Delay the execution for a given amount of milliseconds.
/// @param ms The amount of milliseconds to delay.
static void delay(uint32_t ms);
};

} // namespace tinyui
6 changes: 4 additions & 2 deletions src/backends/sdl2_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,14 @@ ret_code Renderer::drawText(Context &ctx, const char *string, Font *font, const
if (ctx.mStyle.mFont.mName != nullptr) {
loadFont(ctx);
if (font == nullptr) {
const std::string msg = "Cannot load font: " + std::string(ctx.mStyle.mFont.mName) + ", using the default font.";
ctx.mLogger(LogSeverity::Error, msg.c_str());
font = ctx.mDefaultFont;
}
}
}

font = ctx.mDefaultFont;

if (font == nullptr) {
return InvalidHandle;
}
Expand Down Expand Up @@ -446,7 +448,7 @@ ret_code Renderer::createRenderTexture(Context &ctx, int w, int h, SDL_Texture *
}

bool Renderer::update(Context &ctx) {
if (!ctx.mCreated) {
if (!ctx.mCreated) {
return false;
}

Expand Down
63 changes: 52 additions & 11 deletions src/widgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,35 @@
return widget;
}

static void deleteKeyFromText(Context &ctx) {
ctx.mFocus->mText.erase(ctx.mFocus->mText.size() - 1);
}

static void appendKeyToText(Context &ctx, char *buffer) {
ctx.mFocus->mText.append(buffer);
}

static void handleInputField(Context &ctx, EventPayload *eventPayload) {
char buffer[2] = {

Check warning on line 157 in src/widgets.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use "std::string" instead of a C-style char array.

See more on https://sonarcloud.io/project/issues?id=kimkulling_tiny_ui&issues=AZ1KbgMs8ggMi9t8ePBB&open=AZ1KbgMs8ggMi9t8ePBB&pullRequest=27
static_cast<char>(eventPayload->payload[0]),
'\0'
};
if (buffer[0] == SDLK_BACKSPACE) {
deleteKeyFromText(ctx);
} else {
appendKeyToText(ctx, buffer);
}
}

void eventDispatcher(Context &ctx, int32_t eventId, EventPayload *eventPayload) {
if (ctx.mFocus == nullptr) {
return;
}

if (eventId == Events::KeyDownEvent || eventId == Events::KeyUpEvent) {
if (eventId == Events::KeyDownEvent) {
if (eventPayload != nullptr) {
if (ctx.mFocus->mType == WidgetType::InputField) {
char buffer[2] = { eventPayload->payload[0], '\0' };
ctx.mFocus->mText.append(buffer);
handleInputField(ctx, eventPayload);
}
}
}
Expand Down Expand Up @@ -242,7 +261,18 @@
return ResultOk;
}

ret_code Widgets::inputText(Id id, Id parentId, const Rect &rect, Alignment alignment) {
static int inputHandler(Id id, void *instance) {
if (instance == nullptr) {
return ErrorCode;
}

Context *ctx = static_cast<Context *>(instance);

Check warning on line 269 in src/widgets.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace the redundant type with "auto".

See more on https://sonarcloud.io/project/issues?id=kimkulling_tiny_ui&issues=AZ1KVJyGiHvwwFcAXTb1&open=AZ1KVJyGiHvwwFcAXTb1&pullRequest=27
ctx->mFocus = Widgets::findWidget(id, ctx->mRoot);

return ResultOk;
}

ret_code Widgets::inputText(Id id, Id parentId, const Rect &rect, Alignment alignment, KeyInputType type, const char *defaultText) {
auto &ctx = TinyUi::getContext();
if (ctx.mBackendCtx == nullptr) {
return InvalidRenderHandle;
Expand All @@ -258,6 +288,12 @@
}

widget->mAlignment = alignment;
widget->mKeyInputType = type;
if (defaultText != nullptr) {
widget->mText.assign(defaultText);
}

widget->mCallback = new CallbackI(inputHandler, (void *)&ctx, Events::MouseButtonDownEvent);

return ResultOk;
}
Expand Down Expand Up @@ -402,7 +438,6 @@
return ErrorCode;
}


if (title != nullptr) {
widget->mText.assign(title);
}
Expand Down Expand Up @@ -437,7 +472,7 @@
const int32_t w = parentRect.width;
const int32_t h = parentRect.height;
size_t numChildren = parentWidget->mChildren.size() + 1;
const Rect rect(parentRect.top.x + margin, parentRect.top.y + numChildren * margin +
const Rect rect(parentRect.top.x + margin, parentRect.top.y + static_cast<int32_t>(numChildren) * margin +
static_cast<int32_t>(numChildren) * h, w, h);
Widget *child = createWidget(ctx, id, parentItemId, rect, WidgetType::Label);
if (child == nullptr) {
Expand Down Expand Up @@ -558,11 +593,17 @@
break;

case WidgetType::InputField:
{
Renderer::drawRect(ctx, r.top.x, r.top.y, r.width, r.height, true, ctx.mStyle.mFg);
Renderer::drawRect(ctx, r.top.x+2, r.top.y+2, r.width-4, r.height-4, true, ctx.mStyle.mBorder);
}
break;
{
Renderer::drawRect(ctx, r.top.x, r.top.y, r.width, r.height, true, ctx.mStyle.mFg);
Renderer::drawRect(ctx, r.top.x+2, r.top.y+2, r.width-4, r.height-4, true, ctx.mStyle.mBorder);
if (!currentWidget->mText.empty()) {
const Color4 fg = ctx.mStyle.mTextColor;
const Color4 bg = ctx.mStyle.mBg;
Renderer::drawText(ctx, currentWidget->mText.c_str(), ctx.mDefaultFont,
currentWidget->mRect, fg, bg, currentWidget->mAlignment);
}
}
break;

case WidgetType::Container:
case WidgetType::Box:
Expand Down
59 changes: 39 additions & 20 deletions src/widgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ enum class LayoutPolicy {
Count ///< The number of layouts
};

enum class KeyInputType {
Invalid = -1, ///< Not initialized
Character, ///< A character input
Password, ///< A special key input
Numeric, ///< A numeric input
Count ///< The number of key input types
};

/// @brief This struct is used to describe the filled state as a payload.
struct FilledState {
uint32_t filledState{0}; ///< The filled state in percent (0-100)
Expand All @@ -70,20 +78,21 @@ using WidgetArray = std::vector<Widget*>;

/// @brief This struct contains all the data which is needed to describe a widget.
struct Widget {
Id mId{0}; ///< The unique id of the widget
WidgetType mType{WidgetType::Invalid}; ///< The type of the widget
Widget *mParent{nullptr}; ///< The parent widget
bool mEnabled{true}; ///< The enabled state of the widget
Rect mRect{}; ///< The rectangle of the widget
bool mFilledRect{true}; ///< The filled rectangle state
uint32_t mStyles{0u}; ///< The style of the widget
Alignment mAlignment{Alignment::Left}; ///< The alignment of the widget
std::string mText{}; ///< The label text
Image *mImage{nullptr}; ///< The image of the widget
WidgetArray mChildren{}; ///< The children of the widget
CallbackI *mCallback{nullptr}; ///< The callback of the widget
uint8_t *mContent{nullptr}; ///< The content of the widget
uint32_t mIntention{0}; ///< The interaction intention.
Id mId{0}; ///< The unique id of the widget
WidgetType mType{WidgetType::Invalid}; ///< The type of the widget
Widget *mParent{nullptr}; ///< The parent widget
bool mEnabled{true}; ///< The enabled state of the widget
Rect mRect{}; ///< The rectangle of the widget
bool mFilledRect{true}; ///< The filled rectangle state
uint32_t mStyles{0u}; ///< The style of the widget
Alignment mAlignment{Alignment::Left}; ///< The alignment of the widget
KeyInputType mKeyInputType{ KeyInputType::Invalid }; ///< The type of the key input
std::string mText{}; ///< The label text
Image *mImage{nullptr}; ///< The image of the widget
WidgetArray mChildren{}; ///< The children of the widget
CallbackI *mCallback{nullptr}; ///< The callback of the widget
uint8_t *mContent{nullptr}; ///< The content of the widget
uint32_t mIntention{0}; ///< The interaction intention.

/// @brief The default class constructor.
Widget() = default;
Expand Down Expand Up @@ -161,6 +170,14 @@ struct Widgets {
/// @param filled The filled state of the widget.
/// @return ResultOk if the widget was created, ErrorCode if not.
static ret_code box(Id id, Id parentId, const Rect &rect, bool filled);

/// @brief Create a new widget from the type image box.
/// @param id The unique id of the widget.
/// @param parentId The parent id of the widget.
/// @param image The image of the widget.
/// @param rect The rect of the widget.
/// @param filled The filled state of the widget.
/// @return ResultOk if the widget was created, ErrorCode if not.
static ret_code imageBox(Id id, Id parentId, const char *image, const Rect &rect, bool filled);

/// @brief Will look for a widget by its id.
Expand All @@ -187,13 +204,15 @@ struct Widgets {
static ret_code label(Id id, Id parentId, const char *text, const Rect &rect, Alignment alignment);

/// @brief Creates a new widget from the type textfield.
/// @param ctx The context to create the widget in.
/// @param id The unique id of the widget.
/// @param parentId The parent id of the widget.
/// @param rect The rect of the widget.
/// @param alignment The alignment of the widget.
/// @param ctx The context to create the widget in.
/// @param id The unique id of the widget.
/// @param parentId The parent id of the widget.
/// @param rect The rect of the widget.
/// @param alignment The alignment of the widget.
/// @param type The type of the key input.
/// @param defaultText The default text of the widget.
/// @return ResultOk if the widget was created, ErrorCode if not.
static ret_code inputText(Id id, Id parentId, const Rect &rect, Alignment alignment);
static ret_code inputText(Id id, Id parentId, const Rect &rect, Alignment alignment, KeyInputType type, const char *defaultText);

/// @brief Creates a new text button.
/// @param ctx The context to create the widget in.
Expand Down
Loading