Skip to content

Commit

Permalink
[LuaGUI] Text input definition added.
Browse files Browse the repository at this point in the history
[creative_inventory] Now has a search bar!
  • Loading branch information
Unarelith committed Jul 28, 2020
1 parent 4337868 commit ef5ac1d
Show file tree
Hide file tree
Showing 16 changed files with 318 additions and 27 deletions.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [Inventory widget](lua-api-gui-inventory.md)
- [Progress bar](lua-api-gui-progress-bar.md)
- [Scroll bar](lua-api-gui-scroll-bar.md)
- [Text input](lua-api-gui-text-input.md)

# Misc

Expand Down
2 changes: 1 addition & 1 deletion docs/lua-api-gui-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ gui:inventory {
Use a group as a filter for this inventory widget.

Example:
```
```lua
filter = "group:om_fuel"
```

Expand Down
91 changes: 91 additions & 0 deletions docs/lua-api-gui-text-input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Lua API: Text Input

**Note:** This only purpose of this atm is to filter items in an inventory widget. More uses will come later.

## Example

```lua
gui:text_input {
name = "inv_filter",
pos = {x = 82, y = 6},

width = 86,
height = 8,

placeholder = "Search...",
placeholder_color = {192, 192, 192},

inventory = "inv_creative_items"
}
```

## Attributes

### `height`

Height of the widget. **Mandatory field.**

Example:
```lua
height = 100
```

### `inventory`

Name of the inventory widget to filter.

Example:
```lua
inventory = "inv_blocks"
```

### `name`

Name of the widget. **Mandatory field.**

Example:
```lua
name = "inv_main"
```

### `placeholder`

Placeholder text displayed when the box is empty.

Example:
```lua
placeholder = "Search..."
```

### `placeholder_color`

Placeholder text color.

Example:
```lua
placeholder_color = {192, 192, 192}
```

**Note:** Alpha is optional, defaults to max value (`255`).

### `pos`

Position of the widget. **Mandatory field.**

Example:
```lua
pos = {
x = 0,
y = 0
}
```

### `width`

Width of the widget. **Mandatory field.**

Example:
```lua
width = 100
```

1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ nav:
- 'Inventory widget': 'lua-api-gui-inventory.md'
- 'Progress bar': 'lua-api-gui-progress-bar.md'
- 'Scroll bar': 'lua-api-gui-scroll-bar.md'
- 'Text input': 'lua-api-gui-text-input.md'
- 'Misc':
- 'Network Protocol': 'network-protocol.md'

Expand Down
13 changes: 13 additions & 0 deletions mods/creative_inventory/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ mod:key {
size = {x = 9, y = 7}
}

gui:text_input {
name = "inv_input_filter",
pos = {x = 82, y = 6},

width = 86,
height = 8,

placeholder = "Search...",
placeholder_color = {192, 192, 192},

inventory = "inv_creative_items"
}

gui:scroll_bar {
name = "scroll_bar",
pos = {x = 175, y = 18},
Expand Down
29 changes: 23 additions & 6 deletions source/client/gui/InventoryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ void InventoryWidget::update() {
sendUpdatePacket();
}

void InventoryWidget::applySearch(const std::string &search) {
if (search != m_lastSearch) {
loadItemWidgets(m_offset, m_size, search);
m_lastSearch = search;
}
}

bool InventoryWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) {
if (dest->doItemMatchFilter(itemStack->stack().item())) {
ItemStack stackRet = dest->receiveItemStack(itemStack, this);
Expand Down Expand Up @@ -128,15 +135,25 @@ void InventoryWidget::draw(gk::RenderTarget &target, gk::RenderStates states) co
target.draw(m_selectedItemBackground, states);
}

void InventoryWidget::loadItemWidgets(u16 offset, u16 size) {
void InventoryWidget::loadItemWidgets(u16 offset, u16 size, std::string search) {
m_itemWidgets.clear();

u16 itemCounter = 0;
for (u16 i = 0 ; i < size ; ++i) {
m_itemWidgets.emplace_back(*m_inventory, (i + offset) % m_inventory->width(), (i + offset) / m_inventory->width(), this);

ItemWidget &widget = m_itemWidgets.back();
widget.update();
widget.setPosition((i % m_inventory->width()) * 18, (i / m_inventory->width()) * 18, 0);
u16 x = (i + offset) % m_inventory->width();
u16 y = (i + offset) / m_inventory->width();
std::string label = m_inventory->getStack(x, y).item().label();
std::transform(label.begin(), label.end(), label.begin(), [](unsigned char c) { return std::tolower(c); });
std::transform(search.begin(), search.end(), search.begin(), [](unsigned char c) { return std::tolower(c); });
if (search.empty() || label.find(search) != std::string::npos) {
m_itemWidgets.emplace_back(*m_inventory, x, y, this);

ItemWidget &widget = m_itemWidgets.back();
widget.update();
widget.setPosition((itemCounter % m_inventory->width()) * 18, (itemCounter / m_inventory->width()) * 18, 0);

itemCounter++;
}
}
}

6 changes: 5 additions & 1 deletion source/client/gui/InventoryWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class InventoryWidget : public AbstractInventoryWidget {

void update() override;

void applySearch(const std::string &search);

bool sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) override;
ItemStack receiveItemStack(const ItemWidget *itemStack, AbstractInventoryWidget *src) override;

Expand All @@ -59,7 +61,7 @@ class InventoryWidget : public AbstractInventoryWidget {
private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;

void loadItemWidgets(u16 offset, u16 size);
void loadItemWidgets(u16 offset, u16 size, std::string search = "");

ClientCommandHandler &m_client;

Expand All @@ -75,6 +77,8 @@ class InventoryWidget : public AbstractInventoryWidget {
ItemWidget *m_currentItemWidget = nullptr;

gk::RectangleShape m_selectedItemBackground{16, 16, gk::Color{255, 255, 255, 80}};

std::string m_lastSearch;
};

#endif // INVENTORYWIDGET_HPP_
11 changes: 2 additions & 9 deletions source/client/gui/TextInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,15 @@

#include "TextInput.hpp"

TextInput::TextInput() {
TextInput::TextInput(Widget *parent) : Widget(parent) {
m_cursor.setString("_");

m_placeholder.setColor(gk::Color(150, 150, 150));
}

void TextInput::onEvent(const SDL_Event &event) {
if (event.type == SDL_MOUSEBUTTONDOWN) {
gk::FloatRect rect{
getPosition().x,
getPosition().y,
getBackgroundSize().x * getScale().x,
getBackgroundSize().y * getScale().y
};

m_hasFocus = rect.contains(event.button.x, event.button.y);
m_hasFocus = isPointInWidget(event.button.x, event.button.y);
}
else if (m_hasFocus) {
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_BACKSPACE && !m_content.empty()) {
Expand Down
15 changes: 11 additions & 4 deletions source/client/gui/TextInput.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,34 @@
#include <gk/core/SDLHeaders.hpp>

#include "Text.hpp"
#include "Widget.hpp"

class TextInput : public gk::Drawable, public gk::Transformable {
class TextInput : public Widget {
public:
TextInput();
TextInput(Widget *parent = nullptr);

void onEvent(const SDL_Event &event);
void onEvent(const SDL_Event &event) override;

const std::string &string() const { return m_content; }
void setString(const std::string &string);

gk::Vector2f getBackgroundSize() const { return m_text.getBackgroundSize(); }

void setBackgroundColor(const gk::Color &color) { m_text.setBackgroundColor(color); }
void setBackgroundSize(unsigned int width, unsigned int height) { m_text.setBackgroundSize(width, height); }
void setBackgroundOutline(int thickness, const gk::Color &color) { m_text.setBackgroundOutline(thickness, color); }
void setBackgroundSize(unsigned int width, unsigned int height) {
m_text.setBackgroundSize(width, height);
m_width = width;
m_height = height;
}

void setPadding(int x, int y) { m_text.setPadding(x, y); m_cursor.setPadding(x, y); m_placeholder.setPadding(x, y); }
void setCharacterLimit(u16 characterLimit) { m_characterLimit = characterLimit; }

void setPlaceholder(const std::string &placeholder) { m_placeholder.setString(placeholder); }
void setPlaceholderColor(const gk::Color &color) { m_placeholder.setColor(color); }

bool hasFocus() const { return m_hasFocus; }
void setFocus(bool hasFocus) { m_hasFocus = hasFocus; }

private:
Expand Down
56 changes: 51 additions & 5 deletions source/client/states/LuaGUIState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,25 @@ void LuaGUIState::onEvent(const SDL_Event &event) {

if (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE
|| (m_keyID >= 0 && event.key.keysym.sym == Registry::getInstance().getKey(m_keyID).keycode()))) {
gk::Mouse::setCursorGrabbed(true);
gk::Mouse::setCursorVisible(false);
gk::Mouse::resetToWindowCenter();
bool ignoreExit = false;
for (auto &it : m_textInputs) {
if (it.second.hasFocus()) {
ignoreExit = true;

isActive = false;
if (event.key.keysym.sym == SDLK_ESCAPE)
it.second.setFocus(false);
}
}

if (!ignoreExit) {
gk::Mouse::setCursorGrabbed(true);
gk::Mouse::setCursorVisible(false);
gk::Mouse::resetToWindowCenter();

isActive = false;

m_stateStack->pop();
m_stateStack->pop();
}
}

for (auto &it : m_widgets)
Expand Down Expand Up @@ -123,11 +135,23 @@ void LuaGUIState::onEvent(const SDL_Event &event) {

m_mouseItemWidget.onEvent(event);
}

for (auto &it : m_textInputs)
it.second.onEvent(event);
}

void LuaGUIState::update() {
InterfaceState::update();

for (auto &it : m_textInputInventories) {
auto inv = m_inventoryWidgets.find(it.second);
if (inv != m_inventoryWidgets.end()) {
inv->second.applySearch(m_textInputs.at(it.first).string());
}
else
gkError() << "Can't find linked inventory" << it.second << "for text input" << it.first;
}

for (auto &it : m_widgets)
it->update();

Expand Down Expand Up @@ -177,6 +201,9 @@ void LuaGUIState::draw(gk::RenderTarget &target, gk::RenderStates states) const
for (auto &it : m_craftingWidgets)
target.draw(it.second, states);

for (auto &it : m_textInputs)
target.draw(it.second, states);

target.draw(m_mouseItemWidget, states);
}

Expand All @@ -201,6 +228,8 @@ void LuaGUIState::loadGUI(sf::Packet &packet) {
loadCraftingWidget(name, x, y, packet);
else if (type == LuaWidget::ScrollBarWidget)
loadScrollBarWidget(name, x, y, packet);
else if (type == LuaWidget::TextInput)
loadTextInput(name, x, y, packet);
else if (type == LuaWidget::Inventory)
loadInventory(name, packet);
}
Expand Down Expand Up @@ -370,6 +399,23 @@ void LuaGUIState::loadScrollBarWidget(const std::string &, s32 x, s32 y, sf::Pac
m_widgets.emplace_back(scrollBarWidget);
}

void LuaGUIState::loadTextInput(const std::string &name, s32 x, s32 y, sf::Packet &packet) {
u16 width, height;
std::string placeholder, inventory;
gk::Color placeholderColor;
packet >> width >> height >> placeholder >> placeholderColor >> inventory;

TextInput textInput{&m_mainWidget};
textInput.setPosition(x, y);
textInput.setFocus(false);
textInput.setBackgroundSize(width, height);
textInput.setPlaceholder(placeholder);
textInput.setPlaceholderColor(placeholderColor);

m_textInputs.emplace(name, std::move(textInput));
m_textInputInventories.emplace(name, inventory);
}

void LuaGUIState::loadInventory(const std::string &name, sf::Packet &packet) {
m_inventories.emplace(name, Inventory{});

Expand Down
4 changes: 4 additions & 0 deletions source/client/states/LuaGUIState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "InterfaceState.hpp"
#include "InventoryWidget.hpp"
#include "MouseItemWidget.hpp"
#include "TextInput.hpp"

class ClientPlayer;
class ClientWorld;
Expand All @@ -60,6 +61,7 @@ class LuaGUIState : public InterfaceState {
void loadCraftingWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet);
void loadProgressBarWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet);
void loadScrollBarWidget(const std::string &name, s32 x, s32 y, sf::Packet &packet);
void loadTextInput(const std::string &name, s32 x, s32 y, sf::Packet &packet);
void loadInventory(const std::string &name, sf::Packet &packet);

gk::Texture &loadTexture(const std::string &textureFilename);
Expand All @@ -79,6 +81,8 @@ class LuaGUIState : public InterfaceState {
std::vector<std::unique_ptr<gk::Drawable>> m_drawables;
std::unordered_map<std::string, Inventory> m_inventories;
std::unordered_map<std::string, gk::Texture> m_textures;
std::unordered_map<std::string, TextInput> m_textInputs;
std::unordered_map<std::string, std::string> m_textInputInventories;

ClientPlayer &m_player;
ClientWorld &m_world;
Expand Down
Loading

0 comments on commit ef5ac1d

Please sign in to comment.