Inventory Drag and Drop Management implemented.

pull/28/head
sigonasr2 1 year ago
parent 5903692dbb
commit 803a0189d8
  1. 4
      Crawler/Crawler.cpp
  2. 21
      Crawler/Item.cpp
  3. 2
      Crawler/Item.h
  4. 42
      Crawler/Menu.cpp
  5. 8
      Crawler/MenuComponent.cpp
  6. 6
      Crawler/MenuComponent.h
  7. 24
      Crawler/MenuItemButton.h
  8. 2
      Crawler/Version.h
  9. 2
      Crawler/assets/config/gfx/themes.txt

@ -105,6 +105,10 @@ bool Crawler::OnUserCreate(){
camera.EnableWorldBoundary(false);
ItemInfo::InitializeItems();
Inventory::AddItem("Small Health Potion",16);
Inventory::AddItem("Large Health Potion",3);
Inventory::AddItem("Medium Mana Potion",1);
Inventory::AddItem("Blue Slime Remains",22);
InitializeGraphics();

@ -176,23 +176,16 @@ bool Inventory::ExecuteAction(IT item){
return ITEM_SCRIPTS.at(ITEM_DATA.at(item).useFunc)(game,ITEM_DATA[item].customProps);
}
bool Inventory::SwapItems(IT it,IT it2){
ItemInfo&itemInfo1=ITEM_DATA.at(it);
ItemInfo&itemInfo2=ITEM_DATA.at(it2);
if(itemInfo1.category!=itemInfo2.category)return false;
ITCategory category=itemInfo1.category;
Item item1=GetItem(it);
Item item2=GetItem(it2);
if(item1.Amt()<=0&&item2.Amt()<=0)return false;
std::vector<IT>inv=sortedInv.at(category);
auto index1=std::find(inv.begin(),inv.end(),it);
auto index2=std::find(inv.begin(),inv.end(),it2);
int largestSlot=std::max(index1-inv.begin(),index2-inv.begin());
if(inv.size()<largestSlot){
bool Inventory::SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2){
std::vector<IT>&inv=sortedInv.at(itemCategory);
int largestSlot=std::max(slot1,slot2);
if(inv.size()<=largestSlot){
//The inventory is too small, so expand out blank slots to accomodate.
inv.resize(largestSlot+size_t(1));
}
std::swap(*index1,*index2);
IT&item1=inv.at(slot1);
IT&item2=inv.at(slot2);
std::swap(item1,item2);
return true;
}

@ -44,7 +44,7 @@ public:
static void RemoveItem(IT it,uint32_t amt=1);
static std::vector<IT>&get(ITCategory itemCategory);
static bool SwapItems(IT it,IT it2);
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);
private:
static void InsertIntoSortedInv(IT item);
static bool ExecuteAction(IT item);

@ -55,9 +55,10 @@ void Menu::CheckClickAndPerformMenuSelect(Crawler*game){
void Menu::HoverMenuSelect(Crawler*game){
if(selection==vi2d{-1,-1})return;
if(buttons[selection.y][selection.x]->draggable)
if(buttonHoldTime<0.3)CheckClickAndPerformMenuSelect(game);
if(buttonHoldTime<"ThemeGlobal.MenuHoldTime"_F)CheckClickAndPerformMenuSelect(game);
else{
draggingComponent=buttons[selection.y][selection.x];
draggingComponent=buttons[selection.y][selection.x]->PickUpDraggableItem();
buttonHoldTime=0;
}
else CheckClickAndPerformMenuSelect(game);
}
@ -76,11 +77,13 @@ void Menu::MenuSelect(Crawler*game){
}
void Menu::Update(Crawler*game){
if(draggingComponent!=nullptr&&(!MOUSE_NAVIGATION||game->GetMouse(Mouse::LEFT).bHeld)){
if(draggingComponent==nullptr&&(((!MOUSE_NAVIGATION&&(game->GetKey(ENTER).bHeld)||game->GetKey(SPACE).bHeld))||game->GetMouse(Mouse::LEFT).bHeld)){
buttonHoldTime+=game->GetElapsedTime();
}
HoverMenuSelect(game);
if(draggingComponent==nullptr){
HoverMenuSelect(game);
}
for(auto&key:buttons){
for(auto&button:key.second){
@ -91,9 +94,30 @@ void Menu::Update(Crawler*game){
if(selection!=vi2d{-1,-1})buttons[selection.y][selection.x]->hovered=true;
}else{
for(auto&key:buttons){
int index=0;
for(auto&button:key.second){
if(geom2d::overlaps(geom2d::rect<float>{button->rect.pos+pos,button->rect.size},game->GetMousePos())){
button->hovered=true;
selection.y=key.first;
selection.x=index;
}
index++;
}
}
}
if(draggingComponent!=nullptr&&selection!=vi2d{-1,-1}){
MenuComponent*selectedComponent=buttons[selection.y][selection.x];
if(!MOUSE_NAVIGATION){
if(game->GetKey(ENTER).bReleased||game->GetKey(SPACE).bReleased){
if(selectedComponent->DropDraggableItem(draggingComponent)){
draggingComponent=nullptr;
}
}
}else{
if(game->GetMouse(Mouse::LEFT).bReleased){
if(selectedComponent->DropDraggableItem(draggingComponent)){
draggingComponent=nullptr;
}
}
}
@ -126,6 +150,16 @@ void Menu::Draw(Crawler*game){
for(auto&component:displayComponents){
component->Draw(game,pos,this==Menu::stack.back());
}
if(draggingComponent!=nullptr){
vf2d offsetPos=draggingComponent->rect.pos;
if(!MOUSE_NAVIGATION){
MenuComponent*selectedComponent=buttons[selection.y][selection.x];
draggingComponent->Draw(game,pos+-offsetPos+selectedComponent->rect.pos+vi2d{1,-4},this==Menu::stack.back());
}else{
draggingComponent->Draw(game,-offsetPos+game->GetMousePos(),this==Menu::stack.back());
}
}
};
void Menu::OpenMenu(MenuType menu){

@ -21,4 +21,12 @@ void MenuComponent::Draw(Crawler*game,vf2d parentPos,bool focused){
game->DrawRectDecal(rect.pos+parentPos,rect.size,focused?GREY:GREY*"ThemeGlobal.MenuUnfocusedColorMult"_F);
}
game->DrawStringPropDecal(rect.pos+parentPos+rect.size/2-game->GetTextSizeProp(label)/2,label,focused?WHITE:WHITE*"ThemeGlobal.MenuUnfocusedColorMult"_F);
}
MenuComponent*MenuComponent::PickUpDraggableItem(){
return nullptr;
}
bool MenuComponent::DropDraggableItem(MenuComponent*draggable){
return false;
}

@ -4,7 +4,6 @@
class MenuComponent{
friend class Menu;
MenuType menuDest;
MenuFunc onClick;
bool hovered=false;
bool selectable=true;
private:
@ -14,9 +13,14 @@ protected:
std::string label;
bool border=true;
bool draggable=false;
MenuFunc onClick;
public:
MenuComponent(geom2d::rect<float>rect,std::string label,MenuFunc onClick,bool selectable=true);
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick,bool selectable=true);
virtual void Update(Crawler*game);
virtual void Draw(Crawler*game,vf2d parentPos,bool focused);
//We picked up a draggable component, we should make a copy and return it here. If a nullptr is returned here, the pickup is not allowed.
virtual MenuComponent*PickUpDraggableItem();
//We are attempting to drop draggable onto this item. If it's not allowed, return false.
virtual bool DropDraggableItem(MenuComponent*draggable);
};

@ -12,10 +12,12 @@ class MenuItemButton:public MenuIconButton{
private:
std::vector<IT>&invRef;
int inventoryIndex=0;
bool valid=false;
public:
inline MenuItemButton(geom2d::rect<float>rect,std::vector<IT>&invRef,int invIndex,MenuFunc onClick)
:MenuIconButton(rect,invRef.size()>invIndex?ITEM_DATA.at(invRef[invIndex]).Decal():nullptr,onClick),invRef(invRef),inventoryIndex(invIndex){
draggable=true;
valid=invRef.size()>invIndex;
}
inline Item GetItem(){
return Inventory::GetItem(invRef.at(inventoryIndex));
@ -27,8 +29,30 @@ public:
protected:
virtual inline void Update(Crawler*game)override{
MenuIconButton::Update(game);
valid=invRef.size()>inventoryIndex&&ITEM_DATA.count(invRef[inventoryIndex]);
if(valid){
icon=ITEM_DATA.at(invRef[inventoryIndex]).Decal();
}else{
icon=nullptr;
}
}
virtual inline void Draw(Crawler*game,vf2d parentPos,bool focused)override{
MenuIconButton::Draw(game,parentPos,focused);
}
virtual inline MenuComponent*PickUpDraggableItem()override{
if(valid){
MenuItemButton*pickUp=new MenuItemButton(rect,invRef,inventoryIndex,onClick);
valid=false;
return pickUp;
}else{
return nullptr;
}
}
virtual inline bool DropDraggableItem(MenuComponent*draggable)override{
//HACK Warning! We're making a bold assumption that every component that is draggable is of the same type! This may change in the future....
MenuItemButton*draggedItem=(MenuItemButton*)draggable;
ITCategory cat=ITEM_DATA.at(draggedItem->invRef.at(draggedItem->inventoryIndex)).Category();
return Inventory::SwapItems(cat,draggedItem->inventoryIndex,inventoryIndex);
}
};

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 0
#define VERSION_BUILD 1848
#define VERSION_BUILD 1881
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -5,7 +5,7 @@ ThemeGlobal
# How much the R,G,B color components of a menu are multiplied to unfocused windows.
MenuUnfocusedColorMult = 0.4
# Amount of time to hold down an element before a press becomes a drag.
MenuHoldTime = 0.3
MenuHoldTime = 0.1
}
Themes

Loading…
Cancel
Save