Taking things from the LootUI to the StatusUI works way better now and there's a DropTarget to match the GrabSource.
This commit is contained in:
parent
842aac3127
commit
461ad03d27
8 changed files with 93 additions and 70 deletions
|
@ -65,7 +65,7 @@ namespace gui {
|
||||||
set_event(gui::Event::KEY_PRESS);
|
set_event(gui::Event::KEY_PRESS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dbc::sentinel("invalid event");
|
dbc::sentinel(fmt::format("invalid event: {}", int(ev)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
62
gui/fsm.cpp
62
gui/fsm.cpp
|
@ -27,6 +27,7 @@ namespace gui {
|
||||||
$loot_ui($level),
|
$loot_ui($level),
|
||||||
$font{FONT_FILE_NAME}
|
$font{FONT_FILE_NAME}
|
||||||
{
|
{
|
||||||
|
$window.setPosition({0,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSM::event(Event ev) {
|
void FSM::event(Event ev) {
|
||||||
|
@ -132,31 +133,42 @@ namespace gui {
|
||||||
state(State::IDLE);
|
state(State::IDLE);
|
||||||
break;
|
break;
|
||||||
case LOOT_SELECT: {
|
case LOOT_SELECT: {
|
||||||
int slot_id = std::any_cast<int>(data);
|
$grab_source = std::any_cast<DinkyECS::Entity>(data);
|
||||||
|
|
||||||
if(auto world_entity = $loot_ui.select_slot(slot_id)) {
|
if(auto world_entity = $loot_ui.select_slot(*$grab_source)) {
|
||||||
$grab_source = $loot_ui.$gui.entity("item_", slot_id);
|
|
||||||
auto& source = $loot_ui.get_grabber(*$grab_source);
|
auto& source = $loot_ui.get_grabber(*$grab_source);
|
||||||
|
|
||||||
source.grab($window);
|
source.grab($window);
|
||||||
source.move($router.position);
|
source.move($router.position);
|
||||||
|
|
||||||
$status_ui.select_slot(slot_id, *world_entity);
|
$status_ui.select_slot(*world_entity);
|
||||||
|
} else {
|
||||||
|
// BUG: need a cancel operation here
|
||||||
|
$window.setMouseCursorVisible(true);
|
||||||
|
$grab_source = std::nullopt;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case INV_SELECT: {
|
case INV_SELECT: {
|
||||||
std::string slot_name = std::any_cast<std::string>(data);
|
auto gui_id = std::any_cast<DinkyECS::Entity>(data);
|
||||||
int slot_id = $status_ui.place_slot(slot_name);
|
dbc::log(fmt::format("INV_SELECT $grab_source null? {} gui_id {}",
|
||||||
dbc::check(slot_id != -1, "status_ui is trying to place -1 slot_id");
|
$grab_source == std::nullopt, gui_id));
|
||||||
if(slot_id != -1) {
|
|
||||||
$loot_ui.remove_slot(slot_id);
|
if($grab_source) {
|
||||||
|
auto& drop = $status_ui.$gui.get<guecs::DropTarget>(gui_id);
|
||||||
|
|
||||||
|
if(drop.action()) {
|
||||||
|
$loot_ui.remove_slot(*$grab_source);
|
||||||
|
$grab_source = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
$window.setMouseCursorVisible(true);
|
||||||
|
dbc::log("INV_SELECT back to looting");
|
||||||
|
state(State::LOOTING);
|
||||||
}
|
}
|
||||||
$window.setMouseCursorVisible(true);
|
|
||||||
state(State::LOOTING);
|
|
||||||
} break;
|
} break;
|
||||||
case MOUSE_CLICK:
|
case MOUSE_CLICK:
|
||||||
mouse_action(false);
|
mouse_action(false);
|
||||||
break;
|
break;
|
||||||
|
case MOUSE_DRAG:
|
||||||
case MOUSE_MOVE: {
|
case MOUSE_MOVE: {
|
||||||
if($grab_source) {
|
if($grab_source) {
|
||||||
auto& source = $loot_ui.get_grabber(*$grab_source);
|
auto& source = $loot_ui.get_grabber(*$grab_source);
|
||||||
|
@ -164,16 +176,9 @@ namespace gui {
|
||||||
}
|
}
|
||||||
mouse_action(true);
|
mouse_action(true);
|
||||||
} break;
|
} break;
|
||||||
case MOUSE_DRAG_START: {
|
case MOUSE_DRAG_START:
|
||||||
mouse_action(false);
|
dbc::check(false, "DRAG START IN LOOT GRAB");
|
||||||
} break;
|
break;
|
||||||
case MOUSE_DRAG: {
|
|
||||||
if($grab_source) {
|
|
||||||
auto& source = $loot_ui.get_grabber(*$grab_source);
|
|
||||||
source.move($router.position);
|
|
||||||
}
|
|
||||||
mouse_action(true);
|
|
||||||
} break;
|
|
||||||
case MOUSE_DROP:
|
case MOUSE_DROP:
|
||||||
mouse_action(false);
|
mouse_action(false);
|
||||||
break;
|
break;
|
||||||
|
@ -186,6 +191,10 @@ namespace gui {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSM::INV_GRAB(Event ev, std::any data) {
|
void FSM::INV_GRAB(Event ev, std::any data) {
|
||||||
|
dbc::log("INV_SELECT NOT IMPlEMENTED");
|
||||||
|
state(State::LOOTING);
|
||||||
|
return;
|
||||||
|
|
||||||
using enum Event;
|
using enum Event;
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
|
@ -297,9 +306,12 @@ namespace gui {
|
||||||
auto& data = items["TORCH_BAD"];
|
auto& data = items["TORCH_BAD"];
|
||||||
|
|
||||||
for(int i = 0; $loot_ui.contents.size() < 10; i++) {
|
for(int i = 0; $loot_ui.contents.size() < 10; i++) {
|
||||||
auto torch = $level.world->entity();
|
auto gui_id = $loot_ui.$gui.entity("item_", i);
|
||||||
components::configure_entity(*$level.world, torch, data["components"]);
|
if(!$loot_ui.contents.contains(gui_id)) {
|
||||||
$loot_ui.contents.push_back(torch);
|
auto torch = $level.world->entity();
|
||||||
|
components::configure_entity(*$level.world, torch, data["components"]);
|
||||||
|
$loot_ui.contents.try_emplace(gui_id, torch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$loot_ui.update();
|
$loot_ui.update();
|
||||||
|
|
|
@ -19,4 +19,18 @@ namespace guecs {
|
||||||
target.send<Events::GUI>(event, ent, data);
|
target.send<Events::GUI>(event, ent, data);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GrabSource::grab(sf::RenderWindow& window) {
|
||||||
|
window.setMouseCursorVisible(false);
|
||||||
|
sprite->setOrigin({128, 128});
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrabSource::move(sf::Vector2i position) {
|
||||||
|
sprite->setPosition({
|
||||||
|
float(position.x),
|
||||||
|
float(position.y)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,20 +9,11 @@ namespace guecs {
|
||||||
Clickable make_action(DinkyECS::World& target, Events::GUI event, std::any data);
|
Clickable make_action(DinkyECS::World& target, Events::GUI event, std::any data);
|
||||||
|
|
||||||
struct GrabSource : public Sprite {
|
struct GrabSource : public Sprite {
|
||||||
void grab(sf::RenderWindow& window) {
|
void grab(sf::RenderWindow& window);
|
||||||
window.setMouseCursorVisible(false);
|
void move(sf::Vector2i position);
|
||||||
sprite->setOrigin({128, 128});
|
|
||||||
}
|
|
||||||
|
|
||||||
void move(sf::Vector2i position) {
|
|
||||||
sprite->setPosition({
|
|
||||||
float(position.x),
|
|
||||||
float(position.y)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DropTarget {
|
struct DropTarget {
|
||||||
|
std::function<bool()> action;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace gui {
|
||||||
THEME.TRANSPARENT, THEME.LIGHT_MID });
|
THEME.TRANSPARENT, THEME.LIGHT_MID });
|
||||||
$gui.set<guecs::Effect>(id, {0.4f, "ui_shader"});
|
$gui.set<guecs::Effect>(id, {0.4f, "ui_shader"});
|
||||||
$gui.set<guecs::Clickable>(id, {
|
$gui.set<guecs::Clickable>(id, {
|
||||||
guecs::make_action(*$level.world, Events::GUI::LOOT_SELECT, {i})
|
guecs::make_action(*$level.world, Events::GUI::LOOT_SELECT, {id})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,20 +46,16 @@ namespace gui {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<DinkyECS::Entity> LootUI::select_slot(int slot_id) {
|
std::optional<DinkyECS::Entity> LootUI::select_slot(DinkyECS::Entity slot_id) {
|
||||||
if(slot_id >= 0 && size_t(slot_id) < contents.size()) {
|
if(contents.contains(slot_id)) {
|
||||||
return contents.at(slot_id);
|
return contents.at(slot_id);
|
||||||
} else {
|
} else {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LootUI::remove_slot(int slot_id) {
|
void LootUI::remove_slot(DinkyECS::Entity slot_id) {
|
||||||
dbc::check(size_t(slot_id) < contents.size(),
|
contents.erase(slot_id);
|
||||||
fmt::format("invalid slot id {} give, contents.size={}",
|
|
||||||
slot_id, contents.size()));
|
|
||||||
|
|
||||||
contents.erase(contents.begin() + slot_id);
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +69,10 @@ namespace gui {
|
||||||
$gui.remove<guecs::Sprite>(id);
|
$gui.remove<guecs::Sprite>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i < contents.size()) {
|
if(contents.contains(id)) {
|
||||||
auto item = contents.at(i);
|
auto item = contents.at(id);
|
||||||
|
dbc::check($level.world->has<components::Sprite>(item),
|
||||||
|
"item in inventory UI doesn't exist in world. New level?");
|
||||||
auto& sprite = $level.world->get<components::Sprite>(item);
|
auto& sprite = $level.world->get<components::Sprite>(item);
|
||||||
guecs::GrabSource grabber{sprite.name};
|
guecs::GrabSource grabber{sprite.name};
|
||||||
$gui.set_init<guecs::Sprite>(id, grabber);
|
$gui.set_init<guecs::Sprite>(id, grabber);
|
||||||
|
@ -82,8 +80,14 @@ namespace gui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guecs::GrabSource& LootUI::get_grabber(DinkyECS::Entity entity) {
|
bool LootUI::has_grabber(DinkyECS::Entity gui_id) {
|
||||||
return static_cast<guecs::GrabSource&>($gui.get<guecs::Sprite>(entity));
|
return $gui.has<guecs::Sprite>(gui_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
guecs::GrabSource& LootUI::get_grabber(DinkyECS::Entity gui_id) {
|
||||||
|
dbc::check(has_grabber(gui_id), "invalid GrabSource requested, entity isn't in the GUI.");
|
||||||
|
|
||||||
|
return static_cast<guecs::GrabSource&>($gui.get<guecs::Sprite>(gui_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LootUI::render(sf::RenderWindow& window) {
|
void LootUI::render(sf::RenderWindow& window) {
|
||||||
|
@ -92,6 +96,7 @@ namespace gui {
|
||||||
|
|
||||||
void LootUI::update_level(GameLevel &level) {
|
void LootUI::update_level(GameLevel &level) {
|
||||||
$level = level;
|
$level = level;
|
||||||
|
contents.clear();
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace gui {
|
||||||
bool active = false;
|
bool active = false;
|
||||||
guecs::UI $gui;
|
guecs::UI $gui;
|
||||||
GameLevel $level;
|
GameLevel $level;
|
||||||
std::vector<DinkyECS::Entity> contents;
|
std::unordered_map<DinkyECS::Entity, DinkyECS::Entity> contents;
|
||||||
|
|
||||||
LootUI(GameLevel level);
|
LootUI(GameLevel level);
|
||||||
|
|
||||||
|
@ -21,8 +21,9 @@ namespace gui {
|
||||||
void render(sf::RenderWindow& window);
|
void render(sf::RenderWindow& window);
|
||||||
void update_level(GameLevel &level);
|
void update_level(GameLevel &level);
|
||||||
bool mouse(float x, float y, bool hover);
|
bool mouse(float x, float y, bool hover);
|
||||||
std::optional<DinkyECS::Entity> select_slot(int slot);
|
std::optional<DinkyECS::Entity> select_slot(DinkyECS::Entity slot);
|
||||||
void remove_slot(int slot_id);
|
void remove_slot(DinkyECS::Entity slot_id);
|
||||||
guecs::GrabSource& get_grabber(DinkyECS::Entity entity);
|
guecs::GrabSource& get_grabber(DinkyECS::Entity entity);
|
||||||
|
bool has_grabber(DinkyECS::Entity gui_id);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,10 @@ namespace gui {
|
||||||
} else {
|
} else {
|
||||||
$gui.set<Textual>(button, {guecs::to_wstring(name)});
|
$gui.set<Textual>(button, {guecs::to_wstring(name)});
|
||||||
$gui.set<Clickable>(button, {
|
$gui.set<Clickable>(button, {
|
||||||
guecs::make_action(*$level.world, Events::GUI::INV_SELECT, {name})
|
guecs::make_action(*$level.world, Events::GUI::INV_SELECT, {button})
|
||||||
|
});
|
||||||
|
$gui.set<DropTarget>(button, {
|
||||||
|
[&, button]() -> bool { return place_slot(button); }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,22 +83,20 @@ namespace gui {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusUI::select_slot(int slot_id, DinkyECS::Entity entity) {
|
void StatusUI::select_slot(DinkyECS::Entity entity) {
|
||||||
$selected_slot = slot_id;
|
|
||||||
$selected_entity = entity;
|
$selected_entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StatusUI::place_slot(const std::string &name) {
|
bool StatusUI::place_slot(DinkyECS::Entity gui_id) {
|
||||||
fmt::println("LOOT slot={}, entity={} PLACE into slot={}",
|
|
||||||
$selected_slot, $selected_entity, name);
|
|
||||||
|
|
||||||
if($level.world->has<components::Sprite>($selected_entity)) {
|
if($level.world->has<components::Sprite>($selected_entity)) {
|
||||||
auto& sprite = $level.world->get<components::Sprite>($selected_entity);
|
auto& sprite = $level.world->get<components::Sprite>($selected_entity);
|
||||||
auto gui_id = $gui.entity(name);
|
|
||||||
$gui.set_init<guecs::Sprite>(gui_id, {sprite.name});
|
|
||||||
$slots.insert_or_assign(name, $selected_entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $selected_slot;
|
$gui.set_init<guecs::Sprite>(gui_id, {sprite.name});
|
||||||
|
|
||||||
|
$slots.insert_or_assign(gui_id, $selected_entity);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,9 @@ namespace gui {
|
||||||
class StatusUI {
|
class StatusUI {
|
||||||
public:
|
public:
|
||||||
guecs::UI $gui;
|
guecs::UI $gui;
|
||||||
std::unordered_map<std::string, DinkyECS::Entity> $slots;
|
std::unordered_map<DinkyECS::Entity, DinkyECS::Entity> $slots;
|
||||||
GameLevel $level;
|
GameLevel $level;
|
||||||
ritual::UI $ritual_ui;
|
ritual::UI $ritual_ui;
|
||||||
int $selected_slot = -1;
|
|
||||||
DinkyECS::Entity $selected_entity;
|
DinkyECS::Entity $selected_entity;
|
||||||
|
|
||||||
StatusUI(GameLevel level);
|
StatusUI(GameLevel level);
|
||||||
|
@ -23,7 +22,7 @@ namespace gui {
|
||||||
void init();
|
void init();
|
||||||
void render(sf::RenderWindow &window);
|
void render(sf::RenderWindow &window);
|
||||||
void update();
|
void update();
|
||||||
void select_slot(int slot_id, DinkyECS::Entity entity);
|
void select_slot(DinkyECS::Entity entity);
|
||||||
int place_slot(const std::string &name);
|
bool place_slot(DinkyECS::Entity gui_id);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue