Skip to content

Commit

Permalink
Add ecs widgets related documentations
Browse files Browse the repository at this point in the history
Linked: #92
  • Loading branch information
AndreasLrx committed Jun 9, 2022
1 parent 17bb28c commit c4eb02f
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 27 deletions.
11 changes: 10 additions & 1 deletion src/game/components/Controlable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,20 @@ namespace game
/// @retval false otherwise.
using ActionCallback = std::function<bool(ecs::Entity, ecs::SystemData, const Users::ActionEvent &)>;

/// Id of the user controlling the widget
/// Id of the user controlling the widget.
User::UserId userId;
/// Callback called when an action is detected for the user @c userId.
ActionCallback callback;

/// Construct a new Controlable component.
///
/// @param id id of the user controling the component.
Controlable(User::UserId id) : userId(id) {}

/// Construct a new Controlable component.
///
/// @param id id of the user controling the component.
/// @param pcallback callback called when an action of the listened user is detected.
Controlable(User::UserId id, ActionCallback pcallback) : userId(id), callback(pcallback) {}
};
} // namespace game
Expand Down
9 changes: 9 additions & 0 deletions src/game/components/Textual.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@

namespace game
{
/// Textual element.
struct Textual : public ecs::Component {
/// Text printed.
std::string text;
/// Size of the text.
size_t fontSize;
/// Color of the text.
raylib::core::Color color;

/// Construct a new Textual component.
///
/// @param ptext text printed.
/// @param pfontSize size of the text.
/// @param pcolor color of the text.
Textual(
std::string_view ptext, size_t pfontSize = 20, raylib::core::Color pcolor = raylib::core::Color::LIGHT_GRAY)
: text(ptext), fontSize(pfontSize), color(pcolor)
Expand Down
13 changes: 13 additions & 0 deletions src/game/gui/components/Checkable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,30 @@ namespace game
{
namespace gui
{
/// Checkable component, used for checkbox widgets.
struct Checkable final : public IWidgetComponent {
/// Callback called when the checkbox is checked/unchecked.
///
/// @param ecs::Entity entity @a owning the component.
/// @param bool set to true if the component is checked.
using OnStateChanged = std::function<void(ecs::Entity, bool)>;

/// Callback called when the checkbox is checked/unchecked.
OnStateChanged onStateChanged;
/// Set to true if the component is checked.
bool checked;

/// Construct a new Checkable component
///
/// @param ponStateChanged Callback called when the checkbox is checked/unchecked.
/// @param startChecked set to true if the component must start checked.
///
Checkable(OnStateChanged ponStateChanged, bool startChecked = false)
: onStateChanged(ponStateChanged), checked(startChecked)
{
}

/// @copydoc IWidgetComponent::update.
bool update(ecs::Entity self, ecs::SystemData data, const Users::ActionEvent &event) override final;
};
} // namespace gui
Expand Down
2 changes: 1 addition & 1 deletion src/game/gui/components/Clickable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ namespace game
return true;
};
} // namespace gui
} // namespace game
} // namespace game
27 changes: 26 additions & 1 deletion src/game/gui/components/Clickable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,47 @@ namespace game
{
namespace gui
{
/// Clickable component.
struct Clickable final : public IWidgetComponent {
enum class State { Default, Pressed };
/// State of the component.
enum class State {
Default, /// Default state
Pressed, /// The component is pressed and the OnClick event will be executed when it will be released
};

/// Callback called when the component state change from pressed to default.
///
/// @param ecs::Entityentity @a owning the component.
using OnClick = std::function<void(ecs::Entity)>;

/// Callback called when the component state change.
///
/// @param ecs::Entity entity @a owning the component.
/// @param State current state.
using OnStateChanged = std::function<void(ecs::Entity, State)>;

/// Current state.
State state;
/// On click callback.
OnClick onClick;
/// On State changed callback
OnStateChanged onStateChanged;

/// Construct a new Clickable component.
///
/// @param ponClick on click callback.
Clickable(OnClick ponClick) : state(State::Default), onClick(ponClick) {}

/// Construct a new Clickable component
///
/// @param ponClick on click callback.
/// @param ponStateChanged on state changed callback.
Clickable(OnClick ponClick, OnStateChanged ponStateChanged)
: state(State::Default), onClick(ponClick), onStateChanged(ponStateChanged)
{
}

/// @copydoc IWidgetComponent::update.
bool update(ecs::Entity self, ecs::SystemData data, const Users::ActionEvent &event) override final;
};
} // namespace gui
Expand Down
9 changes: 8 additions & 1 deletion src/game/gui/components/IWidgetComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@
#include "ecs/System.hpp"
#include "game/Users.hpp"


namespace game
{
namespace gui
{
/// Base class for all widgets components
class IWidgetComponent : public ecs::Component {
public:
/// Update the widget with the given action.
///
/// @param self entity @a owning the component.
/// @param ecs::SystemData view on the world.
/// @param const Users::ActionEvent& informations about the action detected.
/// @retval true if the action was consumed.
/// @retval false if the action wasn't used.
virtual bool update(ecs::Entity self, ecs::SystemData data, const Users::ActionEvent &event) = 0;
};
} // namespace gui
Expand Down
4 changes: 2 additions & 2 deletions src/game/gui/components/Widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace game
&& (event.action != GameAction::MOVE_UP || up == NullTag)
&& (event.action != GameAction::MOVE_DOWN || down == NullTag)))
return false;
WidgetTag newSelected;
WidgetId newSelected;

switch (event.action) {
case GameAction::MOVE_LEFT: newSelected = left; break;
Expand All @@ -53,4 +53,4 @@ namespace game
return false;
}
} // namespace gui
} // namespace game
} // namespace game
67 changes: 50 additions & 17 deletions src/game/gui/components/Widget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,62 @@
#ifndef GAME_GUI_COMPONENTS_WIDGET_HPP_
#define GAME_GUI_COMPONENTS_WIDGET_HPP_

#include "ecs/Component.hpp"
#include "ecs/Entity.hpp"
#include "IWidgetComponent.hpp"
#include "ecs/Storage.hpp"
#include "ecs/System.hpp"
#include "game/Users.hpp"

namespace game
{
namespace gui
{
struct Widget : public ecs::Component {
using WidgetTag = size_t;
static constexpr WidgetTag NullTag = -1;
WidgetTag tag;

WidgetTag left;
WidgetTag right;
WidgetTag up;
WidgetTag down;
/// Widget component.
struct Widget final : public IWidgetComponent {
/// Widget Id, mandatory to link widgets together.
using WidgetId = size_t;
/// Id meaning none.
static constexpr WidgetId NullTag = -1;
/// Id of the widget
WidgetId id;

/// Id of the left widget
WidgetId left;
/// Id of the right widget
WidgetId right;
/// Id of the top widget
WidgetId up;
/// Id of the bottom widget
WidgetId down;
/// If the widget is the one selected
bool selected;

Widget(WidgetTag ptag, WidgetTag pleft = NullTag, WidgetTag pright = NullTag, WidgetTag pup = NullTag,
WidgetTag pdown = NullTag, bool pselected = false)
: tag(ptag), left(pleft), right(pright), up(pup), down(pdown), selected(pselected)
/// Construct a new Widget component
/// @warning Only one widget should be selected, multiple widgets selected may lead to undefined behavior.
///
/// @param pid id of the widget.
/// @param pleft id of the left widget.
/// @param pright id of the right widget.
/// @param pup id of the top widget.
/// @param pdown id of the bottom widget.
/// @param pselected if the widget is selected.
///
Widget(WidgetId pid, WidgetId pleft = NullTag, WidgetId pright = NullTag, WidgetId pup = NullTag,
WidgetId pdown = NullTag, bool pselected = false)
: id(pid), left(pleft), right(pright), up(pup), down(pdown), selected(pselected)
{
}

bool update(ecs::Entity self, ecs::SystemData data, const Users::ActionEvent &event);
/// @copydoc IWidgetComponent::update
bool update(ecs::Entity self, ecs::SystemData data, const Users::ActionEvent &event) override final;

private:
/// Try to update a widget as a given component.
///
/// @tparam T widget component to test.
/// @param self entity @a owning the component.
/// @param data view on the world.
/// @param event action event.
/// @return true if the component consumed the event
/// @return false if the event wasn't used.
///
template <typename T>
static bool tryUpdate(ecs::Entity self, ecs::SystemData data, const Users::ActionEvent &event)
{
Expand All @@ -53,6 +79,13 @@ namespace game
}
}

/// Update the selected widget.
///
/// @param data view on the world.
/// @param event action event.
/// @return true if the selection changed
/// @return false if the selected widget hasn't changed.
///
bool updateSelection(ecs::SystemData data, const Users::ActionEvent &event);
};
} // namespace gui
Expand Down
4 changes: 4 additions & 0 deletions src/game/systems/DrawText.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@

namespace game
{
/// Draw text system.
struct DrawText : public ecs::System {
/// Draw all the entities with the components Position and Textual.
///
/// @param data view on the world.
void run(ecs::SystemData data) override final;
};
} // namespace game
Expand Down
4 changes: 0 additions & 4 deletions src/game/systems/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@

#include "InputManager.hpp"
#include "components/Controlable.hpp"
#include "ecs/Storage.hpp"
#include "ecs/World.hpp"
#include "ecs/join.hpp"
#include "ecs/system/SystemData.hpp"
#include "game/Users.hpp"
#include "game/gui/components/Widget.hpp"

namespace game
Expand Down
7 changes: 7 additions & 0 deletions src/game/systems/InputManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@

namespace game
{
/// System managing all the users inputs.
struct InputManager : public ecs::System {
/// Retreive all the users @ref Users::ActionEvent and send them to the controlable entities matching the
/// UserId.
///
/// @note Widgets will receive the events only if they are selected.
///
/// @param data view on the world.
void run(ecs::SystemData data) override final;

private:
Expand Down

0 comments on commit c4eb02f

Please sign in to comment.