summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorJosé Ávila <linux@javila.net>2005-06-17 07:14:23 +0000
committerJosé Ávila <linux@javila.net>2005-06-17 07:14:23 +0000
commit50b0f0e7ea4508e1ee30f0a0ea8741af6d3212d4 (patch)
tree846a6272b9c40e7a1fde02c52ad399f34e31124b /src/gui
parent4e031f6dba55f4793247f8603e6260a380a109f7 (diff)
downloadmana-client-50b0f0e7ea4508e1ee30f0a0ea8741af6d3212d4.tar.gz
mana-client-50b0f0e7ea4508e1ee30f0a0ea8741af6d3212d4.tar.bz2
mana-client-50b0f0e7ea4508e1ee30f0a0ea8741af6d3212d4.tar.xz
mana-client-50b0f0e7ea4508e1ee30f0a0ea8741af6d3212d4.zip
new BrowserBox widget with colors/links support
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/browserbox.cpp318
-rw-r--r--src/gui/browserbox.h147
-rw-r--r--src/gui/linkhandler.h42
-rw-r--r--src/gui/popupmenu.cpp213
-rw-r--r--src/gui/popupmenu.h78
5 files changed, 798 insertions, 0 deletions
diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp
new file mode 100644
index 00000000..06094139
--- /dev/null
+++ b/src/gui/browserbox.cpp
@@ -0,0 +1,318 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include "browserbox.h"
+
+int BrowserBox::instances = 0;
+gcn::ImageFont* BrowserBox::browserFont;
+
+BrowserBox::BrowserBox(unsigned int mode):
+ gcn::Widget()
+{
+ mMode = mode;
+ setOpaque(true);
+ setHighlightMode(BOTH);
+ mSelectedLink = -1;
+ setFocusable(true);
+ addMouseListener(this);
+
+ if (instances == 0)
+ {
+ browserFont = new gcn::ImageFont(
+ TMW_DATADIR "data/graphics/gui/browserfont.png",
+ " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567"
+ "89:@!\"$%&/=?^+*#[]{}()<>_;'.,\\|-~`");
+ }
+ instances++;
+}
+
+BrowserBox::~BrowserBox()
+{
+ instances--;
+ if (instances == 0)
+ {
+ // Clean up static resource font
+ delete browserFont;
+ }
+}
+
+void BrowserBox::setLinkHandler(LinkHandler* linkHandler)
+{
+ mLinkHandler = linkHandler;
+}
+
+void BrowserBox::setOpaque(bool opaque)
+{
+ mOpaque = opaque;
+}
+
+void BrowserBox::setHighlightMode(unsigned int highMode)
+{
+ mHighMode = highMode;
+}
+
+void BrowserBox::addRow(const std::string& row)
+{
+ std::string tmp = row;
+ std::string newRow;
+ BROWSER_LINK bLink;
+ int idx1, idx2, idx3;
+
+ // Check for links in format "@@link|Caption@@"
+ idx1 = tmp.find("@@");
+ while (idx1 >= 0)
+ {
+ idx2 = tmp.find("|", idx1);
+ idx3 = tmp.find("@@", idx2);
+ bLink.link = tmp.substr(idx1 + 2, idx2 - (idx1 + 2));
+ bLink.caption = tmp.substr(idx2 + 1, idx3 - (idx2 + 1));
+ bLink.y1 = mTextRows.size() * browserFont->getHeight();
+ bLink.y2 = bLink.y1 + browserFont->getHeight();
+
+ newRow += tmp.substr(0, idx1);
+
+ std::string tmp2 = newRow;
+ idx1 = tmp2.find("##");
+ while (idx1 >= 0)
+ {
+ tmp2.erase(idx1, 3);
+ idx1 = tmp2.find("##");
+ }
+ bLink.x1 = browserFont->getWidth(tmp2) - 1;
+ bLink.x2 = bLink.x1 + browserFont->getWidth(bLink.caption) + 1;
+
+ mLinks.push_back(bLink);
+
+ newRow += "##L" + bLink.caption;
+
+ tmp.erase(0, idx3 + 2);
+ if(tmp != "")
+ {
+ newRow += "##P";
+ }
+ idx1 = tmp.find("@@");
+ }
+
+ newRow += tmp;
+ mTextRows.push_back(newRow);
+
+ // Auto size mode
+ if (mMode == AUTO_SIZE)
+ {
+ std::string plain = newRow;
+ for (idx1 = plain.find("##"); idx1 >= 0; idx1 = plain.find("##"))
+ plain.erase(idx1, 3);
+
+ // Adjust the BrowserBox size
+ int w = browserFont->getWidth(plain);
+ if (w > getWidth())
+ setWidth(w);
+ }
+ setHeight(browserFont->getHeight() * mTextRows.size());
+}
+
+void BrowserBox::clearRows()
+{
+ mTextRows.clear();
+ mLinks.clear();
+ setWidth(0);
+ mSelectedLink = -1;
+}
+
+void BrowserBox::mousePress(int mx, int my, int button)
+{
+ if ((button == gcn::MouseInput::LEFT) && mLinkHandler)
+ {
+ for (unsigned int i = 0; i < mLinks.size(); i++)
+ {
+ if ((mx >= mLinks[i].x1) && (mx < mLinks[i].x2) &&
+ (my > mLinks[i].y1) && (my < mLinks[i].y2))
+ {
+ mLinkHandler->handleLink(mLinks[i].link);
+ return;
+ }
+ }
+ }
+}
+
+void BrowserBox::mouseMotion(int mx, int my)
+{
+ for (unsigned int i = 0; i < mLinks.size(); i++)
+ {
+ if ((mx >= mLinks[i].x1) && (mx < mLinks[i].x2) &&
+ (my > mLinks[i].y1) && (my < mLinks[i].y2))
+ {
+ mSelectedLink = (int) i;
+ return;
+ }
+ else
+ {
+ mSelectedLink = -1;
+ }
+ }
+}
+
+void BrowserBox::draw(gcn::Graphics* graphics)
+{
+ if (mOpaque)
+ {
+ graphics->setColor(gcn::Color(BGCOLOR));
+ graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ if (mSelectedLink >= 0)
+ {
+ if ((mHighMode == BACKGROUND) || (mHighMode == BOTH))
+ {
+ graphics->setColor(gcn::Color(HIGHLIGHT));
+ graphics->fillRectangle(gcn::Rectangle(
+ mLinks[mSelectedLink].x1,
+ mLinks[mSelectedLink].y1,
+ mLinks[mSelectedLink].x2 - mLinks[mSelectedLink].x1,
+ mLinks[mSelectedLink].y2 - mLinks[mSelectedLink].y1));
+ }
+
+ if ((mHighMode == UNDERLINE) || (mHighMode == BOTH))
+ {
+ graphics->setColor(gcn::Color(LINK));
+ graphics->drawLine(
+ mLinks[mSelectedLink].x1,
+ mLinks[mSelectedLink].y2,
+ mLinks[mSelectedLink].x2,
+ mLinks[mSelectedLink].y2);
+ }
+ }
+
+ unsigned int i, j;
+ int x = 0, y = 0;
+ int wrappedLines = 0;
+ for (i = 0; i < mTextRows.size(); i++)
+ {
+ int selColor = BLACK;
+ int prevColor = selColor;
+ std::string row = mTextRows[i];
+ x = 0;
+
+ for (j = 0; j < row.size(); j++)
+ {
+ // Check for color change in format "##x", x = [L,P,0..9]
+ if ((row.at(j) == '#') && (row.at(j + 1) == '#'))
+ {
+ switch (row.at(j + 2))
+ {
+ case 'L': // Link color
+ prevColor = selColor;
+ selColor = LINK;
+ break;
+ case 'P': // Previous color
+ selColor = prevColor;
+ break;
+ case '1':
+ prevColor = selColor;
+ selColor = RED;
+ break;
+ case '2':
+ prevColor = selColor;
+ selColor = GREEN;
+ break;
+ case '3':
+ prevColor = selColor;
+ selColor = BLUE;
+ break;
+ case '4':
+ prevColor = selColor;
+ selColor = ORANGE;
+ break;
+ case '5':
+ prevColor = selColor;
+ selColor = YELLOW;
+ break;
+ case '6':
+ prevColor = selColor;
+ selColor = PINK;
+ break;
+ case '7':
+ prevColor = selColor;
+ selColor = PURPLE;
+ break;
+ case '8':
+ prevColor = selColor;
+ selColor = GRAY;
+ break;
+ case '9':
+ prevColor = selColor;
+ selColor = BROWN;
+ break;
+ case '0':
+ default:
+ prevColor = selColor;
+ selColor = BLACK;
+ }
+ j += 3;
+
+ if (j == row.size())
+ {
+ break;
+ }
+ }
+ graphics->setColor(gcn::Color(selColor));
+
+ // Check for line separators in format "---"
+ if ((j <= 3) && (row.at(j) == '-') && (row.at(j + 1) == '-') &&
+ (row.at(j + 2) == '-'))
+ {
+ for (x = 0; x < getWidth(); x++)
+ {
+ browserFont->drawGlyph(graphics, '-', x, y);
+ x += browserFont->getWidth('-') - 2;
+ }
+ break;
+ }
+ // Draw each char
+ else
+ {
+ browserFont->drawGlyph(graphics, row.at(j), x, y);
+ x += browserFont->getWidth(row.at(j));
+
+ // Auto wrap mode
+ if (mMode == AUTO_WRAP)
+ {
+ /** NOTE (by Javila): this is just a simple example and
+ * will force text wrap at widget width!!!
+ * Maybe it can need improvements.
+ */
+ if ((x + 2 * browserFont->getWidth('~')) > getWidth())
+ {
+ browserFont->drawGlyph(graphics, '~',
+ getWidth() - browserFont->getWidth('~'), y);
+ x = 15; // Ident in new line
+ y += browserFont->getHeight();
+ wrappedLines++;
+ }
+ }
+ }
+ }
+ y += browserFont->getHeight();
+ setHeight((mTextRows.size() + wrappedLines) * browserFont->getHeight());
+ }
+}
diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h
new file mode 100644
index 00000000..8ac5a54c
--- /dev/null
+++ b/src/gui/browserbox.h
@@ -0,0 +1,147 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef __TMW_BROWSERBOX_H__
+#define __TMW_BROWSERBOX_H__
+
+#include <guichan.hpp>
+#include "window.h"
+#include "linkhandler.h"
+
+struct BROWSER_LINK {
+ int x1, x2, y1, y2; /**< Where link is placed */
+ std::string link;
+ std::string caption;
+};
+
+/**
+ * A simple browser box able to handle links and forward events to the
+ * parent conteiner.
+ */
+class BrowserBox : public gcn::Widget, public gcn::MouseListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ BrowserBox(unsigned int mode = AUTO_SIZE);
+
+ /**
+ * Destructor.
+ */
+ ~BrowserBox();
+
+ /**
+ * Sets the handler for links.
+ */
+ void setLinkHandler(LinkHandler* linkHandler);
+
+ /**
+ * Sets the BrowserBox opacity.
+ */
+ void setOpaque(bool opaque);
+
+ /**
+ * Sets the Highlight mode for links.
+ */
+ void setHighlightMode(unsigned int highMode);
+
+ /**
+ * Adds a text row to the browser.
+ */
+ void addRow(const std::string& row);
+
+ /**
+ * Remove all rows.
+ */
+ void clearRows();
+
+ /**
+ * Handles mouse actions.
+ */
+ void mousePress(int mx, int my, int button);
+ void mouseMotion(int mx, int my);
+
+ /**
+ * Draws the browser box.
+ */
+ void draw(gcn::Graphics* graphics);
+
+ /**
+ * BrowserBox modes.
+ */
+ enum {
+ AUTO_SIZE,
+ AUTO_WRAP /**< Maybe it needs a fix or to be redone. */
+ };
+
+ /**
+ * BrowserBox colors.
+ *
+ * NOTES (by Javila):
+ * - color values is "0x" prefix followed by HTML color style.
+ * - we can add up to 10 different colors: [0..9].
+ * - we need a link and a highlighted link colors.
+ * - not all colors will be fine with all backgrounds due transparent
+ * windows and widgets. So, I think it's better keep BrowserBox
+ * opaque (white background) by default.
+ */
+ enum {
+ BLACK = 0x000000, /**< Color 0 */
+ RED = 0xff0000, /**< Color 1 */
+ GREEN = 0x1fa052, /**< Color 2 */
+ BLUE = 0x0000ff, /**< Color 3 */
+ ORANGE = 0xe0980e, /**< Color 4 */
+ YELLOW = 0xf1dc27, /**< Color 5 */
+ PINK = 0xff00d8, /**< Color 6 */
+ PURPLE = 0x8415e2, /**< Color 7 */
+ GRAY = 0x919191, /**< Color 8 */
+ BROWN = 0x8e4c17, /**< Color 9 */
+ BGCOLOR = 0xffffff, /**< Bg color for opacity */
+ LINK = 0xe50d0d, /**< Color L */
+ HIGHLIGHT = 0xcacaca /**< Bg color for highlighted link */
+ };
+
+ /**
+ * Highlight modes for links.
+ */
+ enum {
+ UNDERLINE,
+ BACKGROUND,
+ BOTH
+ };
+
+ private:
+ std::vector<std::string> mTextRows;
+ std::vector<BROWSER_LINK> mLinks;
+ LinkHandler *mLinkHandler;
+ unsigned int mMode;
+ unsigned int mHighMode;
+ bool mOpaque;
+ int mSelectedLink;
+
+ static int instances; /**< Number of Window instances */
+ static gcn::ImageFont* browserFont;
+};
+
+#endif
diff --git a/src/gui/linkhandler.h b/src/gui/linkhandler.h
new file mode 100644
index 00000000..05a0a99b
--- /dev/null
+++ b/src/gui/linkhandler.h
@@ -0,0 +1,42 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _TMW_LINK_HANDLER_H
+#define _TMW_LINK_HANDLER_H
+
+/**
+ * A simple interface to windows that need to handle links from BrowserBox
+ * widget.
+ */
+class LinkHandler
+{
+ public:
+ virtual ~LinkHandler() { }
+
+ virtual void handleLink(const std::string& link) { }
+
+ protected:
+ LinkHandler() { }
+};
+
+#endif
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
new file mode 100644
index 00000000..c56bdfc8
--- /dev/null
+++ b/src/gui/popupmenu.cpp
@@ -0,0 +1,213 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include "popupmenu.h"
+#include "../graphics.h"
+#include "../engine.h"
+#include "../game.h"
+#include <iostream>
+
+PopupMenu::PopupMenu():
+ Window()
+{
+ setResizable(false);
+ setTitleBarHeight(0);
+
+ browserBox = new BrowserBox();
+ browserBox->setPosition(4, 4);
+ browserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ browserBox->setOpaque(false);
+ add(browserBox);
+ browserBox->setLinkHandler(this);
+
+ being = NULL;
+ floorItem = NULL;
+ mX = -1;
+ mY = -1;
+}
+
+PopupMenu::~PopupMenu()
+{
+ delete browserBox;
+ delete being;
+ delete floorItem;
+}
+
+void PopupMenu::setVisible(bool visible)
+{
+ if (visible == false)
+ {
+ if (hasFocus())
+ {
+ mFocusHandler->focusNone();
+ }
+ setPosition(screen->w, screen->h);
+ }
+
+ mVisible = visible;
+}
+
+void PopupMenu::showPopup(int mx, int my)
+{
+ being = findNode(mx, my);
+ floorItem = find_floor_item_by_id(find_floor_item_by_cor(mx, my));
+ mX = mx;
+ mY = mY;
+ browserBox->clearRows();
+
+ if (being)
+ {
+ if (being->isMonster())
+ {
+ browserBox->addRow("@@attack|Attack Monster@@");
+ }
+ else if (being->isNpc())
+ {
+ browserBox->addRow("@@talk|Talk To NPC@@");
+ }
+ else if (being->isPlayer())
+ {
+ std::string name = being->name;
+ //browserBox->addRow("@@attack|Attack " + name + "@@");
+ browserBox->addRow("@@trade|Trade With " + name + "@@");
+ browserBox->addRow("@@follow|Follow " + name + "@@");
+ browserBox->addRow("@@buddy|Add " + name + " to Buddy List@@");
+ }
+ }
+ else if (floorItem)
+ {
+ std::string name = itemDb->getItemInfo(floorItem->id)->getName();
+ browserBox->addRow("@@pickup|Pick Up " + name + "@@");
+ }
+ else
+ {
+ browserBox->addRow("@@walk|Walk To@@");
+ }
+ //browserBox->addRow("@@look|Look To@@");
+ browserBox->addRow("##3---");
+ browserBox->addRow("@@cancel|Cancel@@");
+
+ setContentSize(browserBox->getWidth() + 8, browserBox->getHeight() + 8);
+ mx = (mx - camera_x) * 32 + 25;
+ my = (my - camera_y) * 32 + 25;
+ if (screen->w < (mx + getWidth() + 5))
+ mx -= (getWidth() + 50);
+ if (screen->h < (my + getHeight() + 5))
+ my -= (getHeight() + 50);
+ setPosition(mx, my);
+ setVisible(true);
+}
+
+void PopupMenu::draw(gcn::Graphics* graphics)
+{
+ int x, y;
+ getAbsolutePosition(x, y);
+
+ ((Graphics*) graphics)->drawImageRect(x, y, getWidth(), getHeight(),
+ border);
+
+ if (mContent != NULL)
+ {
+ graphics->pushClipArea(getContentDimension());
+ graphics->pushClipArea(gcn::Rectangle(
+ 0, 0, mContent->getWidth(), mContent->getHeight()));
+ mContent->draw(graphics);
+ graphics->popClipArea();
+ graphics->popClipArea();
+ }
+}
+
+void PopupMenu::handleLink(const std::string& link)
+{
+ // Attack action
+ if ((link == "attack") && being)
+ {
+ if (being->isMonster() && (being->action != MONSTER_DEAD))
+ {
+ autoTarget = being;
+ attack(being);
+ }
+ }
+
+ // Talk To action
+ else if ((link == "talk") && being && being->isNpc() &&
+ (current_npc == 0))
+ {
+ WFIFOW(0) = net_w_value(0x0090);
+ WFIFOL(2) = net_l_value(being->id);
+ WFIFOB(6) = 0;
+ WFIFOSET(7);
+ current_npc = being->id;
+ }
+
+ // Trade action
+ else if ((link == "trade") && being && being->isPlayer())
+ {
+ WFIFOW(0) = net_w_value(0x00e4);
+ WFIFOL(2) = net_l_value(being->id);
+ WFIFOSET(6);
+ }
+
+ // Follow Player action
+ else if (link == "follow")
+ {
+ }
+
+ // Add Buddy action
+ else if (link == "buddy")
+ {
+ }
+
+ // Pick Up Floor Item action
+ else if ((link == "pickup") && floorItem)
+ {
+ WFIFOW(0) = net_w_value(0x009f);
+ WFIFOL(2) = net_l_value(floorItem->int_id);
+ WFIFOSET(6);
+ }
+
+ // Walk To action
+ else if ((link == "walk") && (mX != -1) && (mY != -1))
+ {
+ //walk(mX, mY, 0);
+ //player_node->setDestination(mX, mY);
+ }
+
+ // Look To action
+ else if (link == "look")
+ {
+ }
+
+ // Unknown actions
+ else
+ {
+ std::cout << link << std::endl;
+ }
+
+ setVisible(false);
+
+ being = NULL;
+ floorItem = NULL;
+ mX = -1;
+ mY = -1;
+}
diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h
new file mode 100644
index 00000000..77c8931a
--- /dev/null
+++ b/src/gui/popupmenu.h
@@ -0,0 +1,78 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _TMW_POPUP_MENU_H
+#define _TMW_POPUP_MENU_H
+
+#include <guichan.hpp>
+#include "window.h"
+#include "linkhandler.h"
+#include "browserbox.h"
+#include "../being.h"
+#include "../floor_item.h"
+
+/**
+ * Window showing popup menu.
+ */
+class PopupMenu : public Window, public LinkHandler
+{
+ public:
+ /**
+ * Constructor.
+ */
+ PopupMenu();
+
+ /**
+ * Destructor.
+ */
+ ~PopupMenu();
+
+ /**
+ * Sets the visibility of popup
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Shows the related popup menu specifies by the mouse click coords.
+ */
+ void showPopup(int mx, int my);
+
+ /**
+ * Draws updated popup menu
+ */
+ void draw(gcn::Graphics* graphics);
+
+ /**
+ * Handles link action.
+ */
+ void handleLink(const std::string& link);
+
+ private:
+ BrowserBox* browserBox;
+ int mX, mY;
+
+ Being* being;
+ FloorItem* floorItem;
+};
+
+#endif