Skip to content

Commit

Permalink
[ui] Initiating ItemBox for in-game items in #18 #19
Browse files Browse the repository at this point in the history
  • Loading branch information
gbaudic committed Apr 23, 2020
1 parent cb66af5 commit daff8d8
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 2 deletions.
173 changes: 173 additions & 0 deletions src/ui/itembox.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/**
* \file itembox.cpp
* \brief UI component holding in-game items in room and lobby views
* \author G. B.
* \version 0.1a
* \date 22/04/2020
*/
/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This Source Code Form is "Incompatible With Secondary Licenses",
* as defined by the Mozilla Public License, v. 2.0.
*/

#include <stdexcept>
#include "itembox.hpp"
using namespace gcn;

/**
* Constructor
* \param name Context in which this widget will be used, so we can adapt the behaviour
*/
ItemBox::ItemBox(ContextName name) : inGame(name == ContextName::ROOM) {
setWidth(6 * 34);
setHeight(34);
}

/**
* \brief Try to add an item to the list
* \param item the item to add
* \return true if addition succeeded, false otherwise
*/
bool ItemBox::add(GameItemType item) {
bool result = false;
int size = GameItem::getSize(item);
for (int i = 0; i < SIZE; i++) {
if (items[i] == GameItemType::NONE_1) {
if (size == 1) {
items[i] = item;
result = true;
break;
} else { // size == 2: we need 2 slots
if (i < SIZE - 1 && items[i + 1] == GameItemType::NONE_1) {
items[i] = item;
items[i + 1] = item;
result = true;
break;
}
}
}
}
return result;
}

/**
* \brief Remove all instances of a given type
* Used in Lobby view when room admin disables an item
* \param type type to remove
*/
void ItemBox::remove(GameItemType type) {
if (!inGame) {
int size = GameItem::getSize(type);
int i = 0;
while (i < SIZE) {
if (items[i] == type) {
items[i] = GameItemType::NONE_1;
if (size == 2) {
items[i + 1] = GameItemType::NONE_1;
}
i += size;
} else {
i++;
}
}
}
}

/**
* \brief Remove an item at the specified index
* \return true if success, false otherwise
*/
bool ItemBox::remove(const int index) {
bool result = false;
if (index >= 0 && index < SIZE) {
int i = 0;
while (i < SIZE) {
int size = GameItem::getSize(items[i]);
if ((index == i && size == 1) || (size == 2 && (index == i || index == i + 1))) {
// Location found
current = items[i];
items[i] = GameItemType::NONE_1;
if (size == 2) {
items[i + 1] = GameItemType::NONE_1;
}
result = current != GameItemType::NONE_1;
break;
}
i += size;
}
}
return result;
}

/**
* \brief Get the currently selected item (if any)
* Calling this method resets the selection!
* \return the currently selected item, or NONE_1 if none selected.
*/
GameItemType ItemBox::getSelected() {
GameItemType result = current;
current = GameItemType::NONE_1;
return result;
}

void ItemBox::draw(gcn::Graphics* graphics) {
Color lightgray{ 0xcc, 0xcc, 0xcc };
Color lightblue{ 0x4c, 0xa3, 0xaa };
// Draw background
for (int i = 0; i < SIZE; i++) {
graphics->setColor(lightgray);
graphics->drawRectangle(Rectangle(i * 34, 0, 32, getHeight()));
graphics->setColor(lightblue);
graphics->fillRectangle(Rectangle(i * 34 + 1, 1, 30, getHeight() - 2));
}

// Draw items
int i = 0;
while (i < SIZE) {
int size = GameItem::getSize(items[i]);
if (items[i] != GameItemType::NONE_1 && items[i] != GameItemType::NONE_2) {
// This item should show up
try {
const Image* img = images.at(items[i]);
graphics->drawImage(img, i * 34 + 2, 2);
} catch (const std::out_of_range) {
// Image not found in map: load it
auto it = images.insert(std::make_pair(items[i], Image::load(GameItem::getFilename(items[i]))));
graphics->drawImage(it.first->second, i * 34 + 2, 2);
}
}

i += size;
}
}

void ItemBox::mouseReleased(gcn::MouseEvent& mouseEvent) {
if (mouseEvent.getButton() == MouseEvent::LEFT || mouseEvent.getButton() == MouseEvent::RIGHT) {
if (mouseEvent.getX() >= 0 && mouseEvent.getX() <= getWidth() && mouseEvent.getY() >= 0 && mouseEvent.getY() <= getHeight()) {
bool hasItem = remove(mouseEvent.getX() / 34);
if (hasItem) {
generateAction();
}
mouseEvent.consume();
}
}
}

void ItemBox::keyReleased(gcn::KeyEvent& keyEvent) {
if (inGame) {
const Key key = keyEvent.getKey();
// Only F1-F6 are supported in keyboard interaction
if (key.getValue() >= Key::F1 && key.getValue() <= Key::F6) {
bool hasItem = remove(key.getValue() - Key::F1);
if (hasItem) {
generateAction();
}
keyEvent.consume();
}
}
}


45 changes: 45 additions & 0 deletions src/ui/itembox.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* \file itembox.hpp
* \brief UI component holding in-game items in room and lobby views
* \author G. B.
* \version 0.1a
* \date 22/04/2020
*/
/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This Source Code Form is "Incompatible With Secondary Licenses",
* as defined by the Mozilla Public License, v. 2.0.
*/

#ifndef _H_ITEMBOX_
#define _H_ITEMBOX_

#include <string>
#include <map>
#include <guisan.hpp>
#include "../common/commongameitem.hpp"
#include "../context.hpp" // for ContextName

class ItemBox : public gcn::Widget, public gcn::MouseListener, public gcn::KeyListener {
public:
explicit ItemBox(ContextName name);
bool add(GameItemType item);
void remove(GameItemType type);
bool remove(const int index);
GameItemType getSelected();
virtual void draw(gcn::Graphics* graphics) override;
virtual void mouseReleased(gcn::MouseEvent& mouseEvent) override;
virtual void keyReleased(gcn::KeyEvent& keyEvent) override;

private:
static const int SIZE = 6;
bool inGame;
GameItemType items[SIZE]{GameItemType::NONE_1, GameItemType::NONE_1, GameItemType::NONE_1, GameItemType::NONE_1, GameItemType::NONE_1, GameItemType::NONE_1};
GameItemType current{ GameItemType::NONE_1 };
std::map<GameItemType, gcn::Image*> images;
};

#endif // !_H_ITEMBOX_

10 changes: 9 additions & 1 deletion src/views/lobbyview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "lobbyview.hpp"
using namespace gcn;

LobbyView::LobbyView(ContextName name): Context(name) {
LobbyView::LobbyView(ContextName name): Context(name), itemBox(name) {

btn_back.setActionEventId("back");
btn_back.addActionListener(this);
Expand All @@ -31,6 +31,8 @@ LobbyView::LobbyView(ContextName name): Context(name) {
btn_teamSwitch.addActionListener(this);
tf_message.setActionEventId("message");
tf_message.addActionListener(this);
itemBox.setActionEventId("itembox");
itemBox.addActionListener(this);

Color darkblue{ 0, 0, 0xff };
Color white{ 0xff, 0xff, 0xff };
Expand Down Expand Up @@ -119,8 +121,14 @@ void LobbyView::addWidgets() {
addWidget(&lbl_name, 20, 5);
addWidget(&btn_editName, 100, 5);

addWidget(&tabs, 15, getHeight() - 3 * btn_back.getHeight() - tf_message.getHeight());
addWidget(&tf_message, 15, getHeight() - 3 * btn_back.getHeight() - tf_message.getHeight());

addWidget(&itemBox, getWidth() - 15 - itemBox.getWidth(), tabs.getY());

addWidget(&btn_back, 5, getHeight() - 2 * btn_back.getHeight());
addWidget(&btn_ready, getWidth() - 5 - btn_ready.getWidth(), getHeight() - 2 * btn_back.getHeight());
addWidget(&btn_teamSwitch, btn_ready.getX() - 15 - btn_teamSwitch.getWidth(), btn_ready.getY());
}

void LobbyView::drawBackground(SDL_Renderer* screen) {
Expand Down
2 changes: 2 additions & 0 deletions src/views/lobbyview.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "../context.hpp"
#include "../common/commonroom.hpp"
#include "../common/messages.hpp"
#include "../ui/itembox.hpp"

class LobbyView : public Context, public gcn::ActionListener {
public:
Expand Down Expand Up @@ -65,6 +66,7 @@ class LobbyView : public Context, public gcn::ActionListener {
gcn::TabbedArea tabs;
gcn::TextField tf_message;
gcn::TextBox tb_messages;
ItemBox itemBox;

bool isCurrentPlayerAdmin = false;
RoomBasicInfo roomBasicInfo;
Expand Down
6 changes: 5 additions & 1 deletion src/views/roomview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Uint16 RoomView::MAX_POWER;
* @param view the LobbyView, which already has players and all parameters set
*/
RoomView::RoomView(const LobbyView *view) : Context(ContextName::ROOM),
gameMode(view->getMode()), currentMap(new GameMap(view->getMap())) {
itemBox(ContextName::ROOM), gameMode(view->getMode()), currentMap(new GameMap(view->getMap())) {


fg_rect.w = getWidth();
Expand Down Expand Up @@ -70,6 +70,9 @@ gameMode(view->getMode()), currentMap(new GameMap(view->getMap())) {

scoreBoard.setHeight(15);

itemBox.setActionEventId("item");
itemBox.addActionListener(this);

currentMap->load();

}
Expand Down Expand Up @@ -244,6 +247,7 @@ void RoomView::addWidgets() {
addWidget(&msgLog, 2, 2);
addWidget(&goldDisplay, getWidth() - goldDisplay.getWidth() - 2, getHeight() - goldDisplay.getHeight() - 2);
addWidget(&scoreBoard, getWidth() - scoreBoard.getWidth() - 2, goldDisplay.getY() - scoreBoard.getHeight() - 2);
addWidget(&itemBox, pb_power.getX(), pb_power.getY() - itemBox.getHeight() - 10);

addCenteredWidget(&results);
}
Expand Down
2 changes: 2 additions & 0 deletions src/views/roomview.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "../ui/chatballoon.hpp"
#include "../ui/resultsdialog.hpp"
#include "../ui/scoreboard.hpp"
#include "../ui/itembox.hpp"
#include "../common/commonplayer.hpp" // temporary, use clientplayer
#include "../common/messages.hpp" // for WeaponType
#include "lobbyview.hpp"
Expand Down Expand Up @@ -93,6 +94,7 @@ class RoomView: public Context, public gcn::ActionListener {
ResultsDialog results;
ScoreBoard scoreBoard;
GoldDisplay goldDisplay;
ItemBox itemBox;

Uint16 turnCount = 0;
InteractionMode currentMode = InteractionMode::IDLE;
Expand Down

0 comments on commit daff8d8

Please sign in to comment.