summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2009-03-25 22:50:59 +0100
committerBjørn Lindeijer <bjorn@lindeijer.nl>2009-03-25 22:50:59 +0100
commitcc79f0fe21e1a2ef73cbe987d54e848b9a47142d (patch)
treeedd316eb6094f0c02d6d014385865dcd88a2bc56 /src/gui
parentb0df784f1be44a657ca8092069488602270629b7 (diff)
parent99e8a3fd77b63a029fe02dcf771b6af1aad252ed (diff)
downloadmana-cc79f0fe21e1a2ef73cbe987d54e848b9a47142d.tar.gz
mana-cc79f0fe21e1a2ef73cbe987d54e848b9a47142d.tar.bz2
mana-cc79f0fe21e1a2ef73cbe987d54e848b9a47142d.tar.xz
mana-cc79f0fe21e1a2ef73cbe987d54e848b9a47142d.zip
Merge branch 'eathena/master'
Conflicts: A lot of files.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/browserbox.cpp25
-rw-r--r--src/gui/button.cpp13
-rw-r--r--src/gui/buy.cpp81
-rw-r--r--src/gui/buy.h17
-rw-r--r--src/gui/buysell.cpp62
-rw-r--r--src/gui/buysell.h16
-rw-r--r--src/gui/char_select.cpp35
-rw-r--r--src/gui/char_server.cpp2
-rw-r--r--src/gui/chat.cpp85
-rw-r--r--src/gui/chat.h26
-rw-r--r--src/gui/checkbox.cpp13
-rw-r--r--src/gui/checkbox.h5
-rw-r--r--src/gui/color.cpp146
-rw-r--r--src/gui/color.h136
-rw-r--r--src/gui/confirm_dialog.cpp20
-rw-r--r--src/gui/connection.cpp7
-rw-r--r--src/gui/debugwindow.cpp49
-rw-r--r--src/gui/debugwindow.h2
-rw-r--r--src/gui/emotecontainer.cpp7
-rw-r--r--src/gui/emotecontainer.h2
-rw-r--r--src/gui/emoteshortcutcontainer.cpp41
-rw-r--r--src/gui/emoteshortcutcontainer.h2
-rw-r--r--src/gui/emotewindow.cpp2
-rw-r--r--src/gui/equipmentwindow.cpp45
-rw-r--r--src/gui/gui.cpp37
-rw-r--r--src/gui/gui.h20
-rw-r--r--src/gui/help.cpp13
-rw-r--r--src/gui/inventorywindow.cpp13
-rw-r--r--src/gui/inventorywindow.h10
-rw-r--r--src/gui/item_amount.cpp122
-rw-r--r--src/gui/item_amount.h13
-rw-r--r--src/gui/itemcontainer.cpp19
-rw-r--r--src/gui/itemlinkhandler.cpp17
-rw-r--r--src/gui/itempopup.cpp66
-rw-r--r--src/gui/itempopup.h33
-rw-r--r--src/gui/itemshortcutcontainer.cpp84
-rw-r--r--src/gui/itemshortcutcontainer.h5
-rw-r--r--src/gui/label.cpp40
-rw-r--r--src/gui/label.h55
-rw-r--r--src/gui/listbox.cpp103
-rw-r--r--src/gui/listbox.h19
-rw-r--r--src/gui/login.cpp45
-rw-r--r--src/gui/menuwindow.cpp14
-rw-r--r--src/gui/menuwindow.h4
-rw-r--r--src/gui/minimap.cpp16
-rw-r--r--src/gui/ministatus.cpp52
-rw-r--r--src/gui/ministatus.h4
-rw-r--r--src/gui/npc_text.cpp62
-rw-r--r--src/gui/npc_text.h33
-rw-r--r--src/gui/npcintegerdialog.cpp60
-rw-r--r--src/gui/npcintegerdialog.h19
-rw-r--r--src/gui/npclistdialog.cpp64
-rw-r--r--src/gui/npclistdialog.h21
-rw-r--r--src/gui/npcstringdialog.cpp48
-rw-r--r--src/gui/npcstringdialog.h15
-rw-r--r--src/gui/ok_dialog.cpp19
-rw-r--r--src/gui/palette.cpp347
-rw-r--r--src/gui/palette.h350
-rw-r--r--src/gui/playerbox.cpp3
-rw-r--r--src/gui/popup.cpp209
-rw-r--r--src/gui/popup.h194
-rw-r--r--src/gui/popupmenu.cpp12
-rw-r--r--src/gui/popupmenu.h4
-rw-r--r--src/gui/progressbar.cpp26
-rw-r--r--src/gui/progressbar.h3
-rw-r--r--src/gui/radiobutton.cpp3
-rw-r--r--src/gui/recorder.cpp8
-rw-r--r--src/gui/register.cpp18
-rw-r--r--src/gui/register.h3
-rw-r--r--src/gui/scrollarea.cpp6
-rw-r--r--src/gui/sell.cpp123
-rw-r--r--src/gui/sell.h17
-rw-r--r--src/gui/setup.cpp55
-rw-r--r--src/gui/setup.h8
-rw-r--r--src/gui/setup_audio.cpp10
-rw-r--r--src/gui/setup_colors.cpp268
-rw-r--r--src/gui/setup_colors.h10
-rw-r--r--src/gui/setup_joystick.cpp5
-rw-r--r--src/gui/setup_players.cpp13
-rw-r--r--src/gui/setup_video.cpp100
-rw-r--r--src/gui/setup_video.h6
-rw-r--r--src/gui/shop.cpp48
-rw-r--r--src/gui/shop.h49
-rw-r--r--src/gui/shoplistbox.cpp51
-rw-r--r--src/gui/shoplistbox.h2
-rw-r--r--src/gui/shortcutcontainer.cpp29
-rw-r--r--src/gui/shortcutwindow.cpp31
-rw-r--r--src/gui/shortcutwindow.h5
-rw-r--r--src/gui/skill.cpp17
-rw-r--r--src/gui/skin.cpp191
-rw-r--r--src/gui/skin.h101
-rw-r--r--src/gui/slider.cpp10
-rw-r--r--src/gui/speechbubble.cpp31
-rw-r--r--src/gui/speechbubble.h29
-rw-r--r--src/gui/status.cpp189
-rw-r--r--src/gui/status.h5
-rw-r--r--src/gui/statuswindow.cpp50
-rw-r--r--src/gui/statuswindow.h2
-rw-r--r--src/gui/storagewindow.cpp210
-rw-r--r--src/gui/storagewindow.h110
-rw-r--r--src/gui/table.cpp56
-rw-r--r--src/gui/textbox.cpp37
-rw-r--r--src/gui/textbox.h15
-rw-r--r--src/gui/textfield.cpp35
-rw-r--r--src/gui/textrenderer.h81
-rw-r--r--src/gui/trade.cpp87
-rw-r--r--src/gui/trade.h12
-rw-r--r--src/gui/truetypefont.cpp3
-rw-r--r--src/gui/truetypefont.h6
-rw-r--r--src/gui/updatewindow.cpp8
-rw-r--r--src/gui/viewport.cpp59
-rw-r--r--src/gui/viewport.h29
-rw-r--r--src/gui/widgets/dropdown.cpp46
-rw-r--r--src/gui/widgets/tab.cpp18
-rw-r--r--src/gui/widgets/tabbedarea.cpp17
-rw-r--r--src/gui/widgets/textpreview.cpp81
-rw-r--r--src/gui/widgets/textpreview.h142
-rw-r--r--src/gui/window.cpp444
-rw-r--r--src/gui/window.h67
-rw-r--r--src/gui/windowcontainer.cpp2
-rw-r--r--src/gui/windowcontainer.h7
121 files changed, 4522 insertions, 1675 deletions
diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp
index 7c0ae1a7..2f667237 100644
--- a/src/gui/browserbox.cpp
+++ b/src/gui/browserbox.cpp
@@ -24,8 +24,8 @@
#include <guichan/graphics.hpp>
#include "browserbox.h"
-#include "color.h"
#include "linkhandler.h"
+#include "palette.h"
#include "truetypefont.h"
BrowserBox::BrowserBox(unsigned int mode, bool opaque):
@@ -225,6 +225,7 @@ struct MouseOverLink
void BrowserBox::mousePressed(gcn::MouseEvent &event)
{
+ if (!mLinkHandler) return;
LinkIterator i = find_if(mLinks.begin(), mLinks.end(),
MouseOverLink(event.getX(), event.getY()));
@@ -243,18 +244,20 @@ void BrowserBox::mouseMoved(gcn::MouseEvent &event)
void BrowserBox::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
if (mOpaque)
{
- graphics->setColor(gcn::Color(BGCOLOR));
+ graphics->setColor(guiPalette->getColor(Palette::BACKGROUND));
graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
}
if (mSelectedLink >= 0)
{
- bool valid;
if ((mHighMode & BACKGROUND))
{
- graphics->setColor(gcn::Color(textColor->getColor('H', valid)));
+ graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT));
graphics->fillRectangle(gcn::Rectangle(
mLinks[mSelectedLink].x1,
mLinks[mSelectedLink].y1,
@@ -265,7 +268,7 @@ void BrowserBox::draw(gcn::Graphics *graphics)
if ((mHighMode & UNDERLINE))
{
- graphics->setColor(gcn::Color(textColor->getColor('<', valid)));
+ graphics->setColor(guiPalette->getColor(Palette::HYPERLINK));
graphics->drawLine(
mLinks[mSelectedLink].x1,
mLinks[mSelectedLink].y2,
@@ -279,11 +282,11 @@ void BrowserBox::draw(gcn::Graphics *graphics)
int link = 0;
TrueTypeFont *font = static_cast<TrueTypeFont*>(getFont());
- graphics->setColor(BLACK);
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
{
- int selColor = BLACK;
- int prevColor = selColor;
+ const gcn::Color *selColor = &guiPalette->getColor(Palette::TEXT);
+ const gcn::Color *prevColor = selColor;
std::string row = *(i);
bool wrapped = false;
x = 0;
@@ -331,7 +334,7 @@ void BrowserBox::draw(gcn::Graphics *graphics)
else
{
bool valid;
- int rgb = textColor->getColor(c, valid);
+ const gcn::Color *col = &guiPalette->getColor(c, valid);
if (c == '<')
{
const int size = mLinks[link].x2 - mLinks[link].x1;
@@ -344,7 +347,7 @@ void BrowserBox::draw(gcn::Graphics *graphics)
}
if (valid)
{
- selColor = rgb;
+ selColor = col;
}
}
start += 3;
@@ -354,7 +357,7 @@ void BrowserBox::draw(gcn::Graphics *graphics)
break;
}
}
- graphics->setColor(gcn::Color(selColor));
+ graphics->setColor(*selColor);
}
std::string::size_type len =
diff --git a/src/gui/button.cpp b/src/gui/button.cpp
index 1d3a04e4..f9e5e9dc 100644
--- a/src/gui/button.cpp
+++ b/src/gui/button.cpp
@@ -23,6 +23,7 @@
#include <guichan/font.hpp>
#include "button.h"
+#include "palette.h"
#include "../configuration.h"
#include "../graphics.h"
@@ -72,9 +73,9 @@ Button::Button(const std::string& caption, const std::string &actionEventId,
{
init();
setActionEventId(actionEventId);
- if (listener) {
+
+ if (listener)
addActionListener(listener);
- }
}
void Button::init()
@@ -93,8 +94,10 @@ void Button::init()
{
btn[mode] = resman->getImage(data[mode].file);
a = 0;
- for (y = 0; y < 3; y++) {
- for (x = 0; x < 3; x++) {
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
button[mode].grid[a] = btn[mode]->getSubImage(
data[x].gridX, data[y].gridY,
data[x + 1].gridX - data[x].gridX + 1,
@@ -150,7 +153,7 @@ void Button::draw(gcn::Graphics *graphics)
static_cast<Graphics*>(graphics)->
drawImageRect(0, 0, getWidth(), getHeight(), button[mode]);
- graphics->setColor(getForegroundColor());
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
int textX;
int textY = getHeight() / 2 - getFont()->getHeight() / 2;
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index 53a586c3..0b572a23 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -19,10 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "buy.h"
+#include "label.h"
#include "scrollarea.h"
#include "shop.h"
#include "shoplistbox.h"
@@ -56,29 +55,34 @@ BuyDialog::BuyDialog(Network *network):
{
setWindowName("Buy");
setResizable(true);
+ setCloseButton(true);
setMinWidth(260);
setMinHeight(230);
- setDefaultSize(0, 0, 260, 230);
+ setDefaultSize(260, 230, ImageRect::CENTER);
mShopItems = new ShopItems;
mShopItemList = new ShopListBox(mShopItems, mShopItems);
mScrollArea = new ScrollArea(mShopItemList);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
mSlider = new Slider(1.0);
- mQuantityLabel = new gcn::Label("0");
+ mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"),
"", ""));
+
mIncreaseButton = new Button("+", "+", this);
mDecreaseButton = new Button("-", "-", this);
mBuyButton = new Button(_("Buy"), "buy", this);
mQuitButton = new Button(_("Quit"), "quit", this);
- mItemDescLabel = new gcn::Label(strprintf(_("Description: %s"), ""));
- mItemEffectLabel = new gcn::Label(strprintf(_("Effect: %s"), ""));
+ mAddMaxButton = new Button(_("Max"), "max", this);
+ mItemDescLabel = new Label(strprintf(_("Description: %s"), ""));
+ mItemEffectLabel = new Label(strprintf(_("Effect: %s"), ""));
- mIncreaseButton->setSize(20, 20);
- mDecreaseButton->setSize(20, 20);
+ mDecreaseButton->adjustSize();
+ mDecreaseButton->setWidth(mIncreaseButton->getWidth());
- mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mIncreaseButton->setEnabled(false);
mDecreaseButton->setEnabled(false);
mBuyButton->setEnabled(false);
@@ -88,21 +92,26 @@ BuyDialog::BuyDialog(Network *network):
mSlider->addActionListener(this);
mShopItemList->addSelectionListener(this);
- place(0, 0, mScrollArea, 5).setPadding(3);
- place(0, 1, mQuantityLabel, 2);
- place(2, 1, mSlider, 3);
- place(0, 2, mMoneyLabel, 5);
- place(0, 3, mItemEffectLabel, 5);
- place(0, 4, mItemDescLabel, 5);
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mScrollArea, 8, 5).setPadding(3);
place(0, 5, mDecreaseButton);
- place(1, 5, mIncreaseButton);
- place(3, 5, mBuyButton);
- place(4, 5, mQuitButton);
+ place(1, 5, mSlider, 3);
+ place(4, 5, mIncreaseButton);
+ place(5, 5, mQuantityLabel, 2);
+ place(7, 5, mAddMaxButton);
+ place(0, 6, mMoneyLabel, 8);
+ place(0, 7, mItemEffectLabel, 8);
+ place(0, 8, mItemDescLabel, 8);
+ place(6, 9, mBuyButton);
+ place(7, 9, mQuitButton);
+
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
- setLocationRelativeTo(getParent());
}
BuyDialog::~BuyDialog()
@@ -138,15 +147,14 @@ void BuyDialog::addItem(int id, int amount, int price)
void BuyDialog::action(const gcn::ActionEvent &event)
{
- int selectedItem = mShopItemList->getSelected();
-
if (event.getId() == "quit")
{
- setVisible(false);
- if (current_npc) current_npc->handleDeath();
+ close();
return;
}
+ int selectedItem = mShopItemList->getSelected();
+
// The following actions require a valid selection
if (selectedItem < 0 ||
selectedItem >= (int) mShopItems->getNumberOfElements())
@@ -171,6 +179,12 @@ void BuyDialog::action(const gcn::ActionEvent &event)
mSlider->setValue(mAmountItems);
updateButtonsAndLabels();
}
+ else if (event.getId() == "max")
+ {
+ mAmountItems = mMaxItems;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
// TODO: Actually we'd have a bug elsewhere if this check for the number
// of items to be bought ever fails, Bertram removed the assertions, is
// there a better way to ensure this fails in an _obvious_ way in C++?
@@ -257,3 +271,24 @@ void BuyDialog::updateButtonsAndLabels()
Units::formatCurrency(price).c_str(),
Units::formatCurrency(mMoney - price).c_str()));
}
+
+void BuyDialog::logic()
+{
+ Window::logic();
+
+ if (!current_npc) setVisible(false);
+}
+
+void BuyDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (visible)
+ requestFocus();
+}
+
+void BuyDialog::close()
+{
+ setVisible(false);
+ current_npc = 0;
+}
diff --git a/src/gui/buy.h b/src/gui/buy.h
index 5510ccc6..200394b9 100644
--- a/src/gui/buy.h
+++ b/src/gui/buy.h
@@ -101,12 +101,27 @@ class BuyDialog : public Window, public gcn::ActionListener,
*/
void updateButtonsAndLabels();
+ /**
+ * Check for current NPC
+ */
+ void logic();
+
+ /**
+ * Sets the visibility of this window.
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Closes the Buy Window, as well as resetting the current npc.
+ */
+ void close();
private:
#ifdef EATHENA_SUPPORT
Network *mNetwork;
#endif
gcn::Button *mBuyButton;
gcn::Button *mQuitButton;
+ gcn::Button *mAddMaxButton;
gcn::Button *mIncreaseButton;
gcn::Button *mDecreaseButton;
ShopListBox *mShopItemList;
@@ -124,4 +139,6 @@ class BuyDialog : public Window, public gcn::ActionListener,
int mMaxItems;
};
+extern BuyDialog *buyDialog;
+
#endif
diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp
index 2d39eac7..c56f6435 100644
--- a/src/gui/buysell.cpp
+++ b/src/gui/buysell.cpp
@@ -24,11 +24,17 @@
#include "../npc.h"
+#include "../net/messageout.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
+
#include "../utils/gettext.h"
-BuySellDialog::BuySellDialog():
- Window(_("Shop"))
+BuySellDialog::BuySellDialog(Network *network):
+ Window(_("Shop")), mNetwork(network)
{
+ setWindowName("BuySell");
Button *buyButton = 0;
static const char *buttonNames[] = {
N_("Buy"), N_("Sell"), N_("Cancel"), 0
@@ -46,19 +52,53 @@ BuySellDialog::BuySellDialog():
buyButton->requestFocus();
setContentSize(x, 2 * y + buyButton->getHeight());
- setLocationRelativeTo(getParent());
- requestFocus();
+ center();
+ setDefaultSize();
+ loadWindowState();
+}
+
+void BuySellDialog::logic()
+{
+ Window::logic();
+
+ if (isVisible() && !current_npc)
+ setVisible(false);
+}
+
+void BuySellDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (visible)
+ requestFocus();
}
void BuySellDialog::action(const gcn::ActionEvent &event)
{
- if (event.getId() == "Buy") {
- current_npc->buy();
- } else if (event.getId() == "Sell") {
- current_npc->sell();
- } else if (event.getId() == "Cancel") {
- if (current_npc) current_npc->handleDeath();
- }
setVisible(false);
+ int action = 0;
+
+ NPC::isTalking = false;
+
+ if (event.getId() == "Buy")
+ {
+ action = 0;
+ }
+ else if (event.getId() == "Sell")
+ {
+ action = 1;
+ }
+ else if (event.getId() == "Cancel")
+ {
+ current_npc = 0;
+ return;
+ }
+
+#ifdef EATHENA_SUPPORT
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_NPC_BUY_SELL_REQUEST);
+ outMsg.writeInt32(current_npc);
+ outMsg.writeInt8(action);
+#endif
}
diff --git a/src/gui/buysell.h b/src/gui/buysell.h
index e3cdc52a..4b137554 100644
--- a/src/gui/buysell.h
+++ b/src/gui/buysell.h
@@ -26,6 +26,8 @@
#include "window.h"
+class Network;
+
/**
* A dialog to choose between buying or selling at a shop.
*
@@ -40,12 +42,24 @@ class BuySellDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
- BuySellDialog();
+ BuySellDialog(Network *network);
+
+ /**
+ * Check for current NPC
+ */
+ void logic();
+
+ void setVisible(bool visible);
/**
* Called when receiving actions from the widgets.
*/
void action(const gcn::ActionEvent &event);
+
+ private:
+ Network *mNetwork;
};
+extern BuySellDialog *buySellDialog;
+
#endif
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index e4f560ce..7c0e2ab2 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -23,11 +23,10 @@
#include <guichan/font.hpp>
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "char_select.h"
#include "confirm_dialog.h"
+#include "label.h"
#include "ok_dialog.h"
#include "playerbox.h"
#include "textfield.h"
@@ -63,6 +62,8 @@
#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
+#define MAX_SLOT 2
+
// Defined in main.cpp, used here for setting the char create dialog
extern CharServerHandler charServerHandler;
@@ -114,8 +115,8 @@ CharSelectDialog::CharSelectDialog(Network *network,
mCancelButton = new Button(_("Cancel"), "cancel", this);
mPreviousButton = new Button(_("Previous"), "previous", this);
mNextButton = new Button(_("Next"), "next", this);
- mNameLabel = new gcn::Label(strprintf(_("Name: %s"), ""));
- mLevelLabel = new gcn::Label(strprintf(_("Level: %d"), 0));
+ mNameLabel = new Label(strprintf(_("Name: %s"), ""));
+ mLevelLabel = new Label(strprintf(_("Level: %d"), 0));
#ifdef TMWSERV_SUPPORT
mNewCharButton = new Button(_("New"), "new", this);
mDelCharButton = new Button(_("Delete"), "delete", this);
@@ -123,10 +124,10 @@ CharSelectDialog::CharSelectDialog(Network *network,
mChangePasswordButton = new Button(_("Change Password"), "change_password", this);
mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this);
- mAccountNameLabel = new gcn::Label(strprintf(_("Account: %s"), mLoginData->username.c_str()));
- mNameLabel = new gcn::Label(strprintf(_("Name: %s"), ""));
- mLevelLabel = new gcn::Label(strprintf(_("Level: %d"), 0));
- mMoneyLabel = new gcn::Label(strprintf(_("Money: %d"), 0));
+ mAccountNameLabel = new Label(strprintf(_("Account: %s"), mLoginData->username.c_str()));
+ mNameLabel = new Label(strprintf(_("Name: %s"), ""));
+ mLevelLabel = new Label(strprintf(_("Level: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %d"), 0));
// Control that shows the Player
mPlayerBox = new PlayerBox;
@@ -161,8 +162,8 @@ CharSelectDialog::CharSelectDialog(Network *network,
mPlayerBox = new PlayerBox;
mPlayerBox->setWidth(74);
- mJobLevelLabel = new gcn::Label(strprintf(_("Job Level: %d"), 0));
- mMoneyLabel = new gcn::Label(strprintf(_("Money: %s"), mMoney.c_str()));
+ mJobLevelLabel = new Label(strprintf(_("Job Level: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %s"), mMoney.c_str()));
const std::string tempString = getFont()->getWidth(_("New")) <
getFont()->getWidth(_("Delete")) ?
@@ -189,7 +190,7 @@ CharSelectDialog::CharSelectDialog(Network *network,
reflowLayout(250, 0);
#endif
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mSelectButton->requestFocus();
updatePlayerInfo();
@@ -252,11 +253,11 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
else if (event.getId() == "newdel")
{
// Check for a character
- if (mCharInfo->getEntry() && n_character <= MAX_SLOT + 1)
+ if (mCharInfo->getEntry())
{
new CharDeleteConfirm(this);
}
- else
+ else if (n_character <= MAX_SLOT)
{
// Start new character dialog
CharCreateDialog *charCreateDialog =
@@ -421,13 +422,13 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
rand() % numberOfHairColors);
mNameField = new TextField("");
- mNameLabel = new gcn::Label(_("Name:"));
+ mNameLabel = new Label(_("Name:"));
mNextHairColorButton = new Button(">", "nextcolor", this);
mPrevHairColorButton = new Button("<", "prevcolor", this);
- mHairColorLabel = new gcn::Label(_("Hair Color:"));
+ mHairColorLabel = new Label(_("Hair Color:"));
mNextHairStyleButton = new Button(">", "nextstyle", this);
mPrevHairStyleButton = new Button("<", "prevstyle", this);
- mHairStyleLabel = new gcn::Label(_("Hair Style:"));
+ mHairStyleLabel = new Label(_("Hair Style:"));
mCreateButton = new Button(_("Create"), "create", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
#ifdef TMWSERV_SUPPORT
@@ -545,7 +546,7 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
reflowLayout(225, 0);
#endif
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mNameField->requestFocus();
}
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index fa03bdc2..5cfcef4d 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -85,7 +85,7 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
// Select first server
mServerList->setSelected(1);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mOkButton->requestFocus();
}
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index a072704b..597eddfd 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -71,7 +71,7 @@ ChatWindow::ChatWindow(Network * network):
setWindowName("Chat");
setResizable(true);
- setDefaultSize(0, windowContainer->getHeight() - 123, 600, 123);
+ setDefaultSize(600, 123, ImageRect::LOWER_LEFT);
setMinWidth(150);
setMinHeight(90);
@@ -121,7 +121,15 @@ ChatWindow::~ChatWindow()
config.setValue("PartyPrefix", partyPrefix);
config.setValue("ReturnToggles", mReturnToggles ? "1" : "0");
delete mRecorder;
+ delete mParty;
#endif
+ delete mItemLinkHandler;
+}
+
+void ChatWindow::resetToDefaultSize()
+{
+ mRecorder->resetToDefaultSize();
+ Window::resetToDefaultSize();
}
void ChatWindow::widgetResized(const gcn::Event &event)
@@ -303,6 +311,42 @@ void ChatWindow::chatLog(std::string line, int own, std::string channelName,
<< (int) ((t / 60) % 60)
<< "] ";
+ // Check for item link
+ std::string::size_type start = tmp.text.find('[');
+ while (start != std::string::npos && tmp.text[start+1] != '@')
+ {
+ std::string::size_type end = tmp.text.find(']', start);
+ if (start+1 != end && end != std::string::npos)
+ {
+ // Catch multiple embeds and ignore them
+ // so it doesn't crash the client.
+ while ((tmp.text.find('[', start + 1) != std::string::npos) &&
+ (tmp.text.find('[', start + 1) < end))
+ {
+ start = tmp.text.find('[', start + 1);
+ }
+
+ std::string temp = tmp.text.substr(start+1, end - start - 1);
+
+ trim(temp);
+
+ for (unsigned int i = 0; i < temp.size(); i++)
+ {
+ temp[i] = (char) tolower(temp[i]);
+ }
+
+ const ItemInfo itemInfo = ItemDB::get(temp);
+ if (itemInfo.getName() != _("Unknown item"))
+ {
+ tmp.text.insert(end, "@@");
+ tmp.text.insert(start+1, "|");
+ tmp.text.insert(start+1, toString(itemInfo.getId()));
+ tmp.text.insert(start+1, "@@");
+ }
+ }
+ start = tmp.text.find('[', start + 1);
+ }
+
line = lineColor + timeStr.str() + tmp.nick + tmp.text;
// We look if the Vertical Scroll Bar is set at the max before
@@ -370,7 +414,7 @@ void ChatWindow::action(const gcn::ActionEvent &event)
}
}
-void ChatWindow::requestChatFocus()
+bool ChatWindow::requestChatFocus()
{
// Make sure chatWindow is visible
if (!isVisible())
@@ -385,9 +429,14 @@ void ChatWindow::requestChatFocus()
mTmpVisible = true;
}
+ // Don't do anything else if the input is already visible and has focus
+ if (mChatInput->isVisible() && mChatInput->isFocused())
+ return false;
+
// Give focus to the chat input
mChatInput->setVisible(true);
mChatInput->requestFocus();
+ return true;
}
bool ChatWindow::isInputFocused()
@@ -488,38 +537,6 @@ void ChatWindow::chatSend(std::string &msg)
}
#endif
- // Check for item link
- std::string::size_type start = msg.find('[');
- while (start != std::string::npos && msg[start+1] != '@')
- {
- std::string::size_type end = msg.find(']', start);
- if (start+1 != end && end != std::string::npos)
- {
- // Catch multiple embeds and ignore them
- // so it doesn't crash the client.
- while ((msg.find('[', start + 1) != std::string::npos) &&
- (msg.find('[', start + 1) < end))
- {
- start = msg.find('[', start + 1);
- }
-
- std::string temp = msg.substr(start + 1, end - start - 1);
-
- toLower(trim(temp));
-
- const ItemInfo itemInfo = ItemDB::get(temp);
- if (itemInfo.getName() != _("Unknown item"))
- {
- msg.insert(end, "@@");
- msg.insert(start+1, "|");
- msg.insert(start+1, toString(itemInfo.getId()));
- msg.insert(start+1, "@@");
- }
- }
- start = msg.find('[', start + 1);
- }
-
-
// Prepare ordinary message
if (msg[0] != '/')
{
diff --git a/src/gui/chat.h b/src/gui/chat.h
index 972ecf9a..3c553c67 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -100,6 +100,12 @@ class ChatWindow : public Window,
void logic();
/**
+ * Reset the chat window and recorder window attached to it to their
+ * default positions.
+ */
+ void resetToDefaultSize();
+
+ /**
* Adds a line of text to our message list. Parameters:
*
* @param line Text message.
@@ -129,8 +135,11 @@ class ChatWindow : public Window,
/**
* Request focus for typing chat message.
+ *
+ * \returns true if the input was shown
+ * false otherwise
*/
- void requestChatFocus();
+ bool requestChatFocus();
/**
* Checks whether ChatWindow is Focused or not.
@@ -248,14 +257,15 @@ class ChatWindow : public Window,
typedef std::list<std::string> History;
typedef History::iterator HistoryIterator;
- History mHistory; /**< Command history. */
- HistoryIterator mCurHist; /**< History iterator. */
- Recorder *mRecorder; /**< Recording class */
- bool mReturnToggles; /**< Marks whether <Return> toggles the chat log
- or not */
+ History mHistory; /**< Command history */
+ HistoryIterator mCurHist; /**< History iterator */
+ Recorder *mRecorder; /**< Recording class */
+ bool mReturnToggles; /**< Marks whether <Return> toggles the chat
+ log or not */
#ifdef EATHENA_SUPPORT
- char mPartyPrefix; /**< Messages beginning with the prefix are sent to
- the party */
+ char mPartyPrefix; /**< Messages beginning with the prefix are
+ sent to the party */
+ Party *mParty;
#endif
};
diff --git a/src/gui/checkbox.cpp b/src/gui/checkbox.cpp
index 7fa4fa81..5695a23f 100644
--- a/src/gui/checkbox.cpp
+++ b/src/gui/checkbox.cpp
@@ -20,6 +20,7 @@
*/
#include "checkbox.h"
+#include "palette.h"
#include "../configuration.h"
#include "../graphics.h"
@@ -68,6 +69,18 @@ CheckBox::~CheckBox()
}
}
+void CheckBox::draw(gcn::Graphics* graphics)
+{
+ drawBox(graphics);
+
+ graphics->setFont(getFont());
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
+
+ const int h = getHeight() + getHeight() / 2;
+
+ graphics->drawText(getCaption(), h - 2, 0);
+}
+
void CheckBox::drawBox(gcn::Graphics* graphics)
{
Image *box;
diff --git a/src/gui/checkbox.h b/src/gui/checkbox.h
index 20adb43c..dd59493c 100644
--- a/src/gui/checkbox.h
+++ b/src/gui/checkbox.h
@@ -45,6 +45,11 @@ class CheckBox : public gcn::CheckBox
~CheckBox();
/**
+ * Draws the caption, then calls drawBox to draw the check box.
+ */
+ void draw(gcn::Graphics* graphics);
+
+ /**
* Draws the check box, not the caption.
*/
void drawBox(gcn::Graphics* graphics);
diff --git a/src/gui/color.cpp b/src/gui/color.cpp
deleted file mode 100644
index f9b89857..00000000
--- a/src/gui/color.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Configurable text colors
- * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
- *
- * This file is part of The Mana World.
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "color.h"
-
-#include "../configuration.h"
-
-#include "../utils/gettext.h"
-#include "../utils/stringutils.h"
-
-Color::Color()
-{
- addColor('C', 0x000000, _("Chat"));
- addColor('G', 0xff0000, _("GM"));
- addColor('H', 0xebc873, _("Highlight"));
- addColor('Y', 0x1fa052, _("Player"));
- addColor('W', 0x0000ff, _("Whisper"));
- addColor('I', 0xa08527, _("Is"));
- addColor('P', 0xff00d8, _("Party"));
- addColor('S', 0x8415e2, _("Server"));
- addColor('L', 0x919191, _("Logger"));
- addColor('<', 0xe50d0d, _("Hyperlink"));
- commit();
-}
-
-Color::~Color()
-{
- for (ColVector::iterator col = mColVector.begin(),
- colEnd = mColVector.end();
- col != colEnd;
- ++col)
- {
- config.setValue("Color" + col->text, toString(col->rgb));
- }
-}
-
-void Color::setColor(char c, int rgb)
-{
- for (ColVector::iterator col = mColVector.begin(),
- colEnd = mColVector.end();
- col != colEnd;
- ++col)
- {
- if (col->ch == c)
- {
- col->rgb = rgb;
- return;
- }
- }
-}
-
-int Color::getColor(char c, bool &valid) const
-{
- for (ColVector::const_iterator col = mColVector.begin(),
- colEnd = mColVector.end();
- col != colEnd;
- ++col)
- {
- if (col->ch == c)
- {
- valid = true;
- return col->rgb;
- }
- }
- valid = false;
- return 0x000000;
-}
-
-std::string Color::getElementAt(int i)
-{
- if (i < 0 || i >= getNumberOfElements())
- {
- return "";
- }
- return mColVector[i].text;
-}
-
-char Color::getColorCharAt(int i)
-{
- if (i < 0 || i >= getNumberOfElements())
- {
- return 'C';
- }
- return mColVector[i].ch;
-}
-
-void Color::addColor(char c, int rgb, const std::string &text)
-{
- int trueRgb = (int) config.getValue("Color" + text, rgb);
- mColVector.push_back(ColorElem(c, trueRgb, text));
-}
-
-int Color::getColorAt(int i)
-{
- if (i < 0 || i >= getNumberOfElements())
- {
- return 0;
- }
- return mColVector[i].rgb;
-}
-
-void Color::setColorAt(int i, int rgb)
-{
- if (i >= 0 && i < getNumberOfElements())
- {
- mColVector[i].rgb = rgb;
- }
-}
-
-void Color::commit()
-{
- for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end();
- i != iEnd;
- ++i)
- {
- i->committedRgb = i->rgb;
- }
-}
-
-void Color::rollback()
-{
- for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end();
- i != iEnd;
- ++i)
- {
- i->rgb = i->committedRgb;
- }
-}
diff --git a/src/gui/color.h b/src/gui/color.h
deleted file mode 100644
index 2816cedc..00000000
--- a/src/gui/color.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Configurable text colors
- * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
- *
- * This file is part of The Mana World.
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef COLOR_H
-#define COLOR_H
-
-#include <string>
-#include <vector>
-
-#include <guichan/listmodel.hpp>
-
-class Color : public gcn::ListModel
-{
- public:
- /**
- * Constructor
- */
- Color();
-
- /**
- * Destructor
- */
- ~Color();
-
- /**
- * Define the color replacement for a character
- *
- * @param c charater to be replaced
- * @param rgb color to replace character
- */
- void setColor(char c, int rgb);
-
- /**
- * Define the color replacement for a character
- *
- * @param c character to be replaced
- * @param r red component
- * @param g green component
- * @param b blue component
- */
- void setColor(char c, int r, int g, int b)
- {
- setColor(c, (r << 16) | (g << 8) | b);
- }
-
- /**
- * Return the color associated with a character, if exists
- *
- * @param c character requested
- * @param valid indicate whether character is known
- */
- int getColor(char c, bool &valid) const;
-
- /**
- * Return the number of colors known
- */
- int getNumberOfElements() { return mColVector.size(); }
-
- /**
- * Return the name of the ith color
- *
- * @param i index of color interested in
- */
- std::string getElementAt(int i);
-
- /**
- * Get the color for the element at index i in the current color
- * model
- */
- int getColorAt(int i);
-
- /**
- * Get the character used by the color for the element at index i in
- * the current color model
- */
- char getColorCharAt(int i);
-
- /**
- * Set the color for the element at index i
- */
- void setColorAt(int i, int rgb);
-
- /**
- * Commit the colors
- */
- void commit();
-
- /**
- * Rollback the colors
- */
- void rollback();
-
- private:
- struct ColorElem
- {
- ColorElem(char c, int rgb, const std::string &text) :
- ch(c), rgb(rgb), text(text) {}
- char ch;
- int rgb;
- int committedRgb;
- std::string text;
- };
- typedef std::vector<ColorElem> ColVector;
- ColVector mColVector;
-
- /**
- * Initialise color
- *
- * @param c character that needs initialising
- * @param rgb default color if not found in config
- * @param text identifier of color
- */
- void addColor(char c, int rgb, const std::string &text);
-};
-
-extern Color *textColor;
-
-#endif
diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp
index 5ad2e26c..a40593e3 100644
--- a/src/gui/confirm_dialog.cpp
+++ b/src/gui/confirm_dialog.cpp
@@ -23,6 +23,7 @@
#include "button.h"
#include "confirm_dialog.h"
+#include "gui.h"
#include "scrollarea.h"
#include "textbox.h"
@@ -49,14 +50,16 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
int numRows = mTextBox->getNumberOfRows();
int width = getFont()->getWidth(title);
int inWidth = yesButton->getWidth() + noButton->getWidth() + 5;
+ const int fontHeight = getFont()->getHeight();
if (numRows > 1)
{
- // 15 == height of each line of text (based on font heights)
+ // fontHeight == height of each line of text (based on font heights)
// 14 == row top + bottom graphic pixel heights
- setContentSize(mTextBox->getMinWidth() + 15, 15 + (numRows * 15) + noButton->getHeight());
+ setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) *
+ fontHeight) + noButton->getHeight());
mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5,
- 3 + (numRows * 14)));
+ 3 + (numRows * fontHeight)));
}
else
{
@@ -64,16 +67,17 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
width = getFont()->getWidth(msg);
if (width < inWidth)
width = inWidth;
- setContentSize(width + 15, 30 + noButton->getHeight());
+ setContentSize(width + fontHeight, (2 * fontHeight) +
+ noButton->getHeight());
mTextArea->setDimension(gcn::Rectangle(4, 5, width + 5, 17));
}
yesButton->setPosition(
(mTextBox->getMinWidth() - inWidth) / 2,
- (numRows * 14) + noButton->getHeight() - 8);
+ ((numRows - 1) * fontHeight) + noButton->getHeight() + 2);
noButton->setPosition(
yesButton->getX() + yesButton->getWidth() + 5,
- (numRows * 14) + noButton->getHeight() - 8);
+ ((numRows - 1) * fontHeight) + noButton->getHeight() + 2);
add(mTextArea);
add(yesButton);
@@ -81,7 +85,7 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
if (getParent())
{
- setLocationRelativeTo(getParent());
+ center();
getParent()->moveToTop(this);
}
setVisible(true);
@@ -104,7 +108,5 @@ void ConfirmDialog::action(const gcn::ActionEvent &event)
// Can we receive anything else anyway?
if (event.getId() == "yes" || event.getId() == "no")
- {
scheduleDelete();
- }
}
diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp
index fbf127de..5fb21ff2 100644
--- a/src/gui/connection.cpp
+++ b/src/gui/connection.cpp
@@ -19,10 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "connection.h"
+#include "label.h"
#include "progressbar.h"
#include "../main.h"
@@ -37,7 +36,7 @@ ConnectionDialog::ConnectionDialog(int previousState):
Button *cancelButton = new Button(_("Cancel"), "cancelButton", this);
mProgressBar = new ProgressBar(0.0, 200 - 10, 20, 128, 128, 128);
- gcn::Label *label = new gcn::Label(_("Connecting..."));
+ gcn::Label *label = new Label(_("Connecting..."));
cancelButton->setPosition(5, 100 - 5 - cancelButton->getHeight());
mProgressBar->setPosition(5, cancelButton->getY() - 25);
@@ -47,7 +46,7 @@ ConnectionDialog::ConnectionDialog(int previousState):
add(cancelButton);
add(mProgressBar);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
}
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp
index 2ed891db..a98c9af4 100644
--- a/src/gui/debugwindow.cpp
+++ b/src/gui/debugwindow.cpp
@@ -19,11 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_mouse.h>
-
-#include <guichan/widgets/label.hpp>
-
#include "debugwindow.h"
+#include "label.h"
#include "viewport.h"
#include "widgets/layout.h"
@@ -42,40 +39,38 @@ DebugWindow::DebugWindow():
setResizable(true);
setCloseButton(true);
- setDefaultSize(0, 0, 400, 60);
- loadWindowState();
+ setDefaultSize(400, 100, ImageRect::CENTER);
- mFPSLabel = new gcn::Label("0 FPS");
- mMusicFileLabel = new gcn::Label("Music: ");
- mMapLabel = new gcn::Label("Map: ");
- mMiniMapLabel = new gcn::Label("Mini-Map: ");
- mTileMouseLabel = new gcn::Label("Mouse: 0, 0");
- mParticleCountLabel = new gcn::Label("Particle count: 0");
+ mFPSLabel = new Label("0 FPS");
+ mMusicFileLabel = new Label("Music: ");
+ mMapLabel = new Label("Map: ");
+ mMiniMapLabel = new Label("Mini-Map: ");
+ mTileMouseLabel = new Label("Mouse: 0, 0");
+ mParticleCountLabel = new Label("Particle count: 0");
- place(0, 0, mFPSLabel);
+ place(0, 0, mFPSLabel, 3);
place(3, 0, mTileMouseLabel);
- place(0, 1, mMusicFileLabel, 2);
+ place(0, 1, mMusicFileLabel, 3);
place(3, 1, mParticleCountLabel);
- place(0, 2, mMapLabel, 2);
- place(0, 3, mMiniMapLabel, 2);
+ place(0, 2, mMapLabel, 4);
+ place(0, 3, mMiniMapLabel, 4);
- reflowLayout(375, 0);
+ loadWindowState();
}
void DebugWindow::logic()
{
+ if (!isVisible())
+ return;
+
// Get the current mouse position
- int mouseX, mouseY;
- SDL_GetMouseState(&mouseX, &mouseY);
- int mouseTileX = mouseX / 32 + viewport->getCameraX();
- int mouseTileY = mouseY / 32 + viewport->getCameraY();
+ int mouseTileX = (viewport->getMouseX() + viewport->getCameraX()) / 32;
+ int mouseTileY = (viewport->getMouseY() + viewport->getCameraY()) / 32;
mFPSLabel->setCaption(toString(fps) + " FPS");
- mFPSLabel->adjustSize();
- mTileMouseLabel->setCaption("Mouse: " +
- toString(mouseTileX) + ", " + toString(mouseTileY));
- mTileMouseLabel->adjustSize();
+ mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " +
+ toString(mouseTileY) + ")");
Map *currentMap = engine->getCurrentMap();
if (currentMap)
@@ -83,20 +78,16 @@ void DebugWindow::logic()
const std::string music =
"Music: " + currentMap->getProperty("music");
mMusicFileLabel->setCaption(music);
- mMusicFileLabel->adjustSize();
const std::string minimap =
"MiniMap: " + currentMap->getProperty("minimap");
mMiniMapLabel->setCaption(minimap);
- mMiniMapLabel->adjustSize();
const std::string map =
"Map: " + currentMap->getProperty("_filename");
mMapLabel->setCaption(map);
- mMapLabel->adjustSize();
}
mParticleCountLabel->setCaption("Particle count: " +
toString(Particle::particleCount));
- mParticleCountLabel->adjustSize();
}
diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h
index e089de27..8097132c 100644
--- a/src/gui/debugwindow.h
+++ b/src/gui/debugwindow.h
@@ -50,4 +50,6 @@ class DebugWindow : public Window
gcn::Label *mParticleCountLabel;
};
+extern DebugWindow *debugWindow;
+
#endif
diff --git a/src/gui/emotecontainer.cpp b/src/gui/emotecontainer.cpp
index e22b031b..ececd9aa 100644
--- a/src/gui/emotecontainer.cpp
+++ b/src/gui/emotecontainer.cpp
@@ -53,7 +53,7 @@ EmoteContainer::EmoteContainer():
// Setup emote sprites
for (int i = 0; i <= EmoteDB::getLast(); i++)
{
- mEmoteImg.push_back(player_node->getEmote(i));
+ mEmoteImg.push_back(EmoteDB::getAnimation(i));
}
mSelImg = resman->getImage("graphics/gui/selection.png");
@@ -78,13 +78,14 @@ EmoteContainer::~EmoteContainer()
void EmoteContainer::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
int columns = getWidth() / gridWidth;
// Have at least 1 column
if (columns < 1)
- {
columns = 1;
- }
for (int i = 0; i < mMaxEmote ; i++)
{
diff --git a/src/gui/emotecontainer.h b/src/gui/emotecontainer.h
index fefce793..88df29fc 100644
--- a/src/gui/emotecontainer.h
+++ b/src/gui/emotecontainer.h
@@ -121,7 +121,7 @@ class EmoteContainer : public gcn::Widget,
*/
void distributeValueChangedEvent(void);
- std::vector<AnimatedSprite*> mEmoteImg;
+ std::vector<const AnimatedSprite*> mEmoteImg;
Image *mSelImg;
int mSelectedEmoteIndex;
diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp
index a0739723..661f42a7 100644
--- a/src/gui/emoteshortcutcontainer.cpp
+++ b/src/gui/emoteshortcutcontainer.cpp
@@ -20,6 +20,7 @@
*/
#include "emoteshortcutcontainer.h"
+#include "palette.h"
#include "../animatedsprite.h"
#include "../configuration.h"
@@ -59,7 +60,7 @@ EmoteShortcutContainer::EmoteShortcutContainer():
// Setup emote sprites
for (int i = 0; i <= EmoteDB::getLast(); i++)
{
- mEmoteImg.push_back(player_node->getEmote(i));
+ mEmoteImg.push_back(EmoteDB::getAnimation(i));
}
mMaxItems = EmoteDB::getLast() < MAX_ITEMS ? EmoteDB::getLast() : MAX_ITEMS;
@@ -75,6 +76,15 @@ EmoteShortcutContainer::~EmoteShortcutContainer()
void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
+ if (config.getValue("guialpha", 0.8) != mAlpha)
+ {
+ mAlpha = config.getValue("guialpha", 0.8);
+ mBackgroundImg->setAlpha(mAlpha);
+ }
+
Graphics *g = static_cast<Graphics*>(graphics);
graphics->setFont(getFont());
@@ -89,12 +99,13 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
// Draw emote keyboard shortcut.
const char *key = SDL_GetKeyName(
(SDLKey) keyboard.getKeyValue(keyboard.KEY_EMOTE_1 + i));
- graphics->setColor(0x000000);
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
g->drawText(key, emoteX + 2, emoteY + 2, gcn::Graphics::LEFT);
if (emoteShortcut->getEmote(i))
{
- mEmoteImg[emoteShortcut->getEmote(i) - 1]->draw(g, emoteX + 2, emoteY + 10);
+ mEmoteImg[emoteShortcut->getEmote(i) - 1]->draw(g, emoteX + 2,
+ emoteY + 10);
}
}
@@ -102,7 +113,7 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
if (mEmoteMoved)
{
// Draw the emote image being dragged by the cursor.
- AnimatedSprite* sprite = mEmoteImg[mEmoteMoved - 1];
+ const AnimatedSprite* sprite = mEmoteImg[mEmoteMoved - 1];
if (sprite)
{
const int tPosX = mCursorPosX - (sprite->getWidth() / 2);
@@ -111,12 +122,6 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
sprite->draw(g, tPosX, tPosY);
}
}
-
- if (config.getValue("guialpha", 0.8) != mAlpha)
- {
- mAlpha = config.getValue("guialpha", 0.8);
- mBackgroundImg->setAlpha(mAlpha);
- }
}
void EmoteShortcutContainer::mouseDragged(gcn::MouseEvent &event)
@@ -129,9 +134,7 @@ void EmoteShortcutContainer::mouseDragged(gcn::MouseEvent &event)
const int emoteId = emoteShortcut->getEmote(index);
if (index == -1)
- {
return;
- }
if (emoteId)
{
@@ -152,19 +155,17 @@ void EmoteShortcutContainer::mousePressed(gcn::MouseEvent &event)
const int index = getIndexFromGrid(event.getX(), event.getY());
if (index == -1)
- {
- return;
- }
+ return;
// Stores the selected emote if there is one.
if (emoteShortcut->isEmoteSelected())
{
- emoteShortcut->setEmote(index);
- emoteShortcut->setEmoteSelected(0);
+ emoteShortcut->setEmote(index);
+ emoteShortcut->setEmoteSelected(0);
}
else if (emoteShortcut->getEmote(index))
{
- mEmoteClicked = true;
+ mEmoteClicked = true;
}
}
@@ -175,9 +176,7 @@ void EmoteShortcutContainer::mouseReleased(gcn::MouseEvent &event)
const int index = getIndexFromGrid(event.getX(), event.getY());
if (emoteShortcut->isEmoteSelected())
- {
emoteShortcut->setEmoteSelected(0);
- }
if (index == -1)
{
@@ -196,9 +195,7 @@ void EmoteShortcutContainer::mouseReleased(gcn::MouseEvent &event)
}
if (mEmoteClicked)
- {
mEmoteClicked = false;
- }
}
}
diff --git a/src/gui/emoteshortcutcontainer.h b/src/gui/emoteshortcutcontainer.h
index d32a9f79..2997cb09 100644
--- a/src/gui/emoteshortcutcontainer.h
+++ b/src/gui/emoteshortcutcontainer.h
@@ -68,7 +68,7 @@ class EmoteShortcutContainer : public ShortcutContainer
void mouseReleased(gcn::MouseEvent &event);
private:
- std::vector<AnimatedSprite*> mEmoteImg;
+ std::vector<const AnimatedSprite*> mEmoteImg;
bool mEmoteClicked;
int mEmoteMoved;
diff --git a/src/gui/emotewindow.cpp b/src/gui/emotewindow.cpp
index 48635720..d4b3cf2e 100644
--- a/src/gui/emotewindow.cpp
+++ b/src/gui/emotewindow.cpp
@@ -40,7 +40,7 @@ EmoteWindow::EmoteWindow():
setCloseButton(true);
setMinWidth(80);
setMinHeight(130);
- setDefaultSize(115, 25, 322, 200);
+ setDefaultSize(322, 200, ImageRect::CENTER);
mUseButton = new Button(_("Use"), "use", this);
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index a44ae3ec..7ac9051f 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -27,6 +27,7 @@
#include "button.h"
#include "equipmentwindow.h"
#include "itempopup.h"
+#include "palette.h"
#include "playerbox.h"
#include "viewport.h"
@@ -71,6 +72,7 @@ EquipmentWindow::EquipmentWindow():
mSelected(-1)
{
mItemPopup = new ItemPopup;
+ mItemPopup->setOpaque(false);
// Control that shows the Player
mPlayerBox = new PlayerBox;
@@ -79,7 +81,7 @@ EquipmentWindow::EquipmentWindow():
setWindowName("Equipment");
setCloseButton(true);
- setDefaultSize(5, 195, 180, 300);
+ setDefaultSize(180, 300, ImageRect::CENTER);
loadWindowState();
mUnequip = new Button(_("Unequip"), "unequip", this);
@@ -119,6 +121,9 @@ EquipmentWindow::~EquipmentWindow()
void EquipmentWindow::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
// Draw window graphics
Window::draw(graphics);
@@ -132,6 +137,22 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++)
#endif
{
+ if (i == mSelected)
+ {
+ const gcn::Color color = guiPalette->getColor(Palette::HIGHLIGHT);
+
+ // Set color to the highligh color
+ g->setColor(gcn::Color(color.r, color.g, color.b, getGuiAlpha()));
+ g->fillRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
+ BOX_WIDTH, BOX_HEIGHT));
+ }
+
+ // Set color black.
+ g->setColor(gcn::Color(0, 0, 0));
+ // Draw box border.
+ g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
+ BOX_WIDTH, BOX_HEIGHT));
+
#ifdef TMWSERV_SUPPORT
Item *item = mEquipment->getEquipment(i);
#else
@@ -147,7 +168,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
#ifdef EATHENA_SUPPORT
if (i == EQUIP_AMMO_SLOT)
{
- g->setColor(gcn::Color(0, 0, 0));
+ g->setColor(guiPalette->getColor(Palette::TEXT));
graphics->drawText(toString(item->getQuantity()),
mEquipBox[i].posX + (BOX_WIDTH / 2),
mEquipBox[i].posY - getFont()->getHeight(),
@@ -155,21 +176,6 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
}
#endif
}
-
- if (i == mSelected)
- {
- // Set color red.
- g->setColor(gcn::Color(255, 0, 0));
- }
- else
- {
- // Set color black.
- g->setColor(gcn::Color(0, 0, 0));
- }
-
- // Draw box border.
- g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
- BOX_WIDTH, BOX_HEIGHT));
}
}
@@ -280,8 +286,9 @@ void EquipmentWindow::mouseMoved(gcn::MouseEvent &event)
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
- mItemPopup->setItem(item->getInfo());
- mItemPopup->setOpaque(false);
+ if (item->getInfo().getName() != mItemPopup->getItemName())
+ mItemPopup->setItem(item->getInfo());
+ mItemPopup->updateColors();
mItemPopup->view(x + getX(), y + getY());
}
else
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 1ef0219a..87ce74fa 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -25,7 +25,9 @@
#include "focushandler.h"
#include "gui.h"
+#include "palette.h"
#include "sdlinput.h"
+#include "skin.h"
#include "truetypefont.h"
#include "viewport.h"
#include "window.h"
@@ -46,11 +48,6 @@ Gui *gui = 0;
Viewport *viewport = 0; /**< Viewport on the map. */
SDLInput *guiInput = 0;
-// Fonts used in showing hits
-gcn::Font *hitRedFont = 0;
-gcn::Font *hitBlueFont = 0;
-gcn::Font *hitYellowFont = 0;
-
// Bolded font
gcn::Font *boldFont = 0;
@@ -113,6 +110,7 @@ Gui::Gui(Graphics *graphics):
{
const int fontSize = (int)config.getValue("fontSize", 11);
mGuiFont = new TrueTypeFont(path, fontSize);
+ mInfoParticleFont = new TrueTypeFont(path, fontSize, 1);
}
catch (gcn::Exception e)
{
@@ -136,22 +134,6 @@ Gui::Gui(Graphics *graphics):
gcn::Widget::setGlobalFont(mGuiFont);
- // Load hits' colorful fonts
- try
- {
- hitRedFont = new gcn::ImageFont("graphics/gui/hits_red.png",
- "0123456789crit! ");
- hitBlueFont = new gcn::ImageFont("graphics/gui/hits_blue.png",
- "0123456789crit! ");
- hitYellowFont = new gcn::ImageFont("graphics/gui/hits_yellow.png",
- "0123456789misxp ");
- }
- catch (gcn::Exception e)
- {
- logger->error(std::string("Unable to load colored hits' fonts: ")
- + e.getMessage());
- }
-
// Initialize mouse cursor and listen for changes to the option
setUseCustomCursor(config.getValue("customcursor", 1) == 1);
mConfigListener = new GuiConfigListener(this);
@@ -169,16 +151,12 @@ Gui::~Gui()
config.removeListener("customcursor", mConfigListener);
delete mConfigListener;
- // Fonts used in showing hits
- delete hitRedFont;
- delete hitBlueFont;
- delete hitYellowFont;
-
if (mMouseCursors)
mMouseCursors->decRef();
delete mGuiFont;
delete boldFont;
+ delete mInfoParticleFont;
delete viewport;
delete getTop();
@@ -196,6 +174,8 @@ void Gui::logic()
else
mMouseCursorAlpha = std::max(0.0f, mMouseCursorAlpha - 0.005f);
+ guiPalette->advanceGradient();
+
gcn::Gui::logic();
}
@@ -262,3 +242,8 @@ void Gui::handleMouseMoved(const gcn::MouseInput &mouseInput)
gcn::Gui::handleMouseMoved(mouseInput);
mMouseInactivityTimer = 0;
}
+
+const int Gui::getFontHeight() const
+{
+ return mGuiFont->getHeight();
+}
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 5c0c24f7..2ce153db 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -77,6 +77,18 @@ class Gui : public gcn::Gui
{ return mGuiFont; }
/**
+ * Return game font height.
+ */
+ const int getFontHeight() const;
+
+ /**
+ * Return the Font used for "Info Particles", i.e. ones showing, what
+ * you picked up, etc.
+ */
+ gcn::Font* getInfoParticleFont() const
+ { return mInfoParticleFont; }
+
+ /**
* Sets whether a custom cursor should be rendered.
*/
void setUseCustomCursor(bool customCursor);
@@ -107,6 +119,7 @@ class Gui : public gcn::Gui
private:
GuiConfigListener *mConfigListener;
gcn::Font *mGuiFont; /**< The global GUI font */
+ gcn::Font *mInfoParticleFont; /**< Font for Info Particles*/
bool mCustomCursor; /**< Show custom cursor */
ImageSet *mMouseCursors; /**< Mouse cursor images */
float mMouseCursorAlpha;
@@ -118,13 +131,6 @@ extern Gui *gui; /**< The GUI system */
extern SDLInput *guiInput; /**< GUI input */
/**
- * Fonts used in showing hits
- */
-extern gcn::Font *hitRedFont;
-extern gcn::Font *hitBlueFont;
-extern gcn::Font *hitYellowFont;
-
-/**
* Bolded text font
*/
extern gcn::Font *boldFont;
diff --git a/src/gui/help.cpp b/src/gui/help.cpp
index 30c6a9c4..03dfd08d 100644
--- a/src/gui/help.cpp
+++ b/src/gui/help.cpp
@@ -39,16 +39,17 @@ HelpWindow::HelpWindow():
setWindowName("Help");
setResizable(true);
+ setDefaultSize(500, 400, ImageRect::CENTER);
+
mBrowserBox = new BrowserBox;
mBrowserBox->setOpaque(false);
mScrollArea = new ScrollArea(mBrowserBox);
Button *okButton = new Button(_("Close"), "close", this);
- mScrollArea->setDimension(gcn::Rectangle(
- 5, 5, 445, 335 - okButton->getHeight()));
- okButton->setPosition(
- 450 - okButton->getWidth(),
- 345 - okButton->getHeight());
+ mScrollArea->setDimension(gcn::Rectangle(5, 5, 445,
+ 335 - okButton->getHeight()));
+ okButton->setPosition(450 - okButton->getWidth(),
+ 345 - okButton->getHeight());
mBrowserBox->setLinkHandler(this);
@@ -58,7 +59,7 @@ HelpWindow::HelpWindow():
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- setLocationRelativeTo(getParent());
+ loadWindowState();
}
void HelpWindow::action(const gcn::ActionEvent &event)
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index d18490a4..0b554469 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -24,12 +24,11 @@
#include <guichan/font.hpp>
#include <guichan/mouseinput.hpp>
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "inventorywindow.h"
#include "item_amount.h"
#include "itemcontainer.h"
+#include "label.h"
#include "progressbar.h"
#include "scrollarea.h"
#include "sdlinput.h"
@@ -40,7 +39,6 @@
#include "../inventory.h"
#include "../item.h"
#include "../localplayer.h"
-#include "../log.h"
#include "../units.h"
#include "../resources/iteminfo.h"
@@ -63,7 +61,7 @@ InventoryWindow::InventoryWindow(int invSize):
setMinWidth(375);
setMinHeight(283);
// If you adjust these defaults, don't forget to adjust the trade window's.
- setDefaultSize(115, 30, 375, 283);
+ setDefaultSize(375, 300, ImageRect::CENTER);
addKeyListener(this);
std::string longestUseString = getFont()->getWidth(_("Equip")) >
@@ -96,8 +94,8 @@ InventoryWindow::InventoryWindow(int invSize):
mMaxWeight = -1;
mUsedSlots = toString(player_node->getInventory()->getNumberOfSlotsUsed());
- mSlotsLabel = new gcn::Label(_("Slots: "));
- mWeightLabel = new gcn::Label(_("Weight: "));
+ mSlotsLabel = new Label(_("Slots: "));
+ mWeightLabel = new Label(_("Weight: "));
mSlotsBar = new ProgressBar(1.0f, 100, 20, 225, 200, 25);
mWeightBar = new ProgressBar(1.0f, 100, 20, 0, 0, 255);
@@ -129,6 +127,9 @@ InventoryWindow::~InventoryWindow()
void InventoryWindow::logic()
{
+ if (!isVisible())
+ return;
+
Window::logic();
// It would be nicer if this update could be event based, needs some
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
index 6a51c66d..95a47bdb 100644
--- a/src/gui/inventorywindow.h
+++ b/src/gui/inventorywindow.h
@@ -22,13 +22,13 @@
#ifndef INVENTORYWINDOW_H
#define INVENTORYWINDOW_H
-#include <guichan/actionlistener.hpp>
-#include <guichan/selectionlistener.hpp>
-#include <guichan/keylistener.hpp>
-
#include "window.h"
-#include "../localplayer.h"
+#include "../inventory.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/selectionlistener.hpp>
class Item;
class ItemContainer;
diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp
index 3bd388f4..0f6aa593 100644
--- a/src/gui/item_amount.cpp
+++ b/src/gui/item_amount.cpp
@@ -20,9 +20,12 @@
*/
#include "button.h"
-#include "inttextfield.h"
#include "item_amount.h"
+#include "label.h"
#include "slider.h"
+#ifdef EATHENA_SUPPORT
+#include "storagewindow.h"
+#endif
#include "trade.h"
#include "widgets/layout.h"
@@ -31,46 +34,54 @@
#include "../localplayer.h"
#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item,
int maxRange):
Window("", true, parent),
- mItem(item)
+ mItem(item),
+ mMax(maxRange),
+ mUsage(usage)
{
- if (!maxRange)
- {
- maxRange = mItem->getQuantity();
- }
+ if (!mMax)
+ mMax = mItem->getQuantity();
+
+ setCloseButton(true);
// Integer field
- mItemAmountTextField = new IntTextField(1);
- mItemAmountTextField->setRange(1, maxRange);
- mItemAmountTextField->setWidth(30);
- mItemAmountTextField->setActionEventId("Dummy");
- mItemAmountTextField->addActionListener(this);
+
+ mItemAmountLabel = new Label(strprintf("%d / %d", 1, mMax));
+ mItemAmountLabel->setAlignment(gcn::Graphics::CENTER);
// Slider
- mItemAmountSlide = new Slider(1.0, maxRange);
+ mItemAmountSlide = new Slider(1.0, mMax);
mItemAmountSlide->setHeight(10);
mItemAmountSlide->setActionEventId("Slide");
mItemAmountSlide->addActionListener(this);
// Buttons
Button *minusButton = new Button("-", "Minus", this);
- minusButton->setSize(20, 20);
Button *plusButton = new Button("+", "Plus", this);
- plusButton->setSize(20, 20);
- Button *okButton = new Button(_("Ok"), "Drop", this);
+ Button *okButton = new Button(_("Ok"), "Ok", this);
Button *cancelButton = new Button(_("Cancel"), "Cancel", this);
+ Button *addAllButton = new Button(_("All"), "All", this);
+
+ minusButton->adjustSize();
+ minusButton->setWidth(plusButton->getWidth());
// Set positions
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
place(0, 0, minusButton);
- place(1, 0, mItemAmountTextField).setPadding(2);
- place(2, 0, plusButton);
- place(0, 1, mItemAmountSlide, 6);
- place(4, 2, okButton);
- place(5, 2, cancelButton);
- reflowLayout(250, 0);
+ place(1, 0, mItemAmountSlide, 3);
+ place(4, 0, plusButton);
+ place(5, 0, mItemAmountLabel, 2);
+ place(7, 0, addAllButton);
+ place = getPlacer(0, 1);
+ place(4, 0, cancelButton);
+ place(5, 0, okButton);
+ reflowLayout(225, 0);
resetAmount();
@@ -78,15 +89,18 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item,
{
case AMOUNT_TRADE_ADD:
setCaption(_("Select amount of items to trade."));
- okButton->setActionEventId("AddTrade");
break;
case AMOUNT_ITEM_DROP:
setCaption(_("Select amount of items to drop."));
- okButton->setActionEventId("Drop");
+ break;
+ case AMOUNT_STORE_ADD:
+ setCaption(_("Select amount of items to store."));
+ break;
+ case AMOUNT_STORE_REMOVE:
+ setCaption(_("Select amount of items to retrieve."));
break;
case AMOUNT_ITEM_SPLIT:
setCaption(_("Select amount of items to split."));
- okButton->setActionEventId("Split");
break;
default:
break;
@@ -98,22 +112,22 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item,
void ItemAmountWindow::resetAmount()
{
- mItemAmountTextField->setValue(1);
+ mItemAmountLabel->setCaption(strprintf("%d / %d", 1, mMax));
}
void ItemAmountWindow::action(const gcn::ActionEvent &event)
{
- int amount = mItemAmountTextField->getValue();
+ int amount = mItemAmountSlide->getValue();
if (event.getId() == "Cancel")
{
- scheduleDelete();
+ close();
}
- else if (event.getId() == "Plus")
+ else if (event.getId() == "Plus" && amount < mMax)
{
amount++;
}
- else if (event.getId() == "Minus")
+ else if (event.getId() == "Minus" && amount > 1)
{
amount--;
}
@@ -121,23 +135,45 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event)
{
amount = static_cast<int>(mItemAmountSlide->getValue());
}
- else if (event.getId() == "Drop")
- {
- player_node->dropItem(mItem, mItemAmountTextField->getValue());
- scheduleDelete();
- }
- else if (event.getId() == "AddTrade")
+ else if (event.getId() == "Ok" || event.getId() == "All")
{
- tradeWindow->tradeItem(mItem, mItemAmountTextField->getValue());
- scheduleDelete();
- }
+ if (event.getId() == "All")
+ amount = mMax;
+
+ switch (mUsage)
+ {
+ case AMOUNT_TRADE_ADD:
+ tradeWindow->tradeItem(mItem, amount);
+ break;
+ case AMOUNT_ITEM_DROP:
+ player_node->dropItem(mItem, amount);
+ break;
#ifdef TMWSERV_SUPPORT
- else if (event.getId() == "Split")
- {
- player_node->splitItem(mItem, mItemAmountTextField->getValue());
+ case AMOUNT_ITEM_SPLIT:
+ player_node->splitItem(mItem, amount);
+ break;
+#else
+ case AMOUNT_STORE_ADD:
+ storageWindow->addStore(mItem, amount);
+ break;
+ case AMOUNT_STORE_REMOVE:
+ storageWindow->removeStore(mItem, amount);
+ break;
+#endif
+ default:
+ return;
+ break;
+ }
+
scheduleDelete();
+ return;
}
-#endif
- mItemAmountTextField->setValue(amount);
+
+ mItemAmountLabel->setCaption(strprintf("%d / %d", amount, mMax));
mItemAmountSlide->setValue(amount);
}
+
+void ItemAmountWindow::close()
+{
+ scheduleDelete();
+}
diff --git a/src/gui/item_amount.h b/src/gui/item_amount.h
index 4fdb8dc6..344f8c28 100644
--- a/src/gui/item_amount.h
+++ b/src/gui/item_amount.h
@@ -31,7 +31,9 @@ class Item;
#define AMOUNT_TRADE_ADD 1
#define AMOUNT_ITEM_DROP 2
-#define AMOUNT_ITEM_SPLIT 3
+#define AMOUNT_STORE_ADD 3
+#define AMOUNT_STORE_REMOVE 4
+#define AMOUNT_ITEM_SPLIT 5
/**
* Window used for selecting the amount of items to drop, trade or split.
@@ -56,10 +58,17 @@ class ItemAmountWindow : public Window, public gcn::ActionListener
*/
void resetAmount();
+ /**
+ * Schedules the Item Amount window for deletion.
+ */
+ void close();
+
private:
- IntTextField *mItemAmountTextField; /**< Item amount caption. */
+ gcn::Label *mItemAmountLabel; /**< Item amount caption. */
Item *mItem;
+ int mMax, mUsage;
+
/**
* Item Amount buttons.
*/
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index bdae9ada..38a41e0e 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -19,15 +19,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "itemcontainer.h"
-#include "chat.h"
-
-#include "itempopup.h"
#include <guichan/mouseinput.hpp>
#include <guichan/selectionlistener.hpp>
+#include "chat.h"
+#include "itemcontainer.h"
+#include "itempopup.h"
+#include "palette.h"
#include "sdlinput.h"
+#include "viewport.h"
#include "../graphics.h"
#include "../inventory.h"
@@ -306,12 +307,10 @@ void ItemContainer::mouseMoved(gcn::MouseEvent &event)
if (item)
{
- int mouseX, mouseY;
- SDL_GetMouseState(&mouseX, &mouseY);
-
- mItemPopup->setItem(item->getInfo());
- mItemPopup->setOpaque(false);
- mItemPopup->view(mouseX, mouseY);
+ if (item->getInfo().getName() != mItemPopup->getItemName())
+ mItemPopup->setItem(item->getInfo());
+ mItemPopup->updateColors();
+ mItemPopup->view(viewport->getMouseX(), viewport->getMouseY());
}
else
{
diff --git a/src/gui/itemlinkhandler.cpp b/src/gui/itemlinkhandler.cpp
index 4060b303..29fa310d 100644
--- a/src/gui/itemlinkhandler.cpp
+++ b/src/gui/itemlinkhandler.cpp
@@ -22,10 +22,9 @@
#include <sstream>
#include <string>
-#include <SDL_mouse.h>
-
#include "itemlinkhandler.h"
#include "itempopup.h"
+#include "viewport.h"
#include "../resources/iteminfo.h"
#include "../resources/itemdb.h"
@@ -33,6 +32,7 @@
ItemLinkHandler::ItemLinkHandler()
{
mItemPopup = new ItemPopup;
+ mItemPopup->setOpaque(false);
}
ItemLinkHandler::~ItemLinkHandler()
@@ -49,15 +49,18 @@ void ItemLinkHandler::handleLink(const std::string &link)
if (id > 0)
{
const ItemInfo &iteminfo = ItemDB::get(id);
- int mouseX, mouseY;
-
- SDL_GetMouseState(&mouseX, &mouseY);
- mItemPopup->setItem(iteminfo);
+ if (iteminfo.getName() != mItemPopup->getItemName())
+ mItemPopup->setItem(iteminfo);
if (mItemPopup->isVisible())
+ {
mItemPopup->setVisible(false);
+ }
else
- mItemPopup->view(mouseX, mouseY);
+ {
+ mItemPopup->updateColors();
+ mItemPopup->view(viewport->getMouseX(), viewport->getMouseY());
+ }
}
}
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index 25e6e78e..1b0a2bb2 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -26,11 +26,11 @@
#include "gui.h"
#include "itempopup.h"
+#include "palette.h"
#include "scrollarea.h"
#include "textbox.h"
-#include "windowcontainer.h"
-#include "widgets/layout.h"
+#include "../graphics.h"
#include "../units.h"
@@ -40,14 +40,12 @@
#include "../utils/stringutils.h"
ItemPopup::ItemPopup():
- Window()
+ Popup()
{
- setResizable(false);
- setShowTitle(false);
- setTitleBarHeight(0);
+ mItemType = "";
// Item Name
- mItemName = new gcn::Label("Label");
+ mItemName = new gcn::Label("");
mItemName->setFont(boldFont);
mItemName->setPosition(2, 2);
@@ -88,8 +86,6 @@ ItemPopup::ItemPopup():
add(mItemDescScroll);
add(mItemEffectScroll);
add(mItemWeightScroll);
-
- setLocationRelativeTo(getParent());
}
ItemPopup::~ItemPopup()
@@ -105,15 +101,18 @@ ItemPopup::~ItemPopup()
void ItemPopup::setItem(const ItemInfo &item)
{
+ if (item.getName() == mItemName->getCaption())
+ return;
+
mItemName->setCaption(item.getName());
-#ifdef EATHENA_SUPPORT
- mItemName->setForegroundColor(getColor(item.getType()));
-#endif
mItemName->setWidth(boldFont->getWidth(item.getName()));
mItemDesc->setTextWrapped(item.getDescription(), 196);
mItemEffect->setTextWrapped(item.getEffect(), 196);
mItemWeight->setTextWrapped(_("Weight: ") +
Units::formatWeight(item.getWeight()), 196);
+#ifdef EATHENA_SUPPORT
+ mItemType = item.getType();
+#endif
int minWidth = mItemName->getWidth();
@@ -166,40 +165,53 @@ void ItemPopup::setItem(const ItemInfo &item)
(2 * getFont()->getHeight()));
}
+void ItemPopup::updateColors()
+{
+#ifdef EATHENA_SUPPORT
+ mItemName->setForegroundColor(getColor(mItemType));
+#endif
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
+}
+
gcn::Color ItemPopup::getColor(const std::string& type)
{
gcn::Color color;
if (type.compare("generic") == 0)
- color = 0x21a5b1;
+ color = guiPalette->getColor(Palette::GENERIC);
else if (type.compare("equip-head") == 0)
- color = 0x527fa4;
+ color = guiPalette->getColor(Palette::HEAD);
else if (type.compare("usable") == 0)
- color = 0x268d24;
+ color = guiPalette->getColor(Palette::USABLE);
else if (type.compare("equip-torso") == 0)
- color = 0xd12aa4;
+ color = guiPalette->getColor(Palette::TORSO);
else if (type.compare("equip-1hand") == 0)
- color = 0xf42a2a;
+ color = guiPalette->getColor(Palette::ONEHAND);
else if (type.compare("equip-legs") == 0)
- color = 0x699900;
+ color = guiPalette->getColor(Palette::LEGS);
else if (type.compare("equip-feet") == 0)
- color = 0xaa1d48;
+ color = guiPalette->getColor(Palette::FEET);
else if (type.compare("equip-2hand") == 0)
- color = 0xf46d0e;
+ color = guiPalette->getColor(Palette::TWOHAND);
else if (type.compare("equip-shield") == 0)
- color = 0x9c2424;
+ color = guiPalette->getColor(Palette::SHIELD);
else if (type.compare("equip-ring") == 0)
- color = 0x0000ff;
+ color = guiPalette->getColor(Palette::RING);
else if (type.compare("equip-arms") == 0)
- color = 0x9c24e8;
+ color = guiPalette->getColor(Palette::ARMS);
else if (type.compare("equip-ammo") == 0)
- color = 0x8b6311;
+ color = guiPalette->getColor(Palette::AMMO);
else
- color = 0x000000;
+ color = guiPalette->getColor(Palette::UNKNOWN_ITEM);
return color;
}
+std::string ItemPopup::getItemName()
+{
+ return mItemName->getCaption();
+}
+
unsigned int ItemPopup::getNumRows()
{
return mItemDesc->getNumberOfRows() + mItemEffect->getNumberOfRows() +
@@ -208,8 +220,8 @@ unsigned int ItemPopup::getNumRows()
void ItemPopup::view(int x, int y)
{
- if (windowContainer->getWidth() < (x + getWidth() + 5))
- x = windowContainer->getWidth() - getWidth();
+ if (graphics->getWidth() < (x + getWidth() + 5))
+ x = graphics->getWidth() - getWidth();
if ((y - getHeight() - 10) < 0)
y = 0;
else
diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h
index c820e3a0..03e79886 100644
--- a/src/gui/itempopup.h
+++ b/src/gui/itempopup.h
@@ -23,20 +23,48 @@
#ifndef ITEMPOPUP_H
#define ITEMPOPUP_H
-#include "window.h"
+#include "popup.h"
class ItemInfo;
class ScrollArea;
class TextBox;
-class ItemPopup : public Window
+class ItemPopup : public Popup
{
public:
+ /**
+ * Constructor. Initializes the item popup.
+ */
ItemPopup();
+
+ /**
+ * Destructor. Cleans up the item popup on deletion.
+ */
~ItemPopup();
+ /**
+ * Sets the info to be displayed given a particular item.
+ */
void setItem(const ItemInfo &item);
+
+ /**
+ * Gets the number of rows that the item popup currently has.
+ */
unsigned int getNumRows();
+
+ /**
+ * Gets the name of the currently stored item in this popup.
+ */
+ std::string getItemName();
+
+ /**
+ * Updates the colors used within the item popup.
+ */
+ void updateColors();
+
+ /**
+ * Sets the location to display the item popup.
+ */
void view(int x, int y);
private:
@@ -44,6 +72,7 @@ class ItemPopup : public Window
TextBox *mItemDesc;
TextBox *mItemEffect;
TextBox *mItemWeight;
+ std::string mItemType;
ScrollArea *mItemDescScroll;
ScrollArea *mItemEffectScroll;
ScrollArea *mItemWeightScroll;
diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp
index 8864cbd9..45a5ffa0 100644
--- a/src/gui/itemshortcutcontainer.cpp
+++ b/src/gui/itemshortcutcontainer.cpp
@@ -18,10 +18,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <SDL_mouse.h>
+#include "inventorywindow.h"
#include "itemshortcutcontainer.h"
#include "itempopup.h"
+#include "palette.h"
#include "viewport.h"
#include "../configuration.h"
@@ -46,6 +47,7 @@ ItemShortcutContainer::ItemShortcutContainer():
addWidgetListener(this);
mItemPopup = new ItemPopup;
+ mItemPopup->setOpaque(false);
ResourceManager *resman = ResourceManager::getInstance();
@@ -64,24 +66,19 @@ ItemShortcutContainer::~ItemShortcutContainer()
delete mItemPopup;
}
-void ItemShortcutContainer::logic()
+void ItemShortcutContainer::draw(gcn::Graphics *graphics)
{
- gcn::Widget::logic();
-
- int i = itemShortcut->getItemCount();
+ if (!isVisible())
+ return;
- if (i != mMaxItems)
+ if (config.getValue("guialpha", 0.8) != mAlpha)
{
- mMaxItems = i;
- setWidth(getWidth());
+ mAlpha = config.getValue("guialpha", 0.8);
+ mBackgroundImg->setAlpha(mAlpha);
}
-}
-void ItemShortcutContainer::draw(gcn::Graphics *graphics)
-{
Graphics *g = static_cast<Graphics*>(graphics);
- graphics->setColor(gcn::Color(0, 0, 0));
graphics->setFont(getFont());
for (int i = 0; i < mMaxItems; i++)
@@ -94,7 +91,7 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics)
// Draw item keyboard shortcut.
const char *key = SDL_GetKeyName(
(SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_1 + i));
- graphics->setColor(0x000000);
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT);
if (itemShortcut->getItem(i) < 0)
@@ -102,6 +99,7 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics)
Item *item =
player_node->getInventory()->findItem(itemShortcut->getItem(i));
+
if (item)
{
// Draw item icon.
@@ -115,14 +113,12 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics)
#endif
toString(item->getQuantity());
g->drawImage(image, itemX, itemY);
- g->drawText(
- label,
- itemX + mBoxWidth / 2,
- itemY + mBoxHeight - 14,
- gcn::Graphics::CENTER);
+ g->drawText(label, itemX + mBoxWidth / 2,
+ itemY + mBoxHeight - 14, gcn::Graphics::CENTER);
}
}
}
+
if (mItemMoved)
{
// Draw the item image being dragged by the cursor.
@@ -133,18 +129,11 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics)
const int tPosY = mCursorPosY - (image->getHeight() / 2);
g->drawImage(image, tPosX, tPosY);
- g->drawText(
- toString(mItemMoved->getQuantity()),
- tPosX + mBoxWidth / 2,
- tPosY + mBoxHeight - 14,
- gcn::Graphics::CENTER);
+ g->drawText(toString(mItemMoved->getQuantity()),
+ tPosX + mBoxWidth / 2, tPosY + mBoxHeight - 14,
+ gcn::Graphics::CENTER);
}
}
-
- if (config.getValue("guialpha", 0.8) != mAlpha)
- {
- mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8));
- }
}
void ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event)
@@ -156,10 +145,7 @@ void ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event)
const int index = getIndexFromGrid(event.getX(), event.getY());
const int itemId = itemShortcut->getItem(index);
- if (index == -1)
- return;
-
- if (itemId < 0)
+ if (index == -1 || itemId < 0)
return;
Item *item = player_node->getInventory()->findItem(itemId);
@@ -170,7 +156,8 @@ void ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event)
itemShortcut->removeItem(index);
}
}
- if (mItemMoved) {
+ if (mItemMoved)
+ {
mCursorPosX = event.getX();
mCursorPosY = event.getY();
}
@@ -180,14 +167,14 @@ void ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event)
void ItemShortcutContainer::mousePressed(gcn::MouseEvent &event)
{
const int index = getIndexFromGrid(event.getX(), event.getY());
+
if (index == -1)
return;
if (event.getButton() == gcn::MouseEvent::LEFT)
{
-
// Stores the selected item if theirs one.
- if (itemShortcut->isItemSelected())
+ if (itemShortcut->isItemSelected() && inventoryWindow->isVisible())
{
itemShortcut->setItem(index);
itemShortcut->setItemSelected(-1);
@@ -203,12 +190,9 @@ void ItemShortcutContainer::mousePressed(gcn::MouseEvent &event)
if (!item)
return;
- /* Convert relative to the window coordinates to absolute screen
- * coordinates.
- */
- int mx, my;
- SDL_GetMouseState(&mx, &my);
- viewport->showPopup(mx, my, item);
+ // Convert relative to the window coordinates to absolute screen
+ // coordinates.
+ viewport->showPopup(viewport->getMouseX(), viewport->getMouseY(), item);
}
}
@@ -234,6 +218,7 @@ void ItemShortcutContainer::mouseReleased(gcn::MouseEvent &event)
{
itemShortcut->useItem(index);
}
+
if (mItemClicked)
mItemClicked = false;
}
@@ -245,22 +230,17 @@ void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event)
const int index = getIndexFromGrid(event.getX(), event.getY());
const int itemId = itemShortcut->getItem(index);
- if (index == -1)
- return;
-
- if (itemId < 0)
+ if (index == -1 || itemId < 0)
return;
Item *item = player_node->getInventory()->findItem(itemId);
- if (item)
+ if (item && inventoryWindow->isVisible())
{
- int mouseX, mouseY;
- SDL_GetMouseState(&mouseX, &mouseY);
-
- mItemPopup->setItem(item->getInfo());
- mItemPopup->setOpaque(false);
- mItemPopup->view(mouseX, mouseY);
+ if (item->getInfo().getName() != mItemPopup->getItemName())
+ mItemPopup->setItem(item->getInfo());
+ mItemPopup->updateColors();
+ mItemPopup->view(viewport->getMouseX(), viewport->getMouseY());
}
else
{
diff --git a/src/gui/itemshortcutcontainer.h b/src/gui/itemshortcutcontainer.h
index 22d94ec2..9d188bf0 100644
--- a/src/gui/itemshortcutcontainer.h
+++ b/src/gui/itemshortcutcontainer.h
@@ -49,11 +49,6 @@ class ItemShortcutContainer : public ShortcutContainer
virtual ~ItemShortcutContainer();
/**
- * Handles the logic of the ItemContainer
- */
- void logic();
-
- /**
* Draws the items.
*/
void draw(gcn::Graphics *graphics);
diff --git a/src/gui/label.cpp b/src/gui/label.cpp
new file mode 100644
index 00000000..e8d72ace
--- /dev/null
+++ b/src/gui/label.cpp
@@ -0,0 +1,40 @@
+/*
+ * Aethyra
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ * Copyright (c) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra based on original code
+ * from GUIChan.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "label.h"
+#include "palette.h"
+
+Label::Label() :
+ gcn::Label()
+{
+}
+
+Label::Label(const std::string& caption) :
+ gcn::Label(caption)
+{
+}
+
+void Label::draw(gcn::Graphics* graphics)
+{
+ setForegroundColor(guiPalette->getColor(Palette::TEXT));
+ gcn::Label::draw(static_cast<gcn::Graphics*>(graphics));
+}
diff --git a/src/gui/label.h b/src/gui/label.h
new file mode 100644
index 00000000..961286e0
--- /dev/null
+++ b/src/gui/label.h
@@ -0,0 +1,55 @@
+/*
+ * Aethyra
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ * Copyright (c) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra based on original code
+ * from GUIChan.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef LABEL_H
+#define LABEL_H
+
+#include <guichan/widgets/label.hpp>
+
+/**
+ * Label widget. Same as the Guichan label but modified to use the palette
+ * system.
+ *
+ * \ingroup GUI
+ */
+class Label : public gcn::Label
+{
+ public:
+ /**
+ * Constructor.
+ */
+ Label();
+
+ /**
+ * Constructor. This version of the constructor sets the label with an
+ * inintialization string.
+ */
+ Label(const std::string& caption);
+
+ /**
+ * Draws the label.
+ */
+ void draw(gcn::Graphics* graphics);
+};
+
+#endif
diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp
index 74d0b9ad..7ba84ee7 100644
--- a/src/gui/listbox.cpp
+++ b/src/gui/listbox.cpp
@@ -21,10 +21,11 @@
#include <guichan/font.hpp>
#include <guichan/graphics.hpp>
+#include <guichan/key.hpp>
#include <guichan/listmodel.hpp>
-#include "color.h"
#include "listbox.h"
+#include "palette.h"
#include "../configuration.h"
@@ -37,30 +38,25 @@ ListBox::ListBox(gcn::ListModel *listModel):
void ListBox::draw(gcn::Graphics *graphics)
{
- if (!mListModel)
+ if (!mListModel || !isVisible())
return;
if (config.getValue("guialpha", 0.8) != mAlpha)
mAlpha = config.getValue("guialpha", 0.8);
- bool valid;
- const int red = (textColor->getColor('H', valid) >> 16) & 0xFF;
- const int green = (textColor->getColor('H', valid) >> 8) & 0xFF;
- const int blue = textColor->getColor('H', valid) & 0xFF;
- const int alpha = (int)(mAlpha * 255.0f);
-
- graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT,
+ (int)(mAlpha * 255.0f)));
graphics->setFont(getFont());
const int fontHeight = getFont()->getHeight();
- // Draw rectangle below the selected list element
+ // Draw filled rectangle around the selected list element
if (mSelected >= 0)
graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected,
getWidth(), fontHeight));
// Draw the list elements
- graphics->setColor(gcn::Color(0, 0, 0, 255));
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
for (int i = 0, y = 0; i < mListModel->getNumberOfElements();
++i, y += fontHeight)
{
@@ -68,6 +64,91 @@ void ListBox::draw(gcn::Graphics *graphics)
}
}
+void ListBox::setSelected(int selected)
+{
+ if (!mListModel)
+ {
+ mSelected = -1;
+ }
+ else
+ {
+ if (selected < 0 && !mWrappingEnabled)
+ {
+ mSelected = -1;
+ }
+ else if (selected >= mListModel->getNumberOfElements() &&
+ mWrappingEnabled)
+ {
+ mSelected = 0;
+ }
+ else if ((selected >= mListModel->getNumberOfElements() &&
+ !mWrappingEnabled) || (selected < 0 && mWrappingEnabled))
+ {
+ mSelected = mListModel->getNumberOfElements() - 1;
+ }
+ else
+ {
+ mSelected = selected;
+ }
+ }
+ gcn::ListBox::setSelected(mSelected);
+}
+
+// -- KeyListener notifications
+void ListBox::keyPressed(gcn::KeyEvent& keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == gcn::Key::ENTER || key.getValue() == gcn::Key::SPACE)
+ {
+ distributeActionEvent();
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::UP)
+ {
+ setSelected(mSelected - 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::DOWN)
+ {
+ setSelected(mSelected + 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::HOME)
+ {
+ setSelected(0);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::END)
+ {
+ setSelected(getListModel()->getNumberOfElements() - 1);
+ keyEvent.consume();
+ }
+}
+
+void ListBox::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
+{
+ if (isFocused())
+ {
+ if (getSelected() > 0 || (getSelected() == 0 && mWrappingEnabled))
+ {
+ setSelected(getSelected() - 1);
+ }
+
+ mouseEvent.consume();
+ }
+}
+
+void ListBox::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent)
+{
+ if (isFocused())
+ {
+ setSelected(getSelected() + 1);
+
+ mouseEvent.consume();
+ }
+}
+
void ListBox::mouseDragged(gcn::MouseEvent &event)
{
// Pretend mouse is pressed continuously while dragged. Causes list
diff --git a/src/gui/listbox.h b/src/gui/listbox.h
index 12fcb955..cfb58f15 100644
--- a/src/gui/listbox.h
+++ b/src/gui/listbox.h
@@ -46,8 +46,27 @@ class ListBox : public gcn::ListBox
*/
void draw(gcn::Graphics *graphics);
+ // Inherited from KeyListener
+
+ void keyPressed(gcn::KeyEvent& keyEvent);
+
+ // Inherited from MouseListener
+
+ void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
+
+ void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
+
void mouseDragged(gcn::MouseEvent &event);
+ /**
+ * Sets the selected item. The selected item is represented by
+ * an index from the list model.
+ *
+ * @param selected the selected item as an index from the list model.
+ * @see getSelected
+ */
+ void setSelected(int selected);
+
private:
static float mAlpha;
};
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index e68a8da1..281a25a2 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -19,10 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "checkbox.h"
+#include "label.h"
#include "listbox.h"
#include "login.h"
#include "ok_dialog.h"
@@ -48,12 +47,12 @@ static const int FIELD_WIDTH = LOGIN_DIALOG_WIDTH - 70;
LoginDialog::LoginDialog(LoginData *loginData):
Window(_("Login")), mLoginData(loginData)
{
- gcn::Label *userLabel = new gcn::Label(_("Name:"));
- gcn::Label *passLabel = new gcn::Label(_("Password:"));
+ gcn::Label *userLabel = new Label(_("Name:"));
+ gcn::Label *passLabel = new Label(_("Password:"));
#ifdef EATHENA_SUPPORT
- gcn::Label *serverLabel = new gcn::Label(_("Server:"));
- gcn::Label *portLabel = new gcn::Label(_("Port:"));
- gcn::Label *dropdownLabel = new gcn::Label(_("Recent:"));
+ gcn::Label *serverLabel = new Label(_("Server:"));
+ gcn::Label *portLabel = new Label(_("Port:"));
+ gcn::Label *dropdownLabel = new Label(_("Recent:"));
std::vector<std::string> dfltServer;
dfltServer.push_back("server.themanaworld.org");
std::vector<std::string> dfltPort;
@@ -124,14 +123,13 @@ LoginDialog::LoginDialog(LoginData *loginData):
place(3, 6, mOkButton);
reflowLayout(250, 0);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
- if (mUserField->getText().empty()) {
+ if (mUserField->getText().empty())
mUserField->requestFocus();
- } else {
+ else
mPassField->requestFocus();
- }
mOkButton->setEnabled(canSubmit());
}
@@ -179,15 +177,13 @@ void LoginDialog::action(const gcn::ActionEvent &event)
#ifdef EATHENA_SUPPORT
// Transfer these fields on to the register dialog
mLoginData->hostname = mServerField->getText();
+
if (isUShort(mPortField->getText()))
- {
mLoginData->port = getUShort(mPortField->getText());
- }
else
- {
mLoginData->port = 6901;
- }
#endif
+
mLoginData->username = mUserField->getText();
mLoginData->password = mPassField->getText();
@@ -223,14 +219,12 @@ bool LoginDialog::isUShort(const std::string &str)
strPtr != strEnd; ++strPtr)
{
if (*strPtr < '0' || *strPtr > '9')
- {
return false;
- }
+
l = l * 10 + (*strPtr - '0'); // *strPtr - '0' will never be negative
+
if (l > 65535)
- {
return false;
- }
}
return true;
}
@@ -306,9 +300,7 @@ void LoginDialog::DropDownList::save(const std::string &server,
++sPtr, ++pPtr)
{
if (*sPtr != server || *pPtr != port)
- {
saveEntry(*sPtr, *pPtr, position);
- }
}
}
@@ -320,27 +312,24 @@ int LoginDialog::DropDownList::getNumberOfElements()
std::string LoginDialog::DropDownList::getElementAt(int i)
{
if (i < 0 || i >= getNumberOfElements())
- {
- return "";
- }
+ return "";
+
return getServerAt(i) + ":" + getPortAt(i);
}
std::string LoginDialog::DropDownList::getServerAt(int i)
{
if (i < 0 || i >= getNumberOfElements())
- {
return "";
- }
+
return mServers.at(i);
}
std::string LoginDialog::DropDownList::getPortAt(int i)
{
if (i < 0 || i >= getNumberOfElements())
- {
return "";
- }
+
return mPorts.at(i);
}
#endif
diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp
index 25ece461..e6ae2d3b 100644
--- a/src/gui/menuwindow.cpp
+++ b/src/gui/menuwindow.cpp
@@ -25,7 +25,9 @@
#include "button.h"
#include "menuwindow.h"
-#include "windowcontainer.h"
+#include "window.h"
+
+#include "../graphics.h"
#include "../utils/gettext.h"
@@ -54,13 +56,8 @@ namespace {
}
MenuWindow::MenuWindow():
- Window()
+ Popup("Menu")
{
- setResizable(false);
- setWindowName("Menu");
- setMovable(false);
- setTitleBarHeight(0);
-
// Buttons
static const char *buttonNames[] =
{
@@ -90,7 +87,7 @@ MenuWindow::MenuWindow():
h = btn->getHeight();
}
- setPosition(windowContainer->getWidth() - x - 3, 3);
+ setPosition(graphics->getWidth() - x - 3, 3);
setContentSize(x - 3, h);
}
@@ -99,7 +96,6 @@ void MenuWindow::draw(gcn::Graphics *graphics)
drawChildren(graphics);
}
-
void MenuWindowListener::action(const gcn::ActionEvent &event)
{
Window *window = NULL;
diff --git a/src/gui/menuwindow.h b/src/gui/menuwindow.h
index 9bb54e29..c3d5673e 100644
--- a/src/gui/menuwindow.h
+++ b/src/gui/menuwindow.h
@@ -22,14 +22,14 @@
#ifndef MENU_H
#define MENU_H
-#include "window.h"
+#include "popup.h"
/**
* The Button Menu.
*
* \ingroup Interface
*/
-class MenuWindow : public Window
+class MenuWindow : public Popup
{
public:
/**
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index 4347c9cc..93a55688 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -79,19 +79,6 @@ void Minimap::setMapImage(Image *img)
mMapImage->getWidth() + offsetX : titleWidth);
setMaxHeight(mMapImage->getHeight() + offsetY);
- // Make sure the window is within the minimum and maximum boundaries
- // TODO: Shouldn't this be happening automatically within the Window
- // class?
- if (getMinWidth() > getWidth())
- setWidth(getMinWidth());
- else if (getMaxWidth() < getWidth())
- setWidth(getMaxWidth());
- if (getMinHeight() > getHeight())
- setHeight(getMinHeight());
- else if (getMaxHeight() < getHeight())
- setHeight(getMaxHeight());
-
- setContentSize(getWidth() - offsetX, getHeight() - offsetY);
setDefaultSize(getX(), getY(), getWidth(), getHeight());
resetToDefaultSize();
@@ -112,6 +99,9 @@ void Minimap::draw(gcn::Graphics *graphics)
{
setVisible(mShow);
+ if (!isVisible())
+ return;
+
Window::draw(graphics);
if (!mShow)
diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp
index 5bc25bdb..95577e69 100644
--- a/src/gui/ministatus.cpp
+++ b/src/gui/ministatus.cpp
@@ -22,6 +22,7 @@
#include "gui.h"
#include "ministatus.h"
#include "progressbar.h"
+#include "status.h"
#include "../animatedsprite.h"
#include "../configuration.h"
@@ -30,13 +31,9 @@
#include "../utils/stringutils.h"
-MiniStatusWindow::MiniStatusWindow()
+MiniStatusWindow::MiniStatusWindow():
+ Popup("MiniStatus")
{
- setWindowName("MiniStatus");
- setResizable(false);
- setMovable(false);
- setTitleBarHeight(0);
-
mHpBar = new ProgressBar(1.0f, 100, 20, 0, 171, 34);
#ifdef EATHENA_SUPPORT
mMpBar = new ProgressBar(1.0f, 100, 20, 26, 102, 230);
@@ -62,8 +59,6 @@ MiniStatusWindow::MiniStatusWindow()
setContentSize(mHpBar->getX() + mHpBar->getWidth(),
mHpBar->getY() + mHpBar->getHeight());
#endif
- setDefaultSize(0, 0, getWidth(), getHeight());
- loadWindowState();
}
void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite)
@@ -86,43 +81,10 @@ extern volatile int tick_time;
void MiniStatusWindow::update()
{
- // HP Bar coloration
- int maxHp = player_node->getMaxHp();
- int hp = player_node->getHp();
- if (hp < int(maxHp / 3))
- {
- mHpBar->setColor(223, 32, 32); // Red
- }
- else if (hp < int((maxHp / 3) * 2))
- {
- mHpBar->setColor(230, 171, 34); // Orange
- }
- else
- {
- mHpBar->setColor(0, 171, 34); // Green
- }
-
+ StatusWindow::updateHPBar(mHpBar);
#ifdef EATHENA_SUPPORT
- float xp = (float) player_node->getXp() / player_node->mXpForNextLevel;
-
- if (xp != xp) xp = 0.0f; // check for NaN
- if (xp < 0.0f) xp = 0.0f; // make sure the experience isn't negative (uninitialized pointer most likely)
- if (xp > 1.0f) xp = 1.0f;
-#endif
-
- mHpBar->setProgress((float) hp / maxHp);
-#ifdef EATHENA_SUPPORT
- mMpBar->setProgress((float) player_node->mMp / player_node->mMaxMp);
- mXpBar->setProgress(xp);
-#endif
-
- // Update labels
- mHpBar->setText(toString(player_node->getHp()));
-#ifdef EATHENA_SUPPORT
- mMpBar->setText(toString(player_node->mMp));
-
- std::stringstream updatedText;
- updatedText << (float) ((int) (xp * 10000.0f)) / 100.0f << "%";
+ StatusWindow::updateMPBar(mMpBar);
+ StatusWindow::updateXPBar(mXpBar);
// Displays the number of monsters to next lvl
// (disabled for now but interesting idea)
@@ -136,8 +98,6 @@ void MiniStatusWindow::update()
<< config.getValue("xpBarMonsterCounterName", "Monsters") <<" left...";
}
*/
-
- mXpBar->setText(updatedText.str());
#endif
for (unsigned int i = 0; i < mIcons.size(); i++)
diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h
index b69f9a14..f6d80ca7 100644
--- a/src/gui/ministatus.h
+++ b/src/gui/ministatus.h
@@ -22,7 +22,7 @@
#ifndef MINISTATUS_H
#define MINISTATUS_H
-#include "window.h"
+#include "popup.h"
#include <vector>
@@ -34,7 +34,7 @@ class ProgressBar;
*
* \ingroup Interface
*/
-class MiniStatusWindow : public Window
+class MiniStatusWindow : public Popup
{
public:
/**
diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp
index 48f2adb7..5158e966 100644
--- a/src/gui/npc_text.cpp
+++ b/src/gui/npc_text.cpp
@@ -28,18 +28,33 @@
#include "../npc.h"
+#include "../net/messageout.h"
+#ifdef TMWSERV_SUPPORT
+#include "../net/tmwserv/gameserver/player.h"
+#else
+#include "../net/ea/protocol.h"
+#endif
+
#include "../utils/gettext.h"
-NpcTextDialog::NpcTextDialog():
- Window(_("NPC")),
- mState(NPC_TEXT_STATE_WAITING)
+#ifdef TMWSERV_SUPPORT
+NpcTextDialog::NpcTextDialog()
+#else
+NpcTextDialog::NpcTextDialog(Network *network)
+#endif
+ : Window(_("NPC"))
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
+ , mState(NPC_TEXT_STATE_WAITING)
{
+ setWindowName("NPCText");
setResizable(true);
setMinWidth(200);
setMinHeight(150);
- setDefaultSize(0, 0, 260, 200);
+ setDefaultSize(260, 200, ImageRect::CENTER);
mTextBox = new TextBox;
mTextBox->setEditable(false);
@@ -57,8 +72,14 @@ NpcTextDialog::NpcTextDialog():
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
- setLocationRelativeTo(getParent());
+}
+
+void NpcTextDialog::clearText()
+{
+ NPC::isTalking = false;
+ setText("");
}
void NpcTextDialog::setText(const std::string &text)
@@ -92,13 +113,15 @@ void NpcTextDialog::action(const gcn::ActionEvent &event)
if (event.getId() == "ok")
{
if (mState == NPC_TEXT_STATE_NEXT && current_npc) {
- current_npc->nextDialog();
+ nextDialog();
addText("\n> Next\n");
} else if (mState == NPC_TEXT_STATE_CLOSE ||
(mState == NPC_TEXT_STATE_NEXT && !current_npc)) {
setText("");
+ if (current_npc) nextDialog();
setVisible(false);
- if (current_npc) current_npc->handleDeath();
+ current_npc = 0;
+ NPC::isTalking = false;
} else return;
}
else return;
@@ -108,6 +131,26 @@ void NpcTextDialog::action(const gcn::ActionEvent &event)
mState = NPC_TEXT_STATE_WAITING;
}
+void NpcTextDialog::nextDialog(int npcID)
+{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::talkToNPC(npcID, false);
+#else
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_NPC_NEXT_REQUEST);
+ outMsg.writeInt32(npcID);
+#endif
+}
+
+void NpcTextDialog::closeDialog(int npcID)
+{
+#ifdef EATHENA_SUPPORT
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_NPC_CLOSE);
+ outMsg.writeInt32(npcID);
+#endif
+}
+
void NpcTextDialog::widgetResized(const gcn::Event &event)
{
Window::widgetResized(event);
@@ -115,3 +158,8 @@ void NpcTextDialog::widgetResized(const gcn::Event &event)
setText(mText);
}
+void NpcTextDialog::requestFocus()
+{
+ loadWindowState();
+ setVisible(true);
+}
diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h
index a1373830..4c0c31e3 100644
--- a/src/gui/npc_text.h
+++ b/src/gui/npc_text.h
@@ -28,6 +28,11 @@
#include "window.h"
+#include "../npc.h"
+
+#ifdef EATHENA_SUPPORT
+class Network;
+#endif
class TextBox;
/**
@@ -43,7 +48,11 @@ class NpcTextDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
NpcTextDialog();
+#else
+ NpcTextDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -75,6 +84,23 @@ class NpcTextDialog : public Window, public gcn::ActionListener
void showCloseButton();
/**
+ * Notifies the server that the client has performed a next action.
+ */
+ void nextDialog(int npcID = current_npc);
+
+ /**
+ * Notifies the server that the client has performed a close action.
+ */
+ void closeDialog(int npcID = current_npc);
+
+ /**
+ * Initializes window width to the last known setting. Since the dialog
+ * doesn't need any extra focus outside of what it's given in the Game
+ * class, this is all it does for now.
+ */
+ void requestFocus();
+
+ /**
* Called when resizing the window.
*
* @param event The calling event
@@ -82,6 +108,9 @@ class NpcTextDialog : public Window, public gcn::ActionListener
void widgetResized(const gcn::Event &event);
private:
+#ifdef EATHENA_SUPPORT
+ Network *mNetwork;
+#endif
gcn::ScrollArea *mScrollArea;
TextBox *mTextBox;
gcn::Button *mButton;
@@ -93,7 +122,9 @@ class NpcTextDialog : public Window, public gcn::ActionListener
NPC_TEXT_STATE_NEXT,
NPC_TEXT_STATE_CLOSE
};
- int mState;
+ NPCTextState mState;
};
+extern NpcTextDialog *npcTextDialog;
+
#endif // NPC_TEXT_H
diff --git a/src/gui/npcintegerdialog.cpp b/src/gui/npcintegerdialog.cpp
index 463f46ae..a7ae2748 100644
--- a/src/gui/npcintegerdialog.cpp
+++ b/src/gui/npcintegerdialog.cpp
@@ -28,24 +28,37 @@
#include "../npc.h"
+#include "../net/messageout.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
+
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
-extern NpcTextDialog *npcTextDialog;
-
-NpcIntegerDialog::NpcIntegerDialog():
- Window(_("NPC Number Request"))
+#ifdef TMWSERV_SUPPORT
+NpcIntegerDialog::NpcIntegerDialog()
+#else
+NpcIntegerDialog::NpcIntegerDialog(Network *network)
+#endif
+ : Window(_("NPC Number Request"))
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
{
+ setWindowName("NPCInteger");
mValueField = new IntTextField;
+ setDefaultSize(175, 75, ImageRect::CENTER);
+
mDecButton = new Button("-", "decvalue", this);
mIncButton = new Button("+", "incvalue", this);
gcn::Button *okButton = new Button(_("OK"), "ok", this);
gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this);
gcn::Button *resetButton = new Button(_("Reset"), "reset", this);
- mDecButton->setSize(20, 20);
- mIncButton->setSize(20, 20);
+ mDecButton->adjustSize();
+ mDecButton->setWidth(mIncButton->getWidth());
ContainerPlacer place;
place = getPlacer(0, 0);
@@ -60,7 +73,9 @@ NpcIntegerDialog::NpcIntegerDialog():
place(3, 0, okButton);
reflowLayout(175, 0);
- setLocationRelativeTo(getParent());
+ center();
+ setDefaultSize();
+ loadWindowState();
}
void NpcIntegerDialog::setRange(int min, int max)
@@ -73,18 +88,23 @@ int NpcIntegerDialog::getValue()
return mValueField->getValue();
}
+void NpcIntegerDialog::reset()
+{
+ mValueField->reset();
+}
+
void NpcIntegerDialog::action(const gcn::ActionEvent &event)
{
- int finish = 0;
+ bool finish = false;
if (event.getId() == "ok")
{
- finish = 1;
+ finish = true;
npcTextDialog->addText(strprintf("\n> %d\n", mValueField->getValue()));
}
else if (event.getId() == "cancel")
{
- finish = 1;
+ finish = true;
mValueField->reset();
npcTextDialog->addText(_("\n> Cancel\n"));
}
@@ -104,7 +124,15 @@ void NpcIntegerDialog::action(const gcn::ActionEvent &event)
if (finish)
{
setVisible(false);
- current_npc->integerInput(mValueField->getValue());
+ NPC::isTalking = false;
+
+#ifdef EATHENA_SUPPORT
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_NPC_INT_RESPONSE);
+ outMsg.writeInt32(current_npc);
+ outMsg.writeInt32(mValueField->getValue());
+#endif
+
mValueField->reset();
}
}
@@ -123,3 +151,13 @@ void NpcIntegerDialog::requestFocus()
{
mValueField->requestFocus();
}
+
+void NpcIntegerDialog::setVisible(bool visible)
+{
+ if (visible) {
+ npcTextDialog->setVisible(true);
+ requestFocus();
+ }
+
+ Window::setVisible(visible);
+}
diff --git a/src/gui/npcintegerdialog.h b/src/gui/npcintegerdialog.h
index 941bb55a..df74c904 100644
--- a/src/gui/npcintegerdialog.h
+++ b/src/gui/npcintegerdialog.h
@@ -26,6 +26,9 @@
#include "window.h"
+#ifdef EATHENA_SUPPORT
+class Network;
+#endif
class IntTextField;
/**
@@ -41,7 +44,11 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
NpcIntegerDialog();
+#else
+ NpcIntegerDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -54,6 +61,11 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener
int getValue();
/**
+ * Resets the integer input field.
+ */
+ void reset();
+
+ /**
* Prepares the NPC dialog.
*
* @param min The minimum value to allow
@@ -78,10 +90,17 @@ class NpcIntegerDialog : public Window, public gcn::ActionListener
*/
void requestFocus();
+ void setVisible(bool visible);
+
private:
+#ifdef EATHENA_SUPPORT
+ Network *mNetwork;
+#endif
gcn::Button *mDecButton;
gcn::Button *mIncButton;
IntTextField *mValueField;
};
+extern NpcIntegerDialog *npcIntegerDialog;
+
#endif // GUI_NPCINTEGERDIALOG_H
diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp
index 82e05fd5..968e2514 100644
--- a/src/gui/npclistdialog.cpp
+++ b/src/gui/npclistdialog.cpp
@@ -31,24 +31,39 @@
#include "../npc.h"
+#include "../net/messageout.h"
+#ifdef TMWSERV_SUPPORT
+#include "../net/tmwserv/gameserver/player.h"
+#else
+#include "../net/ea/protocol.h"
+#endif
+
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
-extern NpcTextDialog *npcTextDialog;
-
-NpcListDialog::NpcListDialog():
- Window(_("NPC"))
+#ifdef TMWSERV_SUPPORT
+NpcListDialog::NpcListDialog()
+#else
+NpcListDialog::NpcListDialog(Network *network)
+#endif
+ : Window("NPC")
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
{
+ setWindowName("NPCList");
setResizable(true);
setMinWidth(200);
setMinHeight(150);
- setDefaultSize(0, 0, 260, 200);
+ setDefaultSize(260, 200, ImageRect::CENTER);
mItemList = new ListBox(this);
mItemList->setWrappingEnabled(true);
+
gcn::ScrollArea *scrollArea = new ScrollArea(mItemList);
+
gcn::Button *okButton = new Button(_("OK"), "ok", this);
gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this);
@@ -56,14 +71,14 @@ NpcListDialog::NpcListDialog():
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
place(0, 0, scrollArea, 5).setPadding(3);
- place(3, 1, okButton);
- place(4, 1, cancelButton);
+ place(3, 1, cancelButton);
+ place(4, 1, okButton);
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
- setLocationRelativeTo(getParent());
}
int NpcListDialog::getNumberOfElements()
@@ -92,6 +107,8 @@ void NpcListDialog::parseItems(const std::string &itemString)
void NpcListDialog::reset()
{
+ NPC::isTalking = false;
+ mItemList->setSelected(-1);
mItems.clear();
}
@@ -102,6 +119,7 @@ void NpcListDialog::action(const gcn::ActionEvent &event)
{
// Send the selected index back to the server
int selectedIndex = mItemList->getSelected();
+
if (selectedIndex > -1)
{
choice = selectedIndex + 1;
@@ -113,12 +131,40 @@ void NpcListDialog::action(const gcn::ActionEvent &event)
{
choice = 0xff; // 0xff means cancel
npcTextDialog->addText(_("\n> Cancel\n"));
+ npcTextDialog->showCloseButton();
}
if (choice)
{
setVisible(false);
+ saveWindowState();
reset();
- current_npc->dialogChoice(choice);
+
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::selectFromNPC(current_npc, choice);
+#else
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_NPC_LIST_CHOICE);
+ outMsg.writeInt32(current_npc);
+ outMsg.writeInt8(choice);
+#endif
}
}
+
+void NpcListDialog::setVisible(bool visible)
+{
+ if (visible) {
+ npcTextDialog->setVisible(true);
+ requestFocus();
+ }
+
+ Window::setVisible(visible);
+}
+
+void NpcListDialog::requestFocus()
+{
+ mItemList->requestFocus();
+ mItemList->setSelected(0);
+ loadWindowState();
+ setVisible(true);
+}
diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h
index 7e37c7e6..6c1e02e3 100644
--- a/src/gui/npclistdialog.h
+++ b/src/gui/npclistdialog.h
@@ -29,6 +29,10 @@
#include <vector>
+#ifdef EATHENA_SUPPORT
+class Network;
+#endif
+
/**
* The npc list dialog.
*
@@ -43,7 +47,11 @@ class NpcListDialog : public Window, public gcn::ActionListener,
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
NpcListDialog();
+#else
+ NpcListDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -77,10 +85,23 @@ class NpcListDialog : public Window, public gcn::ActionListener,
*/
void reset();
+ void setVisible(bool visible);
+
+ /**
+ * Requests the listbox to take focus for input and sets window width
+ * to the last known setting.
+ */
+ void requestFocus();
+
private:
+#ifdef EATHENA_SUPPORT
+ Network *mNetwork;
+#endif
gcn::ListBox *mItemList;
std::vector<std::string> mItems;
};
+extern NpcListDialog *npcListDialog;
+
#endif // GUI_NPCLISTDIALOG_H
diff --git a/src/gui/npcstringdialog.cpp b/src/gui/npcstringdialog.cpp
index d9bf5682..c84de015 100644
--- a/src/gui/npcstringdialog.cpp
+++ b/src/gui/npcstringdialog.cpp
@@ -28,16 +28,29 @@
#include "../npc.h"
+#include "../net/messageout.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
+
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
-extern NpcTextDialog *npcTextDialog;
-
-NpcStringDialog::NpcStringDialog():
- Window(_("NPC Text Request"))
+#ifdef TMWSERV_SUPPORT
+NpcStringDialog::NpcStringDialog()
+#else
+NpcStringDialog::NpcStringDialog(Network *network)
+#endif
+ : Window(_("NPC Text Request"))
+#ifdef EATHENA_SUPPORT
+ , mNetwork(network)
+#endif
{
+ setWindowName("NPCString");
mValueField = new TextField("");
+ setDefaultSize(175, 75, ImageRect::CENTER);
+
gcn::Button *okButton = new Button(_("OK"), "ok", this);
gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this);
@@ -46,7 +59,9 @@ NpcStringDialog::NpcStringDialog():
place(2, 1, okButton);
reflowLayout(175, 0);
- setLocationRelativeTo(getParent());
+ center();
+ setDefaultSize();
+ loadWindowState();
}
std::string NpcStringDialog::getValue()
@@ -74,8 +89,19 @@ void NpcStringDialog::action(const gcn::ActionEvent &event)
}
setVisible(false);
- current_npc->stringInput(mValueField->getText());
+ NPC::isTalking = false;
+
+ std::string text = mValueField->getText();
mValueField->setText("");
+
+#ifdef EATHENA_SUPPORT
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_NPC_STR_RESPONSE);
+ outMsg.writeInt16(text.length() + 9);
+ outMsg.writeInt32(current_npc);
+ outMsg.writeString(text, text.length());
+ outMsg.writeInt8(0);
+#endif
}
bool NpcStringDialog::isInputFocused()
@@ -87,3 +113,13 @@ void NpcStringDialog::requestFocus()
{
mValueField->requestFocus();
}
+
+void NpcStringDialog::setVisible(bool visible)
+{
+ if (visible) {
+ npcTextDialog->setVisible(true);
+ requestFocus();
+ }
+
+ Window::setVisible(visible);
+}
diff --git a/src/gui/npcstringdialog.h b/src/gui/npcstringdialog.h
index 0faaf203..94cd59b2 100644
--- a/src/gui/npcstringdialog.h
+++ b/src/gui/npcstringdialog.h
@@ -26,6 +26,10 @@
#include <guichan/actionlistener.hpp>
+#ifdef EATHENA_SUPPORT
+class Network;
+#endif
+
/**
* The npc integer input dialog.
*
@@ -39,7 +43,11 @@ class NpcStringDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
+#ifdef TMWSERV_SUPPORT
NpcStringDialog();
+#else
+ NpcStringDialog(Network *network);
+#endif
/**
* Called when receiving actions from the widgets.
@@ -68,9 +76,16 @@ class NpcStringDialog : public Window, public gcn::ActionListener
*/
void requestFocus();
+ void setVisible(bool visible);
+
private:
+#ifdef EATHENA_SUPPORT
+ Network *mNetwork;
+#endif
gcn::TextField *mValueField;
std::string mDefault;
};
+extern NpcStringDialog *npcStringDialog;
+
#endif // GUI_NPCSTRINGDIALOG_H
diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp
index 4df3fa07..f1a97b49 100644
--- a/src/gui/ok_dialog.cpp
+++ b/src/gui/ok_dialog.cpp
@@ -22,6 +22,7 @@
#include <guichan/font.hpp>
#include "button.h"
+#include "gui.h"
#include "ok_dialog.h"
#include "scrollarea.h"
#include "textbox.h"
@@ -46,14 +47,15 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg,
mTextBox->setTextWrapped(msg, 260);
int numRows = mTextBox->getNumberOfRows();
+ const int fontHeight = getFont()->getHeight();
if (numRows > 1)
{
- // 15 == height of each line of text (based on font heights)
// 14 == row top + bottom graphic pixel heights
- setContentSize(mTextBox->getMinWidth() + 15, 15 + (numRows * 15) + okButton->getHeight());
- mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5,
- 3 + (numRows * 14)));
+ setContentSize(mTextBox->getMinWidth() + fontHeight, ((numRows + 1) *
+ fontHeight) + okButton->getHeight());
+ mTextArea->setDimension(gcn::Rectangle(4, 5,
+ mTextBox->getMinWidth() + 5, 3 + (numRows * fontHeight)));
}
else
{
@@ -62,17 +64,17 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg,
width = getFont()->getWidth(msg);
if (width < okButton->getWidth())
width = okButton->getWidth();
- setContentSize(width + 15, 30 + okButton->getHeight());
+ setContentSize(width + fontHeight, 30 + okButton->getHeight());
mTextArea->setDimension(gcn::Rectangle(4, 5, width + 5, 17));
}
okButton->setPosition((mTextBox->getMinWidth() - okButton->getWidth()) / 2,
- (numRows * 14) + okButton->getHeight() - 8);
+ ((numRows - 1) * fontHeight) + okButton->getHeight() + 2);
add(mTextArea);
add(okButton);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
okButton->requestFocus();
}
@@ -92,7 +94,6 @@ void OkDialog::action(const gcn::ActionEvent &event)
}
// Can we receive anything else anyway?
- if (event.getId() == "ok") {
+ if (event.getId() == "ok")
scheduleDelete();
- }
}
diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp
new file mode 100644
index 00000000..b1e165aa
--- /dev/null
+++ b/src/gui/palette.cpp
@@ -0,0 +1,347 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <math.h>
+
+#include "palette.h"
+#include "gui.h"
+
+#include "../configuration.h"
+#include "../game.h"
+
+#include "../utils/gettext.h"
+#include "../utils/stringutils.h"
+
+const gcn::Color Palette::BLACK = gcn::Color(0, 0, 0);
+
+const gcn::Color Palette::RAINBOW_COLORS[7] = {
+ gcn::Color(255, 0, 0),
+ gcn::Color(255, 153, 0),
+ gcn::Color(255, 255, 0),
+ gcn::Color(0, 153, 0),
+ gcn::Color(0, 204, 204),
+ gcn::Color(51, 0, 153),
+ gcn::Color(153, 0, 153)
+};
+/** Number of Elemets of RAINBOW_COLORS */
+const int Palette::RAINBOW_COLOR_COUNT = 7;
+
+std::string Palette::getConfigName(const std::string &typeName)
+{
+ std::string res = "Color" + typeName;
+
+ int pos = 5;
+ for (size_t i = 0; i < typeName.length(); i++)
+ {
+ if (i == 0 || typeName[i] == '_')
+ {
+ if (i > 0)
+ i++;
+
+ res[pos] = typeName[i];
+ }
+ else
+ {
+ res[pos] = tolower(typeName[i]);
+ }
+ pos++;
+ }
+ res.erase(pos, res.length() - pos);
+
+ return res;
+}
+
+DEFENUMNAMES(ColorType, COLOR_TYPE)
+
+const int Palette::GRADIENT_DELAY = 40;
+
+Palette::Palette() :
+ mRainbowTime(tick_time),
+ mColVector(ColVector(TYPE_COUNT))
+{
+ std::string indent = " ";
+ addColor(TEXT, 0x000000, STATIC, _("Text"));
+ addColor(SHADOW, 0x000000, STATIC, indent + _("Text Shadow"));
+ addColor(OUTLINE, 0x000000, STATIC, indent + _("Text Outline"));
+ addColor(PROGRESS_BAR, 0xffffff, STATIC, indent + _("Progress Bar Labels"));
+
+ addColor(BACKGROUND, 0xffffff, STATIC, _("Background"));
+
+ addColor(HIGHLIGHT, 0xebc873, STATIC, _("Highlight"), 'H');
+ addColor(TAB_HIGHLIGHT, 0xff0000, PULSE, indent + _("Tab Highlight"));
+ addColor(SHOP_WARNING, 0x910000, STATIC, indent +
+ _("Item too expensive"));
+
+ addColor(CHAT, 0x000000, STATIC, _("Chat"), 'C');
+ addColor(GM, 0xff0000, STATIC, indent + _("GM"), 'G');
+ addColor(PLAYER, 0x1fa052, STATIC, indent + _("Player"), 'Y');
+ addColor(WHISPER, 0x0000ff, STATIC, indent + _("Whisper"), 'W');
+ addColor(IS, 0xa08527, STATIC, indent + _("Is"), 'I');
+ addColor(PARTY, 0xff00d8, STATIC, indent + _("Party"), 'P');
+ addColor(SERVER, 0x8415e2, STATIC, indent + _("Server"), 'S');
+ addColor(LOGGER, 0x919191, STATIC, indent + _("Logger"), 'L');
+ addColor(HYPERLINK, 0xe50d0d, STATIC, indent + _("Hyperlink"), '<');
+
+ addColor(BEING, 0xffffff, STATIC, _("Being"));
+ addColor(PC, 0xffffff, STATIC, indent + _("Other Player's Names"));
+ addColor(SELF, 0xff8040, STATIC, indent + _("Own Name"));
+ addColor(GM_NAME, 0x00ff00, STATIC, indent + _("GM Names"));
+ addColor(NPC, 0xc8c8ff, STATIC, indent + _("NPCs"));
+ addColor(MONSTER, 0xff4040, STATIC, indent + _("Monsters"));
+
+ addColor(UNKNOWN_ITEM, 0x000000, STATIC, _("Unknown Item Type"));
+ addColor(GENERIC, 0x21a5b1, STATIC, indent + _("Generic"));
+ addColor(HEAD, 0x527fa4, STATIC, indent + _("Hat"));
+ addColor(USABLE, 0x268d24, STATIC, indent + _("Usable"));
+ addColor(TORSO, 0xd12aa4, STATIC, indent + _("Shirt"));
+ addColor(ONEHAND, 0xf42a2a, STATIC, indent + _("1 Handed Weapons"));
+ addColor(LEGS, 0x699900, STATIC, indent + _("Pants"));
+ addColor(FEET, 0xaa1d48, STATIC, indent + _("Shoes"));
+ addColor(TWOHAND, 0xf46d0e, STATIC, indent + _("2 Handed Weapons"));
+ addColor(SHIELD, 0x9c2424, STATIC, indent + _("Shield"));
+ addColor(RING, 0x0000ff, STATIC, indent + _("Ring"));
+ addColor(ARMS, 0x9c24e8, STATIC, indent + _("Arms"));
+ addColor(AMMO, 0x8b6311, STATIC, indent + _("Ammo"));
+
+ addColor(PARTICLE, 0xffffff, STATIC, _("Particle Effects"));
+ addColor(PICKUP_INFO, 0x28dc28, STATIC, indent + _("Pickup Notification"));
+ addColor(EXP_INFO, 0xffff00, STATIC, indent + _("Exp Notification"));
+ addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC,
+ indent + _("Player hits Monster"));
+ addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC,
+ indent + _("Monster hits Player"));
+ addColor(HIT_CRITICAL, 0xff0000, RAINBOW, indent + _("Critical Hit"));
+ addColor(MISS, 0xffff00, STATIC, indent + _("Misses"));
+ commit(true);
+}
+
+Palette::~Palette()
+{
+ const std::string *configName;
+ for (ColVector::iterator col = mColVector.begin(),
+ colEnd = mColVector.end(); col != colEnd; ++col)
+ {
+ configName = &ColorTypeNames[col->type];
+ config.setValue(*configName + "Gradient", col->committedGrad);
+ if (col->grad == STATIC || col->grad == PULSE)
+ {
+ config.setValue(*configName, toString(col->getRGB()));
+ }
+ }
+}
+
+const gcn::Color& Palette::getColor(char c, bool &valid)
+ {
+ for (ColVector::const_iterator col = mColVector.begin(),
+ colEnd = mColVector.end(); col != colEnd; ++col)
+ {
+ if (col->ch == c)
+ {
+ valid = true;
+ return col->color;
+ }
+ }
+ valid = false;
+ return BLACK;
+}
+
+void Palette::setColor(ColorType type, int r, int g, int b)
+{
+ mColVector[type].color.r = r;
+ mColVector[type].color.g = g;
+ mColVector[type].color.b = b;
+}
+
+void Palette::setGradient(ColorType type, GradientType grad)
+{
+ ColorElem *elem = &mColVector[type];
+ if (elem->grad != STATIC && grad == STATIC)
+ {
+ for (size_t i = 0; i < mGradVector.size(); i++)
+ {
+ if (mGradVector[i] == elem)
+ {
+ mGradVector.erase(mGradVector.begin() + i);
+ break;
+ }
+ }
+ }
+ else if (elem->grad == STATIC && grad != STATIC)
+ {
+ mGradVector.push_back(elem);
+ }
+
+ if (elem->grad != grad)
+ {
+ elem->grad = grad;
+ }
+}
+
+std::string Palette::getElementAt(int i)
+{
+ if (i < 0 || i >= getNumberOfElements())
+ {
+ return "";
+ }
+ return mColVector[i].text;
+}
+
+Palette::ColorType Palette::getColorTypeAt(int i)
+{
+ if (i < 0 || i >= getNumberOfElements())
+ {
+ return CHAT;
+ }
+ return mColVector[i].type;
+}
+
+void Palette::commit(bool commitNonStatic)
+{
+ for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end();
+ i != iEnd; ++i)
+ {
+ i->committedGrad = i->grad;
+ if (commitNonStatic || i->grad == STATIC)
+ {
+ i->committedColor = i->color;
+ }
+ else if (i->grad == PULSE)
+ {
+ i->committedColor = i->testColor;
+ }
+ }
+}
+
+void Palette::rollback()
+{
+ for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end();
+ i != iEnd;
+ ++i)
+ {
+ if (i->grad != i->committedGrad)
+ {
+ setGradient(i->type, i->committedGrad);
+ }
+ setColor(i->type, i->committedColor.r, i->committedColor.g,
+ i->committedColor.b);
+ if (i->grad == PULSE)
+ {
+ i->testColor.r = i->committedColor.r;
+ i->testColor.g = i->committedColor.g;
+ i->testColor.b = i->committedColor.b;
+ }
+ }
+}
+
+void Palette::addColor(Palette::ColorType type, int rgb,
+ Palette::GradientType grad,
+ const std::string &text, char c)
+{
+ const std::string *configName = &ColorTypeNames[type];
+ gcn::Color trueCol = (int)config.getValue(*configName, rgb);
+ grad = (GradientType)config.getValue(*configName + "Gradient", grad);
+ mColVector[type].set(type, trueCol, grad, text, c);
+ if (grad != STATIC)
+ {
+ mGradVector.push_back(&mColVector[type]);
+ }
+}
+
+void Palette::advanceGradient ()
+{
+ if (get_elapsed_time(mRainbowTime) > 5)
+ {
+ int pos, colIndex, colVal;
+ // For slower systems, advance can be greater than one (advance > 1
+ // skips advance-1 steps). Should make gradient look the same
+ // independent of the framerate.
+ int advance = get_elapsed_time(mRainbowTime) / 5;
+ double startColVal, destColVal;
+
+ for (size_t i = 0; i < mGradVector.size(); i++)
+ {
+ mGradVector[i]->gradientIndex =
+ (mGradVector[i]->gradientIndex + advance) %
+ (GRADIENT_DELAY * ((mGradVector[i]->grad == SPECTRUM) ?
+ (mGradVector[i]->grad == PULSE) ? 255 : 6 :
+ RAINBOW_COLOR_COUNT));
+
+ pos = mGradVector[i]->gradientIndex % GRADIENT_DELAY;
+ colIndex = mGradVector[i]->gradientIndex / GRADIENT_DELAY;
+
+ if (mGradVector[i]->grad == PULSE)
+ {
+ colVal = (int) (255.0 * (sin(M_PI *
+ (mGradVector[i]->gradientIndex) / 255) + 1) / 2);
+
+ const gcn::Color* col = &mGradVector[i]->testColor;
+
+ mGradVector[i]->color.r = ((colVal * col->r) / 255) % (col->r + 1);
+ mGradVector[i]->color.g = ((colVal * col->g) / 255) % (col->g + 1);
+ mGradVector[i]->color.b = ((colVal * col->b) / 255) % (col->b + 1);
+ }
+ if (mGradVector[i]->grad == SPECTRUM)
+ {
+ if (colIndex % 2)
+ { // falling curve
+ colVal = (int)(255.0 * (cos(M_PI * pos / GRADIENT_DELAY) +
+ 1) / 2);
+ }
+ else
+ { // ascending curve
+ colVal = (int)(255.0 * (cos(M_PI * (GRADIENT_DELAY-pos) /
+ GRADIENT_DELAY) + 1) / 2);
+ }
+
+ mGradVector[i]->color.r =
+ (colIndex == 0 || colIndex == 5) ? 255 :
+ (colIndex == 1 || colIndex == 4) ? colVal : 0;
+ mGradVector[i]->color.g =
+ (colIndex == 1 || colIndex == 2) ? 255 :
+ (colIndex == 0 || colIndex == 3) ? colVal : 0;
+ mGradVector[i]->color.b =
+ (colIndex == 3 || colIndex == 4) ? 255 :
+ (colIndex == 2 || colIndex == 5) ? colVal : 0;
+ }
+ else if (mGradVector[i]->grad == RAINBOW)
+ {
+ const gcn::Color* startCol = &RAINBOW_COLORS[colIndex];
+ const gcn::Color* destCol =
+ &RAINBOW_COLORS[(colIndex + 1) % RAINBOW_COLOR_COUNT];
+
+ startColVal = (cos(M_PI * pos / GRADIENT_DELAY) + 1) / 2;
+ destColVal = 1 - startColVal;
+
+ mGradVector[i]->color.r =(int)(startColVal * startCol->r +
+ destColVal * destCol->r);
+
+ mGradVector[i]->color.g =(int)(startColVal * startCol->g +
+ destColVal * destCol->g);
+
+ mGradVector[i]->color.b =(int)(startColVal * startCol->b +
+ destColVal * destCol->b);
+ }
+ }
+
+ mRainbowTime = tick_time;
+ }
+}
diff --git a/src/gui/palette.h b/src/gui/palette.h
new file mode 100644
index 00000000..1a466ed4
--- /dev/null
+++ b/src/gui/palette.h
@@ -0,0 +1,350 @@
+/*
+ * Configurable text colors
+ * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net>
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALETTE_H
+#define PALETTE_H
+
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include <guichan/listmodel.hpp>
+#include <guichan/color.hpp>
+
+// Generate strings from an enum ... some preprocessor fun.
+#define EDEF(a) a,
+#define ECONFIGSTR(a) Palette::getConfigName(#a),
+
+#define TEXTENUM(name,def)\
+ enum name { def(EDEF) };\
+ static const std::string name ## Names[];
+#define DEFENUMNAMES(name,def)\
+ const std::string Palette::name ## Names[] = { def(ECONFIGSTR) "" };
+
+/**
+ * Class controlling the game's color palette.
+ */
+class Palette : public gcn::ListModel
+{
+ public:
+ /** List of all colors that are configurable. */
+ #define COLOR_TYPE(ENTRY)\
+ ENTRY(TEXT)\
+ ENTRY(SHADOW)\
+ ENTRY(OUTLINE)\
+ ENTRY(PROGRESS_BAR)\
+ ENTRY(BACKGROUND)\
+ ENTRY(HIGHLIGHT)\
+ ENTRY(TAB_HIGHLIGHT)\
+ ENTRY(SHOP_WARNING)\
+ ENTRY(CHAT)\
+ ENTRY(GM)\
+ ENTRY(PLAYER)\
+ ENTRY(WHISPER)\
+ ENTRY(IS)\
+ ENTRY(PARTY)\
+ ENTRY(SERVER)\
+ ENTRY(LOGGER)\
+ ENTRY(HYPERLINK)\
+ ENTRY(BEING)\
+ ENTRY(PC)\
+ ENTRY(SELF)\
+ ENTRY(GM_NAME)\
+ ENTRY(NPC)\
+ ENTRY(MONSTER)\
+ ENTRY(UNKNOWN_ITEM)\
+ ENTRY(GENERIC)\
+ ENTRY(HEAD)\
+ ENTRY(USABLE)\
+ ENTRY(TORSO)\
+ ENTRY(ONEHAND)\
+ ENTRY(LEGS)\
+ ENTRY(FEET)\
+ ENTRY(TWOHAND)\
+ ENTRY(SHIELD)\
+ ENTRY(RING)\
+ ENTRY(ARMS)\
+ ENTRY(AMMO)\
+ ENTRY(PARTICLE)\
+ ENTRY(EXP_INFO)\
+ ENTRY(PICKUP_INFO)\
+ ENTRY(HIT_PLAYER_MONSTER)\
+ ENTRY(HIT_MONSTER_PLAYER)\
+ ENTRY(HIT_CRITICAL)\
+ ENTRY(MISS)\
+ ENTRY(TYPE_COUNT)\
+
+ TEXTENUM(ColorType, COLOR_TYPE)
+
+ /** Colors can be static or can alter over time. */
+ enum GradientType {
+ STATIC,
+ PULSE,
+ SPECTRUM,
+ RAINBOW
+ };
+
+ /**
+ * Constructor
+ */
+ Palette();
+
+ /**
+ * Destructor
+ */
+ ~Palette();
+
+ /**
+ * Returns the color associated with a character, if it exists. Returns
+ * Palette::BLACK if the character is not found.
+ *
+ * @param c character requested
+ * @param valid indicate whether character is known
+ *
+ * @return the requested color or Palette::BLACK
+ */
+ const gcn::Color& getColor(char c, bool &valid);
+
+ /**
+ * Gets the color associated with the type. Sets the alpha channel
+ * before returning.
+ *
+ * @param type the color type requested
+ * @param alpha alpha channel to use
+ *
+ * @return the requested color
+ */
+ inline const gcn::Color& getColor(ColorType type, int alpha = 255)
+ {
+ gcn::Color* col = &mColVector[type].color;
+ col->a = alpha;
+ return *col;
+ }
+
+ /**
+ * Gets the committed color associated with the specified type.
+ *
+ * @param type the color type requested
+ *
+ * @return the requested committed color
+ */
+ inline const gcn::Color& getCommittedColor(ColorType type)
+ {
+ return mColVector[type].committedColor;
+ }
+
+ /**
+ * Gets the test color associated with the specified type.
+ *
+ * @param type the color type requested
+ *
+ * @return the requested test color
+ */
+ inline const gcn::Color& getTestColor(ColorType type)
+ {
+ return mColVector[type].testColor;
+ }
+
+ /**
+ * Sets the test color associated with the specified type.
+ *
+ * @param type the color type requested
+ * @param color the color that should be tested
+ */
+ inline void setTestColor(ColorType type, gcn::Color color)
+ {
+ mColVector[type].testColor = color;
+ }
+
+ /**
+ * Gets the GradientType associated with the specified type.
+ *
+ * @param type the color type of the color
+ *
+ * @return the gradient type of the color with the given index
+ */
+ inline GradientType getGradientType(ColorType type)
+ {
+ return mColVector[type].grad;
+ }
+
+ /**
+ * Get the character used by the specified color.
+ *
+ * @param type the color type of the color
+ *
+ * @return the color char of the color with the given index
+ */
+ inline char getColorChar(ColorType type)
+ {
+ return mColVector[type].ch;
+ }
+
+ /**
+ * Sets the color for the specified type.
+ *
+ * @param type color to be set
+ * @param r red component
+ * @param g green component
+ * @param b blue component
+ */
+ void setColor(ColorType type, int r, int g, int b);
+
+ /**
+ * Sets the gradient type for the specified color.
+ *
+ * @param grad gradient type to set
+ */
+ void setGradient(ColorType type, GradientType grad);
+
+ /**
+ * Returns the number of colors known.
+ *
+ * @return the number of colors known
+ */
+ inline int getNumberOfElements() { return mColVector.size(); }
+
+ /**
+ * Returns the name of the ith color.
+ *
+ * @param i index of color interested in
+ *
+ * @return the name of the color
+ */
+ std::string getElementAt(int i);
+
+ /**
+ * Gets the ColorType used by the color for the element at index i in
+ * the current color model.
+ *
+ * @param i the index of the color
+ *
+ * @return the color type of the color with the given index
+ */
+ ColorType getColorTypeAt(int i);
+
+ /**
+ * Commit the colors
+ */
+ inline void commit()
+ {
+ commit(false);
+ }
+
+ /**
+ * Rollback the colors
+ */
+ void rollback();
+
+ /**
+ * Updates all colors, that are non-static.
+ */
+ void advanceGradient();
+
+ private:
+ /** Black Color Constant */
+ static const gcn::Color BLACK;
+
+ /** Colors used for the rainbow gradient */
+ static const gcn::Color RAINBOW_COLORS[];
+ static const int RAINBOW_COLOR_COUNT;
+ /** Parameter to control the speed of the gradient */
+ static const int GRADIENT_DELAY;
+ /** Time tick, that gradient-type colors were updated the last time. */
+ int mRainbowTime;
+
+ /**
+ * Define a color replacement.
+ *
+ * @param i the index of the color to replace
+ * @param r red component
+ * @param g green component
+ * @param b blue component
+ */
+ void setColorAt(int i, int r, int g, int b);
+
+ /**
+ * Commit the colors. Commit the non-static color values, if
+ * commitNonStatic is true. Only needed in the constructor.
+ */
+ void commit(bool commitNonStatic);
+
+ struct ColorElem
+ {
+ ColorType type;
+ gcn::Color color;
+ gcn::Color testColor;
+ gcn::Color committedColor;
+ std::string text;
+ char ch;
+ GradientType grad;
+ GradientType committedGrad;
+ int gradientIndex;
+
+ void set(ColorType type, gcn::Color& color, GradientType grad,
+ const std::string &text, char c)
+ {
+ ColorElem::type = type;
+ ColorElem::color = color;
+ ColorElem::text = text;
+ ColorElem::ch = c;
+ ColorElem::grad = grad;
+ ColorElem::gradientIndex = rand();
+ }
+
+ inline int getRGB()
+ {
+ return (committedColor.r << 16) | (committedColor.g << 8) |
+ committedColor.b;
+ }
+ };
+ typedef std::vector<ColorElem> ColVector;
+ /** Vector containing the colors. */
+ ColVector mColVector;
+ std::vector<ColorElem*> mGradVector;
+
+ /**
+ * Initialise color
+ *
+ * @param c character that needs initialising
+ * @param rgb default color if not found in config
+ * @param text identifier of color
+ */
+ void addColor(ColorType type, int rgb, GradientType grad,
+ const std::string &text, char c = 0);
+
+ /**
+ * Prefixes the given string with "Color", lowercases all letters but
+ * the first and all following a '_'. All '_'s will be removed.
+ *
+ * E.g.: HIT_PLAYER_MONSTER -> HitPlayerMonster
+ *
+ * @param typeName string to transform
+ *
+ * @return the transformed string
+ */
+ static std::string getConfigName(const std::string& typeName);
+};
+
+extern Palette *guiPalette;
+
+#endif
diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp
index 2bfa798c..b7e553dc 100644
--- a/src/gui/playerbox.cpp
+++ b/src/gui/playerbox.cpp
@@ -78,6 +78,9 @@ PlayerBox::~PlayerBox()
void PlayerBox::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
if (mPlayer)
{
// Draw character
diff --git a/src/gui/popup.cpp b/src/gui/popup.cpp
new file mode 100644
index 00000000..17d299a5
--- /dev/null
+++ b/src/gui/popup.cpp
@@ -0,0 +1,209 @@
+/*
+ * Aethyra
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra based on original code
+ * from The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <algorithm>
+#include <cassert>
+#include <climits>
+
+#include <guichan/exception.hpp>
+
+#include "gui.h"
+#include "skin.h"
+#include "popup.h"
+#include "window.h"
+#include "windowcontainer.h"
+
+#include "../configlistener.h"
+#include "../configuration.h"
+#include "../log.h"
+
+#include "../resources/image.h"
+
+ConfigListener *Popup::popupConfigListener = 0;
+int Popup::instances = 0;
+bool Popup::mAlphaChanged = false;
+
+class PopupConfigListener : public ConfigListener
+{
+ void optionChanged(const std::string &)
+ {
+ Popup::mAlphaChanged = true;
+ }
+};
+
+Popup::Popup(const std::string& name, Window *parent,
+ const std::string& skin):
+ mParent(parent),
+ mPopupName(name),
+ mMinWidth(100),
+ mMinHeight(40),
+ mMaxWidth(INT_MAX),
+ mMaxHeight(INT_MAX)
+{
+ logger->log("Popup::Popup(\"%s\")", name.c_str());
+
+ if (!windowContainer)
+ throw GCN_EXCEPTION("Popup::Popup(): no windowContainer set");
+
+ if (instances == 0)
+ {
+ popupConfigListener = new PopupConfigListener();
+ // Send GUI alpha changed for initialization
+ popupConfigListener->optionChanged("guialpha");
+ config.addListener("guialpha", popupConfigListener);
+ }
+
+ setPadding(3);
+
+ instances++;
+
+ // Loads the skin
+ mSkin = skinLoader->load(skin);
+
+ setGuiAlpha();
+
+ // Add this window to the window container
+ windowContainer->add(this);
+
+ // Popups are invisible by default
+ setVisible(false);
+}
+
+Popup::~Popup()
+{
+ logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str());
+
+ while (!mWidgets.empty())
+ {
+ gcn::Widget *w = mWidgets.front();
+ remove(w);
+ delete(w);
+ }
+
+ instances--;
+
+ mSkin->instances--;
+
+ if (instances == 0)
+ {
+ config.removeListener("guialpha", popupConfigListener);
+ delete popupConfigListener;
+ popupConfigListener = NULL;
+ }
+}
+
+void Popup::setWindowContainer(WindowContainer *wc)
+{
+ windowContainer = wc;
+}
+
+void Popup::draw(gcn::Graphics *graphics)
+{
+ if (!isVisible())
+ return;
+
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
+
+ // Update Popup alpha values
+ if (mAlphaChanged)
+ {
+ for_each(mSkin->getBorder().grid, mSkin->getBorder().grid + 9,
+ std::bind2nd(std::mem_fun(&Image::setAlpha),
+ config.getValue("guialpha", 0.8)));
+ }
+ drawChildren(graphics);
+}
+
+gcn::Rectangle Popup::getChildrenArea()
+{
+ return gcn::Rectangle(getPadding(), 0, getWidth() - getPadding() * 2,
+ getHeight() - getPadding() * 2);
+}
+
+void Popup::setContentSize(int width, int height)
+{
+ width += 2 * getPadding();
+ height += 2 * getPadding();
+
+ if (getMinWidth() > width)
+ width = getMinWidth();
+ else if (getMaxWidth() < width)
+ width = getMaxWidth();
+ if (getMinHeight() > height)
+ height = getMinHeight();
+ else if (getMaxHeight() < height)
+ height = getMaxHeight();
+
+ setSize(width, height);
+}
+
+void Popup::setLocationRelativeTo(gcn::Widget *widget)
+{
+ int wx, wy;
+ int x, y;
+
+ widget->getAbsolutePosition(wx, wy);
+ getAbsolutePosition(x, y);
+
+ setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x),
+ getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y));
+}
+
+void Popup::setMinWidth(unsigned int width)
+{
+ mMinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth();
+}
+
+void Popup::setMinHeight(unsigned int height)
+{
+ mMinHeight = height > mSkin->getMinHeight() ? height : mSkin->getMinHeight();
+}
+
+void Popup::setMaxWidth(unsigned int width)
+{
+ mMaxWidth = width;
+}
+
+void Popup::setMaxHeight(unsigned int height)
+{
+ mMaxHeight = height;
+}
+
+void Popup::scheduleDelete()
+{
+ windowContainer->scheduleDelete(this);
+}
+
+void Popup::setGuiAlpha()
+{
+ //logger->log("Popup::setGuiAlpha: Alpha Value %f", config.getValue("guialpha", 0.8));
+ for (int i = 0; i < 9; i++)
+ {
+ //logger->log("Popup::setGuiAlpha: Border Image (%i)", i);
+ mSkin->getBorder().grid[i]->setAlpha(config.getValue("guialpha", 0.8));
+ }
+
+ mAlphaChanged = false;
+}
+
diff --git a/src/gui/popup.h b/src/gui/popup.h
new file mode 100644
index 00000000..bfe8d7e9
--- /dev/null
+++ b/src/gui/popup.h
@@ -0,0 +1,194 @@
+/*
+ * Aethyra
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra based on original code
+ * from The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef POPUP_H
+#define POPUP_H
+
+#include <guichan/widgets/container.hpp>
+
+#include "../graphics.h"
+#include "../guichanfwd.h"
+
+class ConfigListener;
+class Skin;
+class SkinLoader;
+class Window;
+class WindowContainer;
+
+/**
+ * A rather reduced down version of the Window class that is particularly suited
+ * for
+ *
+ * \ingroup GUI
+ */
+class Popup : public gcn::Container
+{
+ public:
+ friend class PopupConfigListener;
+
+ /**
+ * Constructor. Initializes the title to the given text and hooks
+ * itself into the popup container.
+ *
+ * @param name A human readable name for the popup. Only useful for
+ * debugging purposes.
+ * @param parent The parent Window. This is the Window standing above
+ * this one in the Window hiearchy. When reordering,
+ * a Popup will never go below its parent Window.
+ * @param skin The location where the Popup's skin XML can be found.
+ */
+ Popup(const std::string& name = "", Window *parent = NULL,
+ const std::string &skin = "graphics/gui/gui.xml");
+
+ /**
+ * Destructor. Deletes all the added widgets.
+ */
+ ~Popup();
+
+ /**
+ * Sets the window container to be used by new popups.
+ */
+ static void setWindowContainer(WindowContainer *windowContainer);
+
+ /**
+ * Draws the popup.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Sets the size of this popup.
+ */
+ void setContentSize(int width, int height);
+
+ /**
+ * Sets the location relative to the given widget.
+ */
+ void setLocationRelativeTo(gcn::Widget *widget);
+
+ /**
+ * Sets the minimum width of the popup.
+ */
+ void setMinWidth(unsigned int width);
+
+ /**
+ * Sets the minimum height of the popup.
+ */
+ void setMinHeight(unsigned int height);
+
+ /**
+ * Sets the maximum width of the popup.
+ */
+ void setMaxWidth(unsigned int width);
+
+ /**
+ * Sets the minimum height of the popup.
+ */
+ void setMaxHeight(unsigned int height);
+
+ /**
+ * Gets the minimum width of the popup.
+ */
+ int getMinWidth() { return mMinWidth; }
+
+ /**
+ * Gets the minimum height of the popup.
+ */
+ int getMinHeight() { return mMinHeight; }
+
+ /**
+ * Gets the maximum width of the popup.
+ */
+ int getMaxWidth() { return mMaxWidth; }
+
+ /**
+ * Gets the minimum height of the popup.
+ */
+ int getMaxHeight() { return mMaxHeight; }
+
+ /**
+ * Gets the padding of the popup. The padding is the distance between
+ * the popup border and the content.
+ *
+ * @return The padding of the popup.
+ * @see setPadding
+ */
+ unsigned int getPadding() const { return mPadding; }
+
+ /**
+ * Sets the padding of the popup. The padding is the distance between the
+ * popup border and the content.
+ *
+ * @param padding The padding of the popup.
+ * @see getPadding
+ */
+ void setPadding(unsigned int padding) { mPadding = padding; }
+
+ /**
+ * Returns the parent Window.
+ *
+ * @return The parent Window or <code>NULL</code> if there is none.
+ */
+ Window* getParentWindow() { return mParent; }
+
+ /**
+ * Sets the name of the popup. This is only useful for debug purposes.
+ */
+ void setPopupName(const std::string &name) { mPopupName = name; }
+
+ /**
+ * Returns the name of the popup. This is only useful for debug purposes.
+ */
+ const std::string& getPopupName() { return mPopupName; }
+
+ /**
+ * Schedule this popup for deletion. It will be deleted at the start
+ * of the next logic update.
+ */
+ void scheduleDelete();
+
+ // Inherited from BasicContainer
+
+ virtual gcn::Rectangle getChildrenArea();
+
+ private:
+ void setGuiAlpha();
+
+ Window *mParent; /**< The parent Window (if there is one) */
+ std::string mPopupName; /**< Name of the Popup */
+ static bool mAlphaChanged; /**< Whether the alpha percent was changed */
+ int mMinWidth; /**< Minimum Popup width */
+ int mMinHeight; /**< Minimum Popup height */
+ int mMaxWidth; /**< Maximum Popup width */
+ int mMaxHeight; /**< Maximum Popup height */
+ unsigned int mPadding; /**< Holds the padding of the window. */
+
+ /**
+ * The config listener that listens to changes relevant to all Popups.
+ */
+ static ConfigListener *popupConfigListener;
+
+ static int instances; /**< Number of Popup instances */
+
+ Skin* mSkin; /**< Skin in use by this Popup */
+};
+
+#endif
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index ced44f42..9ff9b23f 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -26,11 +26,11 @@
#include "inventorywindow.h"
#include "item_amount.h"
#include "popupmenu.h"
-#include "windowcontainer.h"
#include "../being.h"
#include "../beingmanager.h"
#include "../floor_item.h"
+#include "../graphics.h"
#include "../item.h"
#include "../localplayer.h"
#include "../npc.h"
@@ -75,7 +75,7 @@ void PopupMenu::showPopup(int x, int y, Being *being)
{
case Being::PLAYER:
{
- // Players can be traded with. Later also attack, follow and
+ // Players can be traded with. Later also follow and
// add as buddy will be options in this menu.
const std::string &name = being->getName();
mBrowserBox->addRow(strprintf(_("@@trade|Trade With %s@@"), name.c_str()));
@@ -345,10 +345,10 @@ void PopupMenu::showPopup(int x, int y, Item *item)
void PopupMenu::showPopup(int x, int y)
{
setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8);
- if (windowContainer->getWidth() < (x + getWidth() + 5))
- x = windowContainer->getWidth() - getWidth();
- if (windowContainer->getHeight() < (y + getHeight() + 5))
- y = windowContainer->getHeight() - getHeight();
+ if (graphics->getWidth() < (x + getWidth() + 5))
+ x = graphics->getWidth() - getWidth();
+ if (graphics->getHeight() < (y + getHeight() + 5))
+ y = graphics->getHeight() - getHeight();
setPosition(x, y);
setVisible(true);
requestMoveToTop();
diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h
index 2694abd8..0a6877d9 100644
--- a/src/gui/popupmenu.h
+++ b/src/gui/popupmenu.h
@@ -22,8 +22,6 @@
#ifndef POPUP_MENU_H
#define POPUP_MENU_H
-#include <SDL.h> // for Uint32
-
#include "linkhandler.h"
#include "window.h"
@@ -68,7 +66,7 @@ class PopupMenu : public Window, public LinkHandler
private:
BrowserBox* mBrowserBox;
- Uint32 mBeingId;
+ int mBeingId;
FloorItem* mFloorItem;
Item *mItem;
diff --git a/src/gui/progressbar.cpp b/src/gui/progressbar.cpp
index 85f21604..02ddab16 100644
--- a/src/gui/progressbar.cpp
+++ b/src/gui/progressbar.cpp
@@ -22,7 +22,9 @@
#include <guichan/font.hpp>
#include "gui.h"
+#include "palette.h"
#include "progressbar.h"
+#include "textrenderer.h"
#include "../configuration.h"
#include "../graphics.h"
@@ -139,32 +141,22 @@ void ProgressBar::draw(gcn::Graphics *graphics)
// The bar
if (mProgress > 0)
{
-
graphics->setColor(gcn::Color(mRed, mGreen, mBlue, alpha));
graphics->fillRectangle(gcn::Rectangle(4, 4,
- (int) (mProgress * (getWidth() - 8)),
- getHeight() - 8));
+ (int) (mProgress * (getWidth() - 8)),
+ getHeight() - 8));
}
// The label
if (!mText.empty())
{
- gcn::Font *f = boldFont;
const int textX = getWidth() / 2;
- const int textY = (getHeight() - f->getHeight()) / 2;
-
- graphics->setFont(f);
-
- graphics->setColor(gcn::Color(0, 0, 0, alpha));
- graphics->drawText(mText, textX + 1, textY, gcn::Graphics::CENTER);
- graphics->drawText(mText, textX, textY - 1, gcn::Graphics::CENTER);
- graphics->drawText(mText, textX, textY + 1, gcn::Graphics::CENTER);
- graphics->drawText(mText, textX - 1, textY, gcn::Graphics::CENTER);
-
- graphics->setColor(gcn::Color(255, 255, 255, alpha));
- graphics->drawText(mText, textX, textY, gcn::Graphics::CENTER);
+ const int textY = (getHeight() - boldFont->getHeight()) / 2;
- graphics->setColor(gcn::Color(0, 0, 0));
+ TextRenderer::renderText(graphics, mText, textX, textY,
+ gcn::Graphics::CENTER,
+ guiPalette->getColor(Palette::PROGRESS_BAR,
+ alpha), boldFont, true, false);
}
}
diff --git a/src/gui/progressbar.h b/src/gui/progressbar.h
index 49bc3edd..e75b1d44 100644
--- a/src/gui/progressbar.h
+++ b/src/gui/progressbar.h
@@ -124,10 +124,13 @@ class ProgressBar : public gcn::Widget
bool mSmoothColorChange;
std::string mText;
+ bool mUpdated;
static ImageRect mBorder;
static int mInstances;
static float mAlpha;
+
+ static const gcn::Color TEXT_COLOR;
};
#endif
diff --git a/src/gui/radiobutton.cpp b/src/gui/radiobutton.cpp
index c8ae2fad..52ceb837 100644
--- a/src/gui/radiobutton.cpp
+++ b/src/gui/radiobutton.cpp
@@ -69,6 +69,9 @@ RadioButton::~RadioButton()
void RadioButton::drawBox(gcn::Graphics* graphics)
{
+ if (!isVisible())
+ return;
+
if (config.getValue("guialpha", 0.8) != mAlpha)
{
mAlpha = config.getValue("guialpha", 0.8);
diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp
index a94af4cc..0536188c 100644
--- a/src/gui/recorder.cpp
+++ b/src/gui/recorder.cpp
@@ -40,9 +40,11 @@ Recorder::Recorder(ChatWindow *chat, const std::string &title,
mChat = chat;
Button *button = new Button(buttonTxt, "activate", this);
- setDefaultSize(0, windowContainer->getHeight() - 123 - button->getHeight() -
- offsetY, button->getWidth() + offsetX, button->getHeight() +
- offsetY);
+
+ // 123 is the default chat window height. If you change this in Chat, please
+ // change it here as well
+ setDefaultSize(button->getWidth() + offsetX, button->getHeight() +
+ offsetY, ImageRect::LOWER_LEFT, 0, 123);
place(0, 0, button);
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index 216ac211..5fb8b579 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -19,8 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "../configuration.h"
#include "../log.h"
#include "../logindata.h"
@@ -28,6 +26,7 @@
#include "button.h"
#include "checkbox.h"
+#include "label.h"
#include "login.h"
#include "ok_dialog.h"
#include "passwordfield.h"
@@ -49,23 +48,20 @@ void WrongDataNoticeListener::setTarget(gcn::TextField *textField)
void WrongDataNoticeListener::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok")
- {
mTarget->requestFocus();
- }
}
-
RegisterDialog::RegisterDialog(LoginData *loginData):
Window(_("Register")),
mWrongDataNoticeListener(new WrongDataNoticeListener),
mLoginData(loginData)
{
- gcn::Label *userLabel = new gcn::Label(_("Name:"));
- gcn::Label *passwordLabel = new gcn::Label(_("Password:"));
- gcn::Label *confirmLabel = new gcn::Label(_("Confirm:"));
+ gcn::Label *userLabel = new Label(_("Name:"));
+ gcn::Label *passwordLabel = new Label(_("Password:"));
+ gcn::Label *confirmLabel = new Label(_("Confirm:"));
#ifdef EATHENA_SUPPORT
- gcn::Label *serverLabel = new gcn::Label(_("Server:"));
- gcn::Label *portLabel = new gcn::Label(_("Port:"));
+ gcn::Label *serverLabel = new Label(_("Server:"));
+ gcn::Label *portLabel = new Label(_("Port:"));
#endif
mUserField = new TextField(loginData->username);
mPasswordField = new PasswordField(loginData->password);
@@ -131,7 +127,7 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
mPortField->addActionListener(this);
#endif
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mUserField->requestFocus();
mUserField->setCaretPosition(mUserField->getText().length());
diff --git a/src/gui/register.h b/src/gui/register.h
index fde82a40..c37305e4 100644
--- a/src/gui/register.h
+++ b/src/gui/register.h
@@ -37,7 +37,8 @@ class OkDialog;
* to the field which contained wrong data when the Ok button was pressed on
* the error notice.
*/
-class WrongDataNoticeListener : public gcn::ActionListener {
+class WrongDataNoticeListener : public gcn::ActionListener
+{
public:
void setTarget(gcn::TextField *textField);
void action(const gcn::ActionEvent &event);
diff --git a/src/gui/scrollarea.cpp b/src/gui/scrollarea.cpp
index 70504a03..44ef929b 100644
--- a/src/gui/scrollarea.cpp
+++ b/src/gui/scrollarea.cpp
@@ -145,6 +145,9 @@ void ScrollArea::init()
void ScrollArea::logic()
{
+ if (!isVisible())
+ return;
+
gcn::ScrollArea::logic();
gcn::Widget *content = getContent();
@@ -167,6 +170,9 @@ void ScrollArea::logic()
void ScrollArea::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
if (mVBarVisible)
{
drawUpButton(graphics);
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index cab88560..22f56195 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -19,9 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
+#include "label.h"
#include "scrollarea.h"
#include "sell.h"
#include "shop.h"
@@ -55,29 +54,36 @@ SellDialog::SellDialog(Network *network):
{
setWindowName("Sell");
setResizable(true);
+ setCloseButton(true);
setMinWidth(260);
setMinHeight(230);
- setDefaultSize(0, 0, 260, 230);
+ setDefaultSize(260, 230, ImageRect::CENTER);
- mShopItems = new ShopItems;
+ // Create a ShopItems instance, that is aware of duplicate entries.
+ mShopItems = new ShopItems(true);
mShopItemList = new ShopListBox(mShopItems, mShopItems);
mScrollArea = new ScrollArea(mShopItemList);
+ mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
mSlider = new Slider(1.0);
- mQuantityLabel = new gcn::Label("0");
- mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"),
- "", ""));
+
+ mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
+ mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
+ "", ""));
+
mIncreaseButton = new Button("+", "+", this);
mDecreaseButton = new Button("-", "-", this);
mSellButton = new Button(_("Sell"), "sell", this);
mQuitButton = new Button(_("Quit"), "quit", this);
- mItemDescLabel = new gcn::Label(strprintf(_("Description: %s"), ""));
- mItemEffectLabel = new gcn::Label(strprintf(_("Effect: %s"), ""));
+ mAddMaxButton = new Button(_("Max"), "max", this);
+ mItemDescLabel = new Label(strprintf(_("Description: %s"), ""));
+ mItemEffectLabel = new Label(strprintf(_("Effect: %s"), ""));
- mIncreaseButton->setSize(20, 20);
- mDecreaseButton->setSize(20, 20);
+ mDecreaseButton->adjustSize();
+ mDecreaseButton->setWidth(mIncreaseButton->getWidth());
- mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mIncreaseButton->setEnabled(false);
mDecreaseButton->setEnabled(false);
mSellButton->setEnabled(false);
@@ -88,21 +94,26 @@ SellDialog::SellDialog(Network *network):
mSlider->setActionEventId("slider");
mSlider->addActionListener(this);
- place(0, 0, mScrollArea, 5).setPadding(3);
- place(0, 1, mQuantityLabel, 2);
- place(2, 1, mSlider, 3);
- place(0, 2, mMoneyLabel, 5);
- place(0, 3, mItemEffectLabel, 5);
- place(0, 4, mItemDescLabel, 5);
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+
+ place(0, 0, mScrollArea, 8, 5).setPadding(3);
place(0, 5, mDecreaseButton);
- place(1, 5, mIncreaseButton);
- place(3, 5, mSellButton);
- place(4, 5, mQuitButton);
+ place(1, 5, mSlider, 3);
+ place(4, 5, mIncreaseButton);
+ place(5, 5, mQuantityLabel, 2);
+ place(7, 5, mAddMaxButton);
+ place(0, 6, mMoneyLabel, 8);
+ place(0, 7, mItemEffectLabel, 8);
+ place(0, 8, mItemDescLabel, 8);
+ place(6, 9, mSellButton);
+ place(7, 9, mQuitButton);
+
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
+ center();
loadWindowState();
- setLocationRelativeTo(getParent());
}
SellDialog::~SellDialog()
@@ -136,9 +147,8 @@ void SellDialog::addItem(const Item *item, int price)
if (!item)
return;
- mShopItems->addItem(
- item->getInvIndex(), item->getId(),
- item->getQuantity(), price);
+ mShopItems->addItem(item->getInvIndex(), item->getId(),
+ item->getQuantity(), price);
mShopItemList->adjustSize();
}
@@ -147,15 +157,14 @@ void SellDialog::addItem(const Item *item, int price)
void SellDialog::action(const gcn::ActionEvent &event)
{
- int selectedItem = mShopItemList->getSelected();
-
if (event.getId() == "quit")
{
- setVisible(false);
- if (current_npc) current_npc->handleDeath();
+ close();
return;
}
+ int selectedItem = mShopItemList->getSelected();
+
// The following actions require a valid item selection
if (selectedItem == -1 ||
selectedItem >= (int) mShopItems->getNumberOfElements())
@@ -180,6 +189,12 @@ void SellDialog::action(const gcn::ActionEvent &event)
mSlider->setValue(mAmountItems);
updateButtonsAndLabels();
}
+ else if (event.getId() == "max")
+ {
+ mAmountItems = mMaxItems;
+ mSlider->setValue(mAmountItems);
+ updateButtonsAndLabels();
+ }
else if (event.getId() == "sell" && mAmountItems > 0
&& mAmountItems <= mMaxItems)
{
@@ -189,24 +204,35 @@ void SellDialog::action(const gcn::ActionEvent &event)
#else
// Attempt sell
MessageOut outMsg(mNetwork);
- outMsg.writeInt16(CMSG_NPC_SELL_REQUEST);
- outMsg.writeInt16(8);
- outMsg.writeInt16(mShopItems->at(selectedItem)->getInvIndex());
- outMsg.writeInt16(mAmountItems);
-#endif
+ ShopItem* item = mShopItems->at(selectedItem);
+ int sellCount;
+ mPlayerMoney +=
+ mAmountItems * mShopItems->at(selectedItem)->getPrice();
mMaxItems -= mAmountItems;
- mShopItems->getShop()->at(selectedItem)->setQuantity(mMaxItems);
+ while (mAmountItems > 0) {
+ outMsg.writeInt16(CMSG_NPC_SELL_REQUEST);
+ outMsg.writeInt16(8);
+ outMsg.writeInt16(item->getCurrentInvIndex());
+ // This order is important, item->getCurrentInvIndex() would return
+ // the inventory index of the next Duplicate otherwise.
+ sellCount = item->sellCurrentDuplicate(mAmountItems);
+ mAmountItems -= sellCount;
+ outMsg.writeInt16(sellCount);
+ }
+#endif
+
mPlayerMoney +=
mAmountItems * mShopItems->at(selectedItem)->getPrice();
mAmountItems = 1;
+ mSlider->setValue(0);
if (!mMaxItems)
{
// All were sold
mShopItemList->setSelected(-1);
- mShopItems->getShop()->erase(
- mShopItems->getShop()->begin() + selectedItem);
+ delete mShopItems->at(selectedItem);
+ mShopItems->erase(selectedItem);
gcn::Rectangle scroll;
scroll.y = mShopItemList->getRowHeight() * (selectedItem + 1);
@@ -278,5 +304,26 @@ void SellDialog::updateButtonsAndLabels()
mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"),
Units::formatCurrency(income).c_str(),
- Units::formatCurrency(mPlayerMoney - income).c_str()));
+ Units::formatCurrency(mPlayerMoney + income).c_str()));
+}
+
+void SellDialog::logic()
+{
+ Window::logic();
+
+ if (!current_npc) setVisible(false);
+}
+
+void SellDialog::setVisible(bool visible)
+{
+ Window::setVisible(visible);
+
+ if (visible)
+ requestFocus();
+}
+
+void SellDialog::close()
+{
+ setVisible(false);
+ current_npc = 0;
}
diff --git a/src/gui/sell.h b/src/gui/sell.h
index f64a6fd5..b6388a1f 100644
--- a/src/gui/sell.h
+++ b/src/gui/sell.h
@@ -91,6 +91,20 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
*/
void setMoney(int amount);
+ /**
+ * Check for current NPC
+ */
+ void logic();
+
+ /**
+ * Sets the visibility of this window.
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Closes the Buy Window, as well as resetting the current npc.
+ */
+ void close();
private:
/**
* Updates the state of buttons and labels.
@@ -102,6 +116,7 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
#endif
gcn::Button *mSellButton;
gcn::Button *mQuitButton;
+ gcn::Button *mAddMaxButton;
gcn::Button *mIncreaseButton;
gcn::Button *mDecreaseButton;
ShopListBox *mShopItemList;
@@ -119,4 +134,6 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
int mAmountItems;
};
+extern SellDialog *sellDialog;
+
#endif
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index c8b7f900..72dfbce5 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -34,19 +34,27 @@
#include "../utils/gettext.h"
extern Window *chatWindow;
-extern Window *equipmentWindow;
-extern Window *helpWindow;
+extern Window *statusWindow;
+extern Window *buyDialog;
+extern Window *sellDialog;
+extern Window *buySellDialog;
extern Window *inventoryWindow;
-extern Window *minimap;
+extern Window *emoteWindow;
+extern Window *npcTextDialog;
+extern Window *npcStringDialog;
extern Window *skillDialog;
-extern Window *statusWindow;
+extern Window *minimap;
+extern Window *equipmentWindow;
+extern Window *tradeWindow;
+extern Window *helpWindow;
+extern Window *debugWindow;
extern Window *itemShortcutWindow;
extern Window *emoteShortcutWindow;
-extern Window *emoteWindow;
-extern Window *tradeWindow;
#ifdef TMWSERV_SUPPORT
extern Window *magicDialog;
extern Window *guildWindow;
+#else
+extern Window *storageWindow;
#endif
Setup::Setup():
@@ -68,9 +76,9 @@ Setup::Setup():
btn->setPosition(x, height - btn->getHeight() - 5);
add(btn);
- // Disable this button when the windows aren't created yet
+ // Store this button, as it needs to be enabled/disabled
if (!strcmp(*curBtn, "Reset Windows"))
- btn->setEnabled(statusWindow != NULL);
+ mResetWindows = btn;
}
TabbedArea *panel = new TabbedArea;
@@ -104,7 +112,9 @@ Setup::Setup():
add(panel);
- setLocationRelativeTo(getParent());
+ center();
+
+ setInGame(false);
}
Setup::~Setup()
@@ -131,20 +141,37 @@ void Setup::action(const gcn::ActionEvent &event)
if (!statusWindow)
return;
- statusWindow->resetToDefaultSize();
- minimap->resetToDefaultSize();
chatWindow->resetToDefaultSize();
+ statusWindow->resetToDefaultSize();
+ buyDialog->resetToDefaultSize();
+ sellDialog->resetToDefaultSize();
+#ifdef EATHENA_SUPPORT
+ buySellDialog->resetToDefaultSize();
+#endif
inventoryWindow->resetToDefaultSize();
+ emoteWindow->resetToDefaultSize();
+ npcTextDialog->resetToDefaultSize();
+ npcStringDialog->resetToDefaultSize();
+ skillDialog->resetToDefaultSize();
+ minimap->resetToDefaultSize();
equipmentWindow->resetToDefaultSize();
+ tradeWindow->resetToDefaultSize();
helpWindow->resetToDefaultSize();
- skillDialog->resetToDefaultSize();
+ debugWindow->resetToDefaultSize();
itemShortcutWindow->resetToDefaultSize();
emoteShortcutWindow->resetToDefaultSize();
- emoteWindow->resetToDefaultSize();
- tradeWindow->resetToDefaultSize();
#ifdef TMWSERV_SUPPORT
magicDialog->resetToDefaultSize();
guildWindow->resetToDefaultSize();
+#else
+ storageWindow->resetToDefaultSize();
#endif
}
}
+
+void Setup::setInGame(bool inGame)
+{
+ mResetWindows->setEnabled(inGame);
+}
+
+Setup* setupWindow;
diff --git a/src/gui/setup.h b/src/gui/setup.h
index e4eb0902..4c387d34 100644
--- a/src/gui/setup.h
+++ b/src/gui/setup.h
@@ -55,8 +55,16 @@ class Setup : public Window, public gcn::ActionListener
*/
void action(const gcn::ActionEvent &event);
+ /**
+ * Enables the reset button when in game.
+ */
+ void setInGame(bool inGame);
+
private:
std::list<SetupTab*> mTabs;
+ gcn::Button *mResetWindows;
};
+extern Setup* setupWindow;
+
#endif
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
index 43cc28e6..28a80b3d 100644
--- a/src/gui/setup_audio.cpp
+++ b/src/gui/setup_audio.cpp
@@ -19,9 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "checkbox.h"
+#include "label.h"
#include "ok_dialog.h"
#include "setup_audio.h"
#include "slider.h"
@@ -45,8 +44,8 @@ Setup_Audio::Setup_Audio():
setOpaque(false);
setDimension(gcn::Rectangle(0, 0, 250, 200));
- gcn::Label *sfxLabel = new gcn::Label(_("Sfx volume"));
- gcn::Label *musicLabel = new gcn::Label(_("Music volume"));
+ gcn::Label *sfxLabel = new Label(_("Sfx volume"));
+ gcn::Label *musicLabel = new Label(_("Music volume"));
mSfxSlider->setActionEventId("sfx");
mMusicSlider->setActionEventId("music");
@@ -80,7 +79,8 @@ void Setup_Audio::apply()
if (mSoundCheckBox->isSelected())
{
config.setValue("sound", 1);
- try {
+ try
+ {
sound.init();
}
catch (const char *err)
diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp
index 49c99996..033ba372 100644
--- a/src/gui/setup_colors.cpp
+++ b/src/gui/setup_colors.cpp
@@ -23,13 +23,14 @@
#include <cmath>
#include <guichan/listmodel.hpp>
-#include <guichan/widgets/label.hpp>
#include <guichan/widgets/slider.hpp>
#include "browserbox.h"
-#include "color.h"
+#include "gui.h"
#include "itemlinkhandler.h"
+#include "label.h"
#include "listbox.h"
+#include "palette.h"
#include "scrollarea.h"
#include "setup_colors.h"
#include "slider.h"
@@ -42,71 +43,91 @@
#include "../utils/gettext.h"
#include "../utils/stringutils.h"
+const std::string Setup_Colors::rawmsg = _("This is what the color looks like");
+
Setup_Colors::Setup_Colors() :
mSelected(-1)
{
setOpaque(false);
- mColorBox = new ListBox(textColor);
+ mColorBox = new ListBox(guiPalette);
mColorBox->setActionEventId("color_box");
mColorBox->addActionListener(this);
mScroll = new ScrollArea(mColorBox);
mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mTextPreview = new TextPreview(&rawmsg);
+
mPreview = new BrowserBox(BrowserBox::AUTO_WRAP);
mPreview->setOpaque(false);
- // Replace this later with a more appropriate link handler. For now, this'll
- // do, as it'll do nothing when clicked on.
- mPreview->setLinkHandler(new ItemLinkHandler);
+ // don't do anything with links
+ mPreview->setLinkHandler(NULL);
mPreviewBox = new ScrollArea(mPreview);
mPreviewBox->setHeight(20);
mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
gcn::ScrollArea::SHOW_NEVER);
- mRedLabel = new gcn::Label(_("Red: "));
+ mGradTypeLabel = new Label(_("Type: "));
+
+ mGradTypeSlider = new Slider(0, 3);
+ mGradTypeSlider->setWidth(160);
+ mGradTypeSlider->setActionEventId("slider_grad");
+ mGradTypeSlider->setValue(0);
+ mGradTypeSlider->addActionListener(this);
+ mGradTypeSlider->setEnabled(false);
+
+ mGradTypeText = new Label();
+
+ mRedLabel = new Label(_("Red: "));
mRedText = new TextField;
mRedText->setWidth(40);
mRedText->setRange(0, 255);
mRedText->setNumeric(true);
mRedText->addListener(this);
+ mRedText->setEnabled(false);
mRedSlider = new Slider(0, 255);
mRedSlider->setWidth(160);
mRedSlider->setValue(mRedText->getValue());
mRedSlider->setActionEventId("slider_red");
mRedSlider->addActionListener(this);
+ mRedSlider->setEnabled(false);
- mGreenLabel = new gcn::Label(_("Green: "));
+ mGreenLabel = new Label(_("Green: "));
mGreenText = new TextField;
mGreenText->setWidth(40);
mGreenText->setRange(0, 255);
mGreenText->setNumeric(true);
mGreenText->addListener(this);
+ mGreenText->setEnabled(false);
mGreenSlider = new Slider(0, 255);
mGreenSlider->setWidth(160);
mGreenSlider->setValue(mGreenText->getValue());
mGreenSlider->setActionEventId("slider_green");
mGreenSlider->addActionListener(this);
+ mGreenSlider->setEnabled(false);
- mBlueLabel = new gcn::Label(_("Blue: "));
+ mBlueLabel = new Label(_("Blue: "));
mBlueText = new TextField;
mBlueText->setWidth(40);
mBlueText->setRange(0, 255);
mBlueText->setNumeric(true);
mBlueText->addListener(this);
+ mBlueText->setEnabled(false);
mBlueSlider = new Slider(0, 255);
mBlueSlider->setWidth(160);
mBlueSlider->setValue(mBlueText->getValue());
mBlueSlider->setActionEventId("slider_blue");
mBlueSlider->addActionListener(this);
+ mBlueSlider->setEnabled(false);
setOpaque(false);
@@ -114,8 +135,11 @@ Setup_Colors::Setup_Colors() :
LayoutHelper h(this);
ContainerPlacer place = h.getPlacer(0, 0);
- place(0, 0, mScroll, 4, 7).setPadding(2);
- place(0, 7, mPreviewBox, 4).setPadding(2);
+ place(0, 0, mScroll, 4, 6).setPadding(2);
+ place(0, 6, mPreviewBox, 4).setPadding(2);
+ place(0, 7, mGradTypeLabel, 2);
+ place(2, 7, mGradTypeSlider);
+ place(3, 7, mGradTypeText);
place(0, 8, mRedLabel, 2);
place(2, 8, mRedSlider);
place(3, 8, mRedText).setPadding(1);
@@ -131,19 +155,10 @@ Setup_Colors::Setup_Colors() :
Setup_Colors::~Setup_Colors()
{
- delete mRedLabel;
- delete mRedSlider;
- delete mRedText;
-
- delete mGreenLabel;
- delete mGreenSlider;
- delete mGreenText;
-
- delete mBlueLabel;
- delete mBlueSlider;
- delete mBlueText;
-
- delete mScroll;
+ if (mPreviewBox->getContent() == mPreview)
+ delete mTextPreview;
+ else
+ delete mPreview;
}
void Setup_Colors::action(const gcn::ActionEvent &event)
@@ -151,22 +166,140 @@ void Setup_Colors::action(const gcn::ActionEvent &event)
if (event.getId() == "color_box")
{
mSelected = mColorBox->getSelected();
- int col = textColor->getColorAt(mSelected);
- char ch = textColor->getColorCharAt(mSelected);
- std::string msg;
+ Palette::ColorType type = guiPalette->getColorTypeAt(mSelected);
+ const gcn::Color *col = &guiPalette->getColor(type);
+ Palette::GradientType grad = guiPalette->getGradientType(type);
- if (ch == '<')
- msg = toString("@@|") +
- _("This is what the color looks like") + "@@";
- else
- msg = "##" + toString(ch) +
- _("This is what the color looks like");
+ std::string msg;
+ char ch = guiPalette->getColorChar(type);
mPreview->clearRows();
- mPreview->addRow(msg);
- setEntry(mRedSlider, mRedText, col >> 16);
- setEntry(mGreenSlider, mGreenText, (col >> 8) & 0xff);
- setEntry(mBlueSlider, mBlueText, col & 0xff);
+ mPreviewBox->setContent(mTextPreview);
+ mTextPreview->setFont(gui->getFont());
+ mTextPreview->setTextColor(&guiPalette->getColor(Palette::TEXT));
+ mTextPreview->setTextBGColor(NULL);
+ mTextPreview->setOpaque(false);
+ mTextPreview->setShadow(true);
+ mTextPreview->setOutline(true);
+ mTextPreview->useTextAlpha(false);
+
+ switch (type)
+ {
+ case Palette::TEXT:
+ case Palette::SHADOW:
+ case Palette::OUTLINE:
+ mTextPreview->setFont(gui->getFont());
+ mTextPreview->setShadow(type == Palette::SHADOW);
+ mTextPreview->setOutline(type == Palette::OUTLINE);
+ break;
+ case Palette::PROGRESS_BAR:
+ mTextPreview->useTextAlpha(true);
+ mTextPreview->setFont(boldFont);
+ mTextPreview->setTextColor(col);
+ mTextPreview->setOutline(true);
+ mTextPreview->setShadow(false);
+ break;
+ case Palette::TAB_HIGHLIGHT:
+ mTextPreview->setFont(gui->getFont());
+ mTextPreview->setTextColor(col);
+ mTextPreview->setOutline(false);
+ mTextPreview->setShadow(false);
+ break;
+ case Palette::BACKGROUND:
+ case Palette::SHOP_WARNING:
+ mTextPreview->setBGColor(col);
+ mTextPreview->setOpaque(true);
+ mTextPreview->setOutline(false);
+ mTextPreview->setShadow(false);
+ break;
+ case Palette::HIGHLIGHT:
+ mTextPreview->setTextBGColor(col);
+ mTextPreview->setOutline(false);
+ mTextPreview->setShadow(false);
+ mPreview->addRow(rawmsg);
+ break;
+ case Palette::CHAT:
+ case Palette::GM:
+ case Palette::PLAYER:
+ case Palette::WHISPER:
+ case Palette::IS:
+ case Palette::PARTY:
+ case Palette::SERVER:
+ case Palette::LOGGER:
+ case Palette::HYPERLINK:
+ mPreviewBox->setContent(mPreview);
+ mPreview->clearRows();
+
+ if (ch == '<')
+ msg = toString("@@|") + rawmsg + "@@";
+ else
+ msg = "##" + toString(ch) + rawmsg;
+
+ mPreview->addRow(msg);
+ break;
+ case Palette::UNKNOWN_ITEM:
+ case Palette::GENERIC:
+ case Palette::HEAD:
+ case Palette::USABLE:
+ case Palette::TORSO:
+ case Palette::ONEHAND:
+ case Palette::LEGS:
+ case Palette::FEET:
+ case Palette::TWOHAND:
+ case Palette::SHIELD:
+ case Palette::RING:
+ case Palette::ARMS:
+ case Palette::AMMO:
+ mTextPreview->setFont(boldFont);
+ mTextPreview->setTextColor(col);
+ mTextPreview->setOutline(false);
+ mTextPreview->setShadow(false);
+ break;
+ case Palette::PARTICLE:
+ case Palette::EXP_INFO:
+ case Palette::PICKUP_INFO:
+ case Palette::HIT_PLAYER_MONSTER:
+ case Palette::HIT_MONSTER_PLAYER:
+ case Palette::HIT_CRITICAL:
+ case Palette::MISS:
+ mTextPreview->setShadow(false);
+ case Palette::BEING:
+ case Palette::PC:
+ case Palette::SELF:
+ case Palette::GM_NAME:
+ case Palette::NPC:
+ case Palette::MONSTER:
+ mTextPreview->setFont(boldFont);
+ mTextPreview->setTextColor(col);
+ case Palette::TYPE_COUNT:
+ break;
+ }
+
+ if (grad != Palette::STATIC && grad != Palette::PULSE)
+ { // If nonstatic color, don't display the current, but the committed
+ // color at the sliders
+ col = &guiPalette->getCommittedColor(type);
+ }
+ else if (grad == Palette::PULSE)
+ {
+ col = &guiPalette->getTestColor(type);
+ }
+
+ setEntry(mRedSlider, mRedText, col->r);
+ setEntry(mGreenSlider, mGreenText, col->g);
+ setEntry(mBlueSlider, mBlueText, col->b);
+
+ mGradTypeSlider->setValue(grad);
+ updateGradType();
+ mGradTypeSlider->setEnabled(true);
+
+ return;
+ }
+
+ if (event.getId() == "slider_grad")
+ {
+ updateGradType();
+ updateColor();
return;
}
@@ -202,16 +335,18 @@ void Setup_Colors::setEntry(gcn::Slider *s, TextField *t, int value)
void Setup_Colors::apply()
{
- textColor->commit();
+ guiPalette->commit();
}
void Setup_Colors::cancel()
{
- textColor->rollback();
- int col = textColor->getColorAt(mSelected);
- setEntry(mRedSlider, mRedText, col >> 16);
- setEntry(mGreenSlider, mGreenText, (col >> 8) & 0xff);
- setEntry(mBlueSlider, mBlueText, col & 0xff);
+ guiPalette->rollback();
+ Palette::ColorType type = guiPalette->getColorTypeAt(mSelected);
+ const gcn::Color *col = &guiPalette->getColor(type);
+ mGradTypeSlider->setValue(guiPalette->getGradientType(type));
+ setEntry(mRedSlider, mRedText, col->r);
+ setEntry(mGreenSlider, mGreenText, col->g);
+ setEntry(mBlueSlider, mBlueText, col->b);
}
void Setup_Colors::listen(const TextField *tf)
@@ -236,14 +371,51 @@ void Setup_Colors::listen(const TextField *tf)
}
}
+void Setup_Colors::updateGradType()
+{
+ if (mSelected == -1)
+ return;
+
+ mSelected = mColorBox->getSelected();
+ Palette::ColorType type = guiPalette->getColorTypeAt(mSelected);
+ Palette::GradientType grad = guiPalette->getGradientType(type);
+
+ mGradTypeText->setCaption(
+ (grad == Palette::STATIC) ? _("Static") :
+ (grad == Palette::PULSE) ? _("Pulse") :
+ (grad == Palette::RAINBOW) ? _("Rainbow") : _("Spectrum"));
+
+ bool enable = (grad == Palette::STATIC || grad == Palette::PULSE);
+ mRedText->setEnabled(enable);
+ mRedSlider->setEnabled(enable);
+ mGreenText->setEnabled(enable);
+ mGreenSlider->setEnabled(enable);
+ mBlueText->setEnabled(enable);
+ mBlueSlider->setEnabled(enable);
+}
+
void Setup_Colors::updateColor()
{
if (mSelected == -1)
- {
return;
+
+ Palette::ColorType type = guiPalette->getColorTypeAt(mSelected);
+ Palette::GradientType grad =
+ static_cast<Palette::GradientType>(mGradTypeSlider->getValue());
+ guiPalette->setGradient(type, grad);
+
+ if (grad == Palette::STATIC)
+ {
+ guiPalette->setColor(type,
+ static_cast<int>(mRedSlider->getValue()),
+ static_cast<int>(mGreenSlider->getValue()),
+ static_cast<int>(mBlueSlider->getValue()));
+ }
+ else if (grad == Palette::PULSE)
+ {
+ guiPalette->setTestColor(type, gcn::Color(
+ static_cast<int>(mRedSlider->getValue()),
+ static_cast<int>(mGreenSlider->getValue()),
+ static_cast<int>(mBlueSlider->getValue())));
}
- int rgb = static_cast<int>(mRedSlider->getValue()) << 16 |
- static_cast<int>(mGreenSlider->getValue()) << 8 |
- static_cast<int>(mBlueSlider->getValue());
- textColor->setColorAt(mSelected, rgb);
}
diff --git a/src/gui/setup_colors.h b/src/gui/setup_colors.h
index 2831297f..52d3f727 100644
--- a/src/gui/setup_colors.h
+++ b/src/gui/setup_colors.h
@@ -34,6 +34,8 @@
#include "../guichanfwd.h"
+#include "widgets/textpreview.h"
+
class BrowserBox;
class Setup_Colors : public SetupTab, public gcn::ActionListener,
@@ -48,12 +50,19 @@ class Setup_Colors : public SetupTab, public gcn::ActionListener,
void listen(const TextField *tf);
private:
+ static const std::string rawmsg;
+
gcn::ListBox *mColorBox;
gcn::ScrollArea *mScroll;
BrowserBox *mPreview;
+ TextPreview *mTextPreview;
gcn::ScrollArea *mPreviewBox;
int mSelected;
+ gcn::Label *mGradTypeLabel;
+ gcn::Slider *mGradTypeSlider;
+ gcn::Label *mGradTypeText;
+
gcn::Label *mRedLabel;
gcn::Slider *mRedSlider;
TextField *mRedText;
@@ -71,5 +80,6 @@ class Setup_Colors : public SetupTab, public gcn::ActionListener,
void setEntry(gcn::Slider *s, TextField *t, int value);
void updateColor();
+ void updateGradType();
};
#endif
diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp
index c0c04949..59a882c7 100644
--- a/src/gui/setup_joystick.cpp
+++ b/src/gui/setup_joystick.cpp
@@ -19,10 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "checkbox.h"
+#include "label.h"
#include "setup_joystick.h"
#include "widgets/layouthelper.h"
@@ -35,7 +34,7 @@
extern Joystick *joystick;
Setup_Joystick::Setup_Joystick():
- mCalibrateLabel(new gcn::Label(_("Press the button to start calibration"))),
+ mCalibrateLabel(new Label(_("Press the button to start calibration"))),
mCalibrateButton(new Button(_("Calibrate"), "calibrate", this)),
mJoystickEnabled(new CheckBox(_("Enable joystick")))
{
diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp
index 96792436..1451e71e 100644
--- a/src/gui/setup_players.cpp
+++ b/src/gui/setup_players.cpp
@@ -22,10 +22,9 @@
#include <string>
#include <vector>
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
#include "checkbox.h"
+#include "label.h"
#include "listbox.h"
#include "ok_dialog.h"
#include "scrollarea.h"
@@ -137,7 +136,7 @@ public:
for (unsigned int r = 0; r < player_names->size(); ++r)
{
std::string name = (*player_names)[r];
- gcn::Widget *widget = new gcn::Label(name);
+ gcn::Widget *widget = new Label(name);
mWidgets.push_back(widget);
gcn::ListModel *playerRelation = new PlayerRelationListModel;
@@ -247,7 +246,7 @@ Setup_Players::Setup_Players():
for (int i = 0; i < COLUMNS_NR; i++)
{
mPlayerTableTitleModel->set(0, i,
- new gcn::Label(gettext(table_titles[i])));
+ new Label(gettext(table_titles[i])));
}
mPlayerTitleTable->setLinewiseSelection(true);
@@ -257,7 +256,7 @@ Setup_Players::Setup_Players():
mPlayerTable->setLinewiseSelection(true);
mPlayerTable->addActionListener(this);
- gcn::Label *ignore_action_label = new gcn::Label(_("When ignoring:"));
+ gcn::Label *ignore_action_label = new Label(_("When ignoring:"));
mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY);
mIgnoreActionChoicesBox->addActionListener(this);
@@ -329,7 +328,7 @@ void Setup_Players::apply()
~(PlayerRelation::TRADE |
PlayerRelation::WHISPER);
player_relations.setDefault(old_default_relations
- | (mDefaultTrading->isSelected() ?
+ | (mDefaultTrading->isSelected() ?
PlayerRelation::TRADE : 0)
| (mDefaultWhisper->isSelected() ?
PlayerRelation::WHISPER : 0));
@@ -341,7 +340,7 @@ void Setup_Players::cancel()
void Setup_Players::action(const gcn::ActionEvent &event)
{
- if (event.getId() == ACTION_TABLE)
+ if (event.getId() == ACTION_TABLE)
{
// temporarily eliminate ourselves: we are fully aware of this change,
// so there is no need for asynchronous updates. (In fact, thouse
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index 526c67ce..07f073db 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -26,9 +26,8 @@
#include <guichan/key.hpp>
#include <guichan/listmodel.hpp>
-#include <guichan/widgets/label.hpp>
-
#include "checkbox.h"
+#include "label.h"
#include "listbox.h"
#include "ok_dialog.h"
#include "scrollarea.h"
@@ -88,13 +87,15 @@ ModeListModel::ModeListModel()
SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
/* Check which modes are available */
- if (modes == (SDL_Rect **)0) {
+ if (modes == (SDL_Rect **)0)
logger->log("No modes available");
- } else if (modes == (SDL_Rect **)-1) {
+ else if (modes == (SDL_Rect **)-1)
logger->log("All resolutions available");
- } else {
+ else
+ {
//logger->log("Available Modes");
- for (int i = 0; modes[i]; ++i) {
+ for (int i = 0; modes[i]; ++i)
+ {
const std::string modeString =
toString((int)modes[i]->w) + "x" + toString((int)modes[i]->h);
//logger->log(modeString.c_str());
@@ -110,6 +111,8 @@ Setup_Video::Setup_Video():
mVisibleNamesEnabled(config.getValue("visiblenames", 1)),
mParticleEffectsEnabled(config.getValue("particleeffects", true)),
mNameEnabled(config.getValue("showownname", false)),
+ mPickupChatEnabled(config.getValue("showpickupchat", true)),
+ mPickupParticleEnabled(config.getValue("showpickupparticle", false)),
mOpacity(config.getValue("guialpha", 0.8)),
mFps((int) config.getValue("fpslimit", 0)),
mSpeechMode((int) config.getValue("speech", 3)),
@@ -121,11 +124,15 @@ Setup_Video::Setup_Video():
mVisibleNamesCheckBox(new CheckBox(_("Visible names"), mVisibleNamesEnabled)),
mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)),
mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)),
+ mPickupNotifyLabel(new Label(_("Show pickup notification"))),
+ mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)),
+ mPickupParticleCheckBox(new CheckBox(_("as particle"),
+ mPickupParticleEnabled)),
mSpeechSlider(new Slider(0, 3)),
- mSpeechLabel(new gcn::Label("")),
+ mSpeechLabel(new Label("")),
mAlphaSlider(new Slider(0.2, 1.0)),
mFpsCheckBox(new CheckBox(_("FPS Limit:"))),
- mFpsSlider(new Slider(10, 200)),
+ mFpsSlider(new Slider(10, 120)),
mFpsField(new TextField),
mOriginalScrollLaziness((int) config.getValue("ScrollLaziness", 16)),
mScrollLazinessSlider(new Slider(1, 64)),
@@ -135,22 +142,22 @@ Setup_Video::Setup_Video():
mScrollRadiusField(new TextField),
mOverlayDetail((int) config.getValue("OverlayDetail", 2)),
mOverlayDetailSlider(new Slider(0, 2)),
- mOverlayDetailField(new gcn::Label("")),
+ mOverlayDetailField(new Label("")),
mParticleDetail(3 - (int) config.getValue("particleEmitterSkip", 1)),
mParticleDetailSlider(new Slider(0, 3)),
- mParticleDetailField(new gcn::Label(""))
+ mParticleDetailField(new Label(""))
{
setOpaque(false);
ScrollArea *scrollArea = new ScrollArea(mModeList);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
- speechLabel = new gcn::Label(_("Overhead text"));
- alphaLabel = new gcn::Label(_("Gui opacity"));
- scrollRadiusLabel = new gcn::Label(_("Scroll radius"));
- scrollLazinessLabel = new gcn::Label(_("Scroll laziness"));
- overlayDetailLabel = new gcn::Label(_("Ambient FX"));
- particleDetailLabel = new gcn::Label(_("Particle Detail"));
+ speechLabel = new Label(_("Overhead text"));
+ alphaLabel = new Label(_("Gui opacity"));
+ scrollRadiusLabel = new Label(_("Scroll radius"));
+ scrollLazinessLabel = new Label(_("Scroll laziness"));
+ overlayDetailLabel = new Label(_("Ambient FX"));
+ particleDetailLabel = new Label(_("Particle Detail"));
mModeList->setEnabled(true);
#ifndef USE_OPENGL
@@ -172,6 +179,8 @@ Setup_Video::Setup_Video():
mCustomCursorCheckBox->setActionEventId("customcursor");
mVisibleNamesCheckBox->setActionEventId("visiblenames");
mParticleEffectsCheckBox->setActionEventId("particleeffects");
+ mPickupChatCheckBox->setActionEventId("pickupchat");
+ mPickupParticleCheckBox->setActionEventId("pickupparticle");
mNameCheckBox->setActionEventId("showownname");
mAlphaSlider->setActionEventId("guialpha");
mFpsCheckBox->setActionEventId("fpslimitcheckbox");
@@ -190,6 +199,8 @@ Setup_Video::Setup_Video():
mCustomCursorCheckBox->addActionListener(this);
mVisibleNamesCheckBox->addActionListener(this);
mParticleEffectsCheckBox->addActionListener(this);
+ mPickupChatCheckBox->addActionListener(this);
+ mPickupParticleCheckBox->addActionListener(this);
mNameCheckBox->addActionListener(this);
mAlphaSlider->addActionListener(this);
mFpsCheckBox->addActionListener(this);
@@ -264,12 +275,15 @@ Setup_Video::Setup_Video():
ContainerPlacer place = h.getPlacer(0, 0);
place(0, 0, scrollArea, 1, 6).setPadding(2);
- place(1, 0, mFsCheckBox, 3);
- place(1, 1, mOpenGLCheckBox, 3);
- place(1, 2, mCustomCursorCheckBox, 3);
- place(1, 3, mVisibleNamesCheckBox, 3);
- place(1, 4, mNameCheckBox, 3);
- place(1, 5, mParticleEffectsCheckBox, 3);
+ place(1, 0, mFsCheckBox, 2);
+ place(3, 0, mOpenGLCheckBox, 1);
+ place(1, 1, mCustomCursorCheckBox, 3);
+ place(1, 2, mVisibleNamesCheckBox, 3);
+ place(3, 2, mNameCheckBox, 1);
+ place(1, 3, mParticleEffectsCheckBox, 3);
+ place(1, 4, mPickupNotifyLabel, 3);
+ place(1, 5, mPickupChatCheckBox, 1);
+ place(2, 5, mPickupParticleCheckBox, 2);
place(0, 6, mAlphaSlider);
place(0, 7, mFpsSlider);
@@ -279,7 +293,7 @@ Setup_Video::Setup_Video():
place(0, 11, mOverlayDetailSlider);
place(0, 12, mParticleDetailSlider);
- place(1, 6, alphaLabel, 2);
+ place(1, 6, alphaLabel, 3);
place(1, 7, mFpsCheckBox).setPadding(3);
place(1, 8, scrollRadiusLabel);
place(1, 9, scrollLazinessLabel);
@@ -290,9 +304,9 @@ Setup_Video::Setup_Video():
place(2, 7, mFpsField).setPadding(1);
place(2, 8, mScrollRadiusField).setPadding(1);
place(2, 9, mScrollLazinessField).setPadding(1);
- place(2, 10, mSpeechLabel, 2).setPadding(2);
- place(2, 11, mOverlayDetailField, 2).setPadding(2);
- place(2, 12, mParticleDetailField, 2).setPadding(2);
+ place(2, 10, mSpeechLabel, 3).setPadding(2);
+ place(2, 11, mOverlayDetailField, 3).setPadding(2);
+ place(2, 12, mParticleDetailField, 3).setPadding(2);
setDimension(gcn::Rectangle(0, 0, 325, 280));
}
@@ -329,9 +343,11 @@ void Setup_Video::apply()
}
}
#if defined(WIN32) || defined(__APPLE__)
- } else {
+ }
+ else
+ {
new OkDialog(_("Switching to full screen"),
- _("Restart needed for changes to take effect."));
+ _("Restart needed for changes to take effect."));
}
#endif
config.setValue("screen", fullscreen ? true : false);
@@ -344,7 +360,7 @@ void Setup_Video::apply()
// OpenGL can currently only be changed by restarting, notify user.
new OkDialog(_("Changing OpenGL"),
- _("Applying change to OpenGL requires restart."));
+ _("Applying change to OpenGL requires restart."));
}
// FPS change
@@ -360,6 +376,8 @@ void Setup_Video::apply()
mOpacity = config.getValue("guialpha", 0.8);
mOverlayDetail = (int) config.getValue("OverlayDetail", 2);
mOpenGLEnabled = config.getValue("opengl", false);
+ mPickupChatEnabled = config.getValue("showpickupchat", true);
+ mPickupParticleEnabled = config.getValue("showpickupparticle", false);
}
int Setup_Video::updateSlider(gcn::Slider *slider, gcn::TextField *field,
@@ -406,8 +424,13 @@ void Setup_Video::cancel()
config.setValue("particleeffects", mParticleEffectsEnabled ? true : false);
config.setValue("speech", mSpeechMode);
config.setValue("showownname", mNameEnabled ? true : false);
+ if (player_node)
+ player_node->mUpdateName = true;
config.setValue("guialpha", mOpacity);
config.setValue("opengl", mOpenGLEnabled ? true : false);
+ config.setValue("showpickupchat", mPickupChatEnabled ? true : false);
+ config.setValue("showpickupparticle", mPickupParticleEnabled ?
+ true : false);
}
void Setup_Video::action(const gcn::ActionEvent &event)
@@ -443,8 +466,19 @@ void Setup_Video::action(const gcn::ActionEvent &event)
{
config.setValue("particleeffects",
mParticleEffectsCheckBox->isSelected() ? true : false);
- new OkDialog(_("Particle effect settings changed"),
- _("Restart your client or change maps for the change to take effect."));
+ new OkDialog(_("Particle effect settings changed."),
+ _("Restart your client or change maps "
+ "for the change to take effect."));
+ }
+ else if (event.getId() == "pickupchat")
+ {
+ config.setValue("showpickupchat", mPickupChatCheckBox->isSelected()
+ ? true : false);
+ }
+ else if (event.getId() == "pickupparticle")
+ {
+ config.setValue("showpickupparticle",
+ mPickupParticleCheckBox->isSelected() ? true : false);
}
else if (event.getId() == "speech")
{
@@ -558,9 +592,9 @@ void Setup_Video::keyPressed(gcn::KeyEvent &event)
{
mFps = 10;
}
- else if (mFps > 200)
+ else if (mFps > 120)
{
- mFps = 200;
+ mFps = 120;
}
mFpsField->setText(toString(mFps));
mFpsSlider->setValue(mFps);
diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h
index 44ecdfe5..d2680fa8 100644
--- a/src/gui/setup_video.h
+++ b/src/gui/setup_video.h
@@ -53,6 +53,8 @@ class Setup_Video : public SetupTab, public gcn::ActionListener,
bool mVisibleNamesEnabled;
bool mParticleEffectsEnabled;
bool mNameEnabled;
+ bool mPickupChatEnabled;
+ bool mPickupParticleEnabled;
double mOpacity;
int mFps;
int mSpeechMode;
@@ -74,6 +76,10 @@ class Setup_Video : public SetupTab, public gcn::ActionListener,
gcn::CheckBox *mParticleEffectsCheckBox;
gcn::CheckBox *mNameCheckBox;
+ gcn::Label *mPickupNotifyLabel;
+ gcn::CheckBox *mPickupChatCheckBox;
+ gcn::CheckBox *mPickupParticleCheckBox;
+
gcn::Slider *mSpeechSlider;
gcn::Label *mSpeechLabel;
gcn::Slider *mAlphaSlider;
diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp
index 7b28cef4..3cdc304c 100644
--- a/src/gui/shop.cpp
+++ b/src/gui/shop.cpp
@@ -23,6 +23,11 @@
#include "../utils/dtor.h"
+ShopItems::ShopItems(bool mergeDuplicates) :
+ mMergeDuplicates(mergeDuplicates)
+{
+}
+
ShopItems::~ShopItems()
{
clear();
@@ -40,15 +45,27 @@ std::string ShopItems::getElementAt(int i)
void ShopItems::addItem(int id, int amount, int price)
{
- mShopItems.push_back(new ShopItem(id, amount, price));
+ mShopItems.push_back(new ShopItem(-1, id, amount, price));
}
#ifdef EATHENA_SUPPORT
-void ShopItems::addItem(int inventoryIndex, int id, int amount, int price)
+void ShopItems::addItem(int inventoryIndex, int id, int quantity, int price)
{
- ShopItem *item = new ShopItem(id, amount, price);
- item->setInvIndex(inventoryIndex);
- mShopItems.push_back(item);
+ ShopItem* item = 0;
+ if (mMergeDuplicates)
+ {
+ item = findItem(id);
+ }
+
+ if (item)
+ {
+ item->addDuplicate (inventoryIndex, quantity);
+ }
+ else
+ {
+ item = new ShopItem(inventoryIndex, id, quantity, price);
+ mShopItems.push_back(item);
+ }
}
#endif
@@ -57,13 +74,30 @@ ShopItem* ShopItems::at(int i) const
return mShopItems.at(i);
}
+void ShopItems::erase(int i)
+{
+ mShopItems.erase(mShopItems.begin() + i);
+}
+
void ShopItems::clear()
{
delete_all(mShopItems);
mShopItems.clear();
}
-std::vector<ShopItem*>* ShopItems::getShop()
+ShopItem* ShopItems::findItem(int id)
{
- return &mShopItems;
+ ShopItem *item;
+
+ std::vector<ShopItem*>::iterator it;
+ for(it = mShopItems.begin(); it != mShopItems.end(); it++)
+ {
+ item = *(it);
+ if (item->getId() == id)
+ {
+ return item;
+ }
+ }
+
+ return 0;
}
diff --git a/src/gui/shop.h b/src/gui/shop.h
index aa72bf2a..6c3031af 100644
--- a/src/gui/shop.h
+++ b/src/gui/shop.h
@@ -31,10 +31,27 @@
class ShopItem;
+/**
+ * This class handles the list of items available in a shop.
+ *
+ * The addItem routine can automatically check, if an item already exists and
+ * only adds duplicates to the old item, if one is found. The original
+ * distribution of the duplicates can be retrieved from the item.
+ *
+ * This functionality can be enabled in the constructor.
+ */
class ShopItems : public gcn::ListModel
{
public:
/**
+ * Constructor. Creates a new ShopItems instance.
+ *
+ * @param mergeDuplicates lets the Shop look for duplicate entries and
+ * merges them to one item.
+ */
+ ShopItems(bool mergeDuplicates = false);
+
+ /**
* Destructor.
*/
~ShopItems();
@@ -46,18 +63,28 @@ class ShopItems : public gcn::ListModel
#ifdef EATHENA_SUPPORT
/**
- * Adds an item to the list (used by eAthena sell dialog).
+ * Adds an item to the list (used by sell dialog). Looks for
+ * duplicate entries, if mergeDuplicates was turned on.
+ *
+ * @param inventoryIndex the inventory index of the item
+ * @param id the id of the item
+ * @param quantity number of available copies of the item
+ * @param price price of the item
*/
void addItem(int inventoryIndex, int id, int amount, int price);
#endif
/**
* Returns the number of items in the shop.
+ *
+ * @return the number of items in the shop
*/
int getNumberOfElements();
/**
* Returns the name of item number i in the shop.
+ *
+ * @param i the index to retrieve
*/
std::string getElementAt(int i);
@@ -67,17 +94,31 @@ class ShopItems : public gcn::ListModel
ShopItem* at(int i) const;
/**
+ * Removes an element from the shop.
+ *
+ * @param i index to remove
+ */
+ void erase(int i);
+
+ /**
* Clear the vector.
*/
void clear();
+ private:
/**
- * Direct access to the vector.
+ * Searches the current items in the shop for the specified
+ * id and returns the item if found, or 0 else.
+ *
+ * @return the item found or 0
*/
- std::vector<ShopItem*>* getShop();
+ ShopItem* findItem(int id);
- private:
+ /** the shop storage */
std::vector<ShopItem*> mShopItems;
+
+ /** Look for duplicate entries on addition */
+ bool mMergeDuplicates;
};
#endif
diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp
index 8aed3c77..aa42c294 100644
--- a/src/gui/shoplistbox.cpp
+++ b/src/gui/shoplistbox.cpp
@@ -22,7 +22,7 @@
#include <guichan/font.hpp>
#include <guichan/listmodel.hpp>
-#include "color.h"
+#include "palette.h"
#include "shop.h"
#include "shoplistbox.h"
@@ -57,17 +57,15 @@ void ShopListBox::setPlayersMoney(int money)
void ShopListBox::draw(gcn::Graphics *gcnGraphics)
{
- if (!mListModel)
+ if (!mListModel || !isVisible())
return;
if (config.getValue("guialpha", 0.8) != mAlpha)
mAlpha = config.getValue("guialpha", 0.8);
- bool valid;
- const int red = (textColor->getColor('H', valid) >> 16) & 0xFF;
- const int green = (textColor->getColor('H', valid) >> 8) & 0xFF;
- const int blue = textColor->getColor('H', valid) & 0xFF;
- const int alpha = (int)(mAlpha * 255.0f);
+ int alpha = (int)(mAlpha * 255.0f);
+ const gcn::Color* highlightColor =
+ &guiPalette->getColor(Palette::HIGHLIGHT, alpha);
Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
@@ -78,19 +76,27 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics)
i < mListModel->getNumberOfElements();
++i, y += mRowHeight)
{
- gcn::Color backgroundColor = gcn::Color(255, 255, 255, alpha);
+ gcn::Color temp;
+ const gcn::Color* backgroundColor =
+ &guiPalette->getColor(Palette::BACKGROUND, alpha);
- if (i == mSelected)
- {
- backgroundColor = gcn::Color(red, green, blue, alpha);
- }
- else if (mShopItems &&
+ if (mShopItems &&
mPlayerMoney < mShopItems->at(i)->getPrice() && mPriceCheck)
- {
- backgroundColor = gcn::Color(145, 145, 145, alpha);
- }
+ if (i != mSelected)
+ backgroundColor = &guiPalette->getColor(Palette::SHOP_WARNING,
+ alpha);
+ else
+ {
+ temp = guiPalette->getColor(Palette::SHOP_WARNING, alpha);
+ temp.r = (temp.r + highlightColor->r) / 2;
+ temp.g = (temp.g + highlightColor->g) / 2;
+ temp.b = (temp.g + highlightColor->b) / 2;
+ backgroundColor = &temp;
+ }
+ else if (i == mSelected)
+ backgroundColor = highlightColor;
- graphics->setColor(backgroundColor);
+ graphics->setColor(*backgroundColor);
graphics->fillRectangle(gcn::Rectangle(0, y, getWidth(), mRowHeight));
if (mShopItems)
@@ -101,21 +107,12 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics)
graphics->drawImage(icon, 1, y);
}
}
- graphics->setColor(gcn::Color(0, 0, 0));
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
graphics->drawText(mListModel->getElementAt(i), ITEM_ICON_SIZE + 5,
y + (ITEM_ICON_SIZE - getFont()->getHeight()) / 2);
}
}
-void ShopListBox::mousePressed(gcn::MouseEvent &event)
-{
- if (event.getButton() == gcn::MouseEvent::LEFT)
- {
- setSelected(event.getY() / mRowHeight);
- distributeActionEvent();
- }
-}
-
void ShopListBox::adjustSize()
{
if (mListModel)
diff --git a/src/gui/shoplistbox.h b/src/gui/shoplistbox.h
index cde4786e..5d3378b1 100644
--- a/src/gui/shoplistbox.h
+++ b/src/gui/shoplistbox.h
@@ -56,8 +56,6 @@ class ShopListBox : public ListBox
*/
unsigned int getRowHeight() const { return mRowHeight; }
- void mousePressed(gcn::MouseEvent &event);
-
/**
* gives information about the current player's money
*/
diff --git a/src/gui/shortcutcontainer.cpp b/src/gui/shortcutcontainer.cpp
index 74609fa1..901095e5 100644
--- a/src/gui/shortcutcontainer.cpp
+++ b/src/gui/shortcutcontainer.cpp
@@ -38,34 +38,27 @@ ShortcutContainer::ShortcutContainer():
void ShortcutContainer::widgetResized(const gcn::Event &event)
{
mGridWidth = getWidth() / mBoxWidth;
+
if (mGridWidth < 1)
- {
mGridWidth = 1;
- }
- setHeight((mMaxItems / mGridWidth +
- (mMaxItems % mGridWidth > 0 ? 1 : 0)) * mBoxHeight);
+ setHeight((mMaxItems / mGridWidth) * mBoxHeight);
mGridHeight = getHeight() / mBoxHeight;
+
if (mGridHeight < 1)
- {
mGridHeight = 1;
- }
}
int ShortcutContainer::getIndexFromGrid(int pointX, int pointY) const
{
- const gcn::Rectangle tRect = gcn::Rectangle(
- 0, 0, mGridWidth * mBoxWidth, mGridHeight * mBoxHeight);
- if (!tRect.isPointInRect(pointX, pointY))
- {
- return -1;
- }
- const int index = ((pointY / mBoxHeight) * mGridWidth) +
- pointX / mBoxWidth;
- if (index >= mMaxItems)
- {
- return -1;
- }
+ const gcn::Rectangle tRect = gcn::Rectangle(0, 0, mGridWidth * mBoxWidth,
+ mGridHeight * mBoxHeight);
+
+ int index = ((pointY / mBoxHeight) * mGridWidth) + pointX / mBoxWidth;
+
+ if (!tRect.isPointInRect(pointX, pointY) || index >= mMaxItems)
+ index = -1;
+
return index;
}
diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp
index c704fc44..dcc7f72e 100644
--- a/src/gui/shortcutwindow.cpp
+++ b/src/gui/shortcutwindow.cpp
@@ -23,6 +23,8 @@
#include "shortcutcontainer.h"
#include "shortcutwindow.h"
+#include "widgets/layout.h"
+
#include "../configuration.h"
static const int SCROLL_PADDING = 0;
@@ -39,29 +41,28 @@ ShortcutWindow::ShortcutWindow(const char *title, ShortcutContainer *content)
mItems = content;
- mInstances++;
-
const int border = SCROLL_PADDING * 2 + getPadding() * 2;
setMinWidth(mItems->getBoxWidth() + border);
setMinHeight(mItems->getBoxHeight() + border);
setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border);
setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border);
- const int width = (int) config.getValue("screenwidth", 800);
- const int height = (int) config.getValue("screenheight", 600);
+ setDefaultSize(mItems->getBoxWidth() + border, (mItems->getBoxHeight() *
+ mItems->getMaxItems()) + border, ImageRect::LOWER_RIGHT,
+ mInstances * mItems->getBoxWidth(), 0);
- setDefaultSize(width - (mInstances * mItems->getBoxWidth()) -
- (mInstances * border), height - (mItems->getBoxHeight() *
- mItems->getMaxItems()) - border, mItems->getBoxWidth() +
- border, (mItems->getBoxHeight() * mItems->getMaxItems()) +
- border);
+ mInstances++;
mScrollArea = new ScrollArea(mItems);
mScrollArea->setPosition(SCROLL_PADDING, SCROLL_PADDING);
mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mScrollArea->setOpaque(false);
- add(mScrollArea);
+ place(0, 0, mScrollArea, 5, 5).setPadding(0);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+ layout.setMargin(0);
loadWindowState();
}
@@ -71,13 +72,3 @@ ShortcutWindow::~ShortcutWindow()
delete mItems;
}
-void ShortcutWindow::widgetResized(const gcn::Event &event)
-{
- Window::widgetResized(event);
-
- const gcn::Rectangle &area = getChildrenArea();
-
- mScrollArea->setSize(
- area.width - SCROLL_PADDING,
- area.height - SCROLL_PADDING);
-}
diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h
index 64592328..eae881ba 100644
--- a/src/gui/shortcutwindow.h
+++ b/src/gui/shortcutwindow.h
@@ -45,11 +45,6 @@ class ShortcutWindow : public Window
*/
~ShortcutWindow();
- /**
- * Called whenever the widget changes size.
- */
- void widgetResized(const gcn::Event &event);
-
private:
ShortcutWindow();
ShortcutContainer *mItems;
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
index 61bb9ce9..39ccbb06 100644
--- a/src/gui/skill.cpp
+++ b/src/gui/skill.cpp
@@ -19,9 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
+#include "label.h"
#include "listbox.h"
#include "scrollarea.h"
#include "skill.h"
@@ -102,13 +101,13 @@ public:
info = &fakeSkillInfo;
sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str());
- gcn::Label *name_label = new gcn::Label(tmp);
+ gcn::Label *name_label = new Label(tmp);
sprintf(tmp, "Lv:%i", skill->lv);
- gcn::Label *lv_label = new gcn::Label(tmp);
+ gcn::Label *lv_label = new Label(tmp);
sprintf(tmp, "Sp:%i", skill->sp);
- gcn::Label *sp_label = new gcn::Label(tmp);
+ gcn::Label *sp_label = new Label(tmp);
set(i, 0, name_label);
set(i, 1, lv_label);
@@ -136,13 +135,13 @@ SkillDialog::SkillDialog():
setWindowName("Skills");
setCloseButton(true);
- setDefaultSize(windowContainer->getWidth() - 260, 25, 255, 260);
+ setDefaultSize(255, 260, ImageRect::CENTER);
setMinHeight(50 + mTableModel->getHeight());
setMinWidth(200);
ScrollArea *skillScrollArea = new ScrollArea(mTable);
- mPointsLabel = new gcn::Label(strprintf(_("Skill points: %d"), 0));
+ mPointsLabel = new Label(strprintf(_("Skill points: %d"), 0));
mIncButton = new Button(_("Up"), _("inc"), this);
mUseButton = new Button(_("Use"), _("use"), this);
mUseButton->setEnabled(false);
@@ -157,13 +156,13 @@ SkillDialog::SkillDialog():
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- setLocationRelativeTo(getParent());
+ center();
loadWindowState();
}
SkillDialog::~SkillDialog()
{
- delete mTable;
+ delete_all(mSkillList);
}
void SkillDialog::action(const gcn::ActionEvent &event)
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp
new file mode 100644
index 00000000..d44c54a8
--- /dev/null
+++ b/src/gui/skin.cpp
@@ -0,0 +1,191 @@
+/*
+ * Aethyra
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "skin.h"
+
+#include "../log.h"
+
+#include "../resources/image.h"
+#include "../resources/resourcemanager.h"
+
+#include "../utils/dtor.h"
+#include "../utils/xml.h"
+
+SkinLoader* skinLoader = NULL;
+
+Skin::Skin(ImageRect skin, Image* close, std::string name):
+ instances(0),
+ mName(name),
+ border(skin),
+ closeImage(close)
+{
+}
+
+Skin::~Skin()
+{
+ // Clean up static resources
+ for (int i = 0; i < 9; i++)
+ {
+ delete border.grid[i];
+ border.grid[i] = NULL;
+ }
+
+ closeImage->decRef();
+}
+
+unsigned int Skin::getMinWidth()
+{
+ return (border.grid[0]->getWidth() + border.grid[1]->getWidth()) +
+ border.grid[2]->getWidth();
+}
+
+unsigned int Skin::getMinHeight()
+{
+ return (border.grid[0]->getHeight() + border.grid[3]->getHeight()) +
+ border.grid[6]->getHeight();
+}
+
+Skin* SkinLoader::load(const std::string &filename)
+{
+ SkinIterator skinIterator = mSkins.find(filename);
+
+ if (mSkins.end() != skinIterator)
+ {
+ skinIterator->second->instances++;
+ return skinIterator->second;
+ }
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ logger->log("Loading Skin '%s'.", filename.c_str());
+
+ if (filename.empty())
+ logger->error("SkinLoader::load(): Invalid File Name.");
+
+ // TODO:
+ // If there is an error loading the specified file, we should try to revert
+ // to a 'default' skin file. Only if the 'default' skin file can't be loaded
+ // should we have a terminating error.
+ XML::Document doc(filename);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
+ logger->error("Widget Skinning error");
+
+ std::string skinSetImage;
+ skinSetImage = XML::getProperty(rootNode, "image", "");
+ Image *dBorders = NULL;
+ ImageRect border;
+
+ if (!skinSetImage.empty())
+ {
+ logger->log("SkinLoader::load(): <skinset> defines "
+ "'%s' as a skin image.", skinSetImage.c_str());
+ dBorders = resman->getImage("graphics/gui/" + skinSetImage);
+ }
+ else
+ {
+ logger->error("SkinLoader::load(): Skinset does not define an image!");
+ }
+
+ //iterate <widget>'s
+ for_each_xml_child_node(widgetNode, rootNode)
+ {
+ if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget"))
+ continue;
+
+ std::string widgetType;
+ widgetType = XML::getProperty(widgetNode, "type", "unknown");
+ if (widgetType == "Window")
+ {
+ // Iterate through <part>'s
+ // LEEOR / TODO:
+ // We need to make provisions to load in a CloseButton image. For
+ // now it can just be hard-coded.
+ for_each_xml_child_node(partNode, widgetNode)
+ {
+ if (!xmlStrEqual(partNode->name, BAD_CAST "part"))
+ continue;
+
+ std::string partType;
+ partType = XML::getProperty(partNode, "type", "unknown");
+ // TOP ROW
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ if (partType == "top-left-corner")
+ border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "top-edge")
+ border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "top-right-corner")
+ border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height);
+
+ // MIDDLE ROW
+ else if (partType == "left-edge")
+ border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "bg-quad")
+ border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "right-edge")
+ border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height);
+
+ // BOTTOM ROW
+ else if (partType == "bottom-left-corner")
+ border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "bottom-edge")
+ border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "bottom-right-corner")
+ border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height);
+
+ // Part is of an uknown type.
+ else
+ logger->log("SkinLoader::load(): Unknown Part Type '%s'", partType.c_str());
+ }
+ }
+ // Widget is of an uknown type.
+ else
+ {
+ logger->log("SkinLoader::load(): Unknown Widget Type '%s'", widgetType.c_str());
+ }
+ }
+ dBorders->decRef();
+
+ logger->log("Finished loading Skin.");
+
+ // Hard-coded for now until we update the above code to look for window buttons.
+ Image* closeImage = resman->getImage("graphics/gui/close_button.png");
+
+ Skin* skin = new Skin(border, closeImage);
+
+ mSkins[filename] = skin;
+ return skin;
+}
+
+SkinLoader::SkinLoader()
+{
+}
+
+SkinLoader::~SkinLoader()
+{
+ delete_all(mSkins);
+}
+
diff --git a/src/gui/skin.h b/src/gui/skin.h
new file mode 100644
index 00000000..b8a1242e
--- /dev/null
+++ b/src/gui/skin.h
@@ -0,0 +1,101 @@
+/*
+ * Aethyra
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SKIN_H
+#define SKIN_H
+
+#include <map>
+#include <string>
+
+#include "../graphics.h"
+
+class Image;
+
+class Skin
+{
+ public:
+ Skin(ImageRect skin, Image* close, std::string name = "");
+ ~Skin();
+
+ /**
+ * Returns the skin's name. Useful for giving a human friendly skin
+ * name if a dialog for skin selection for a specific window type is
+ * done.
+ */
+ std::string getName() { return mName; }
+
+ /**
+ * Returns the background skin.
+ */
+ ImageRect getBorder() { return border; }
+
+ /**
+ * Returns the image used by a close button for this skin.
+ */
+ Image* getCloseImage() { return closeImage; }
+
+ /**
+ * Returns the number of instances which use this skin.
+ */
+ int getNumberOfInstances() { return instances; }
+
+ /**
+ * Returns the minimum width which can be used with this skin.
+ */
+ unsigned int getMinWidth();
+
+ /**
+ * Returns the minimum height which can be used with this skin.
+ */
+ unsigned int getMinHeight();
+
+ int instances;
+
+ private:
+ std::string mName; /**< Name of the skin to use */
+ ImageRect border; /**< The window border and background */
+ Image *closeImage; /**< Close Button Image */
+};
+
+// Map containing all window skins
+typedef std::map<std::string, Skin*> Skins;
+
+// Iterator for window skins
+typedef Skins::iterator SkinIterator;
+
+class SkinLoader
+{
+ public:
+ SkinLoader();
+ ~SkinLoader();
+
+ /**
+ * Loads a skin
+ */
+ Skin* load(const std::string &filename);
+
+ private:
+ Skins mSkins;
+};
+
+extern SkinLoader* skinLoader;
+
+#endif
diff --git a/src/gui/slider.cpp b/src/gui/slider.cpp
index 9bfa840f..cc381c32 100644
--- a/src/gui/slider.cpp
+++ b/src/gui/slider.cpp
@@ -95,6 +95,16 @@ void Slider::init()
vGrip = slider->getSubImage(x, y, w, h);
slider->decRef();
+
+ hStart->setAlpha(mAlpha);
+ hMid->setAlpha(mAlpha);
+ hEnd->setAlpha(mAlpha);
+ hGrip->setAlpha(mAlpha);
+
+ vStart->setAlpha(mAlpha);
+ vMid->setAlpha(mAlpha);
+ vEnd->setAlpha(mAlpha);
+ vGrip->setAlpha(mAlpha);
}
mInstances++;
diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp
index 165d216f..73ada2e1 100644
--- a/src/gui/speechbubble.cpp
+++ b/src/gui/speechbubble.cpp
@@ -29,14 +29,17 @@
#include "speechbubble.h"
#include "textbox.h"
+#include "../graphics.h"
+
#include "../utils/gettext.h"
SpeechBubble::SpeechBubble():
- Window(_("Speech"), false, NULL, "graphics/gui/speechbubble.xml")
+ Popup("Speech", NULL, "graphics/gui/speechbubble.xml"),
+ mText("")
{
setContentSize(140, 46);
- setShowTitle(false);
- setTitleBarHeight(0);
+ setMinWidth(29);
+ setMinHeight(29);
mCaption = new gcn::Label("");
mCaption->setFont(boldFont);
@@ -45,6 +48,7 @@ SpeechBubble::SpeechBubble():
mSpeechBox = new TextBox;
mSpeechBox->setEditable(false);
mSpeechBox->setOpaque(false);
+ mSpeechBox->setTextColor(&guiPalette->getColor(Palette::CHAT));
mSpeechArea = new ScrollArea(mSpeechBox);
@@ -56,26 +60,29 @@ SpeechBubble::SpeechBubble():
add(mCaption);
add(mSpeechArea);
-
- setLocationRelativeTo(getParent());
}
-void SpeechBubble::setCaption(const std::string &name, const gcn::Color &color)
+void SpeechBubble::setCaption(const std::string &name, const gcn::Color *color)
{
mCaption->setCaption(name);
mCaption->adjustSize();
- mCaption->setForegroundColor(color);
+ mCaption->setForegroundColor(*color);
}
-void SpeechBubble::setText(std::string mText, bool showName)
+void SpeechBubble::setText(std::string text, bool showName)
{
+ if ((text == mText) && (mCaption->getWidth() <= mSpeechBox->getMinWidth()))
+ return;
+
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
+
int width = mCaption->getWidth();
- mSpeechBox->setTextWrapped(mText, 130 > width ? 130 : width);
+ mSpeechBox->setTextWrapped(text, 130 > width ? 130 : width);
const int fontHeight = getFont()->getHeight();
const int numRows = showName ? mSpeechBox->getNumberOfRows() + 1 :
mSpeechBox->getNumberOfRows();
- int yPos = showName ? fontHeight + 3 : 3;
+ int yPos = showName ? fontHeight + getPadding() : getPadding();
int height = (numRows * fontHeight);
if (width < mSpeechBox->getMinWidth())
@@ -83,11 +90,11 @@ void SpeechBubble::setText(std::string mText, bool showName)
if (numRows == 1)
{
- yPos = (fontHeight / 4) + 3;
+ yPos = (fontHeight / 4) + getPadding();
height = ((3 * fontHeight) / 2) + 1;
}
- setContentSize(width + fontHeight, height + 6);
+ setContentSize(width + fontHeight, height + getPadding());
mSpeechArea->setDimension(gcn::Rectangle(4, yPos, width + 5, height));
}
diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h
index 5d582b1d..3eead884 100644
--- a/src/gui/speechbubble.h
+++ b/src/gui/speechbubble.h
@@ -23,23 +23,44 @@
#ifndef SPEECHBUBBLE_H
#define SPEECHBUBBLE_H
-#include "window.h"
+#include "palette.h"
+#include "popup.h"
class ScrollArea;
class TextBox;
-class SpeechBubble : public Window
+class SpeechBubble : public Popup
{
public:
+ /**
+ * Constructor. Initializes the speech bubble.
+ */
SpeechBubble();
+ /**
+ * Sets the name displayed for the speech bubble, and in what color.
+ */
void setCaption(const std::string &name,
- const gcn::Color &color = 0x000000);
- void setText(std::string mText, bool showName = true);
+ const gcn::Color *color =
+ &guiPalette->getColor(Palette::TEXT));
+
+ /**
+ * Sets the text to be displayed.
+ */
+ void setText(std::string text, bool showName = true);
+
+ /**
+ * Sets the location in which the speech bubble will be displayed.
+ */
void setLocation(int x, int y);
+
+ /**
+ * Gets the number of rows the speech bubble has.
+ */
unsigned int getNumRows();
private:
+ std::string mText;
gcn::Label *mCaption;
TextBox *mSpeechBox;
ScrollArea *mSpeechArea;
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
index 3c48d045..2f95f1c8 100644
--- a/src/gui/status.cpp
+++ b/src/gui/status.cpp
@@ -19,9 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <guichan/widgets/label.hpp>
-
#include "button.h"
+#include "label.h"
#include "progressbar.h"
#include "status.h"
#include "windowcontainer.h"
@@ -42,28 +41,27 @@ StatusWindow::StatusWindow(LocalPlayer *player):
{
setWindowName("Status");
setCloseButton(true);
- setDefaultSize((windowContainer->getWidth() - 365) / 2,
- (windowContainer->getHeight() - 255) / 2, 400, 345);
+ setDefaultSize(400, 345, ImageRect::CENTER);
// ----------------------
// Status Part
// ----------------------
- mLvlLabel = new gcn::Label(strprintf(_("Level: %d"), 0));
- mJobLvlLabel = new gcn::Label(strprintf(_("Job: %d"), 0));
- mGpLabel = new gcn::Label(strprintf(_("Money: %s"),
+ mLvlLabel = new Label(strprintf(_("Level: %d"), 0));
+ mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0));
+ mGpLabel = new Label(strprintf(_("Money: %s"),
Units::formatCurrency(mCurrency).c_str()));
- mHpLabel = new gcn::Label(_("HP:"));
+ mHpLabel = new Label(_("HP:"));
mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34);
- mXpLabel = new gcn::Label(_("Exp:"));
+ mXpLabel = new Label(_("Exp:"));
mXpBar = new ProgressBar(1.0f, 80, 15, 143, 192, 211);
- mMpLabel = new gcn::Label(_("MP:"));
+ mMpLabel = new Label(_("MP:"));
mMpBar = new ProgressBar(1.0f, 80, 15, 26, 102, 230);
- mJobLabel = new gcn::Label(_("Job:"));
+ mJobLabel = new Label(_("Job:"));
mJobBar = new ProgressBar(1.0f, 80, 15, 220, 135, 203);
// ----------------------
@@ -71,41 +69,41 @@ StatusWindow::StatusWindow(LocalPlayer *player):
// ----------------------
// Static Labels
- gcn::Label *mStatsTitleLabel = new gcn::Label(_("Stats"));
- gcn::Label *mStatsTotalLabel = new gcn::Label(_("Total"));
- gcn::Label *mStatsCostLabel = new gcn::Label(_("Cost"));
+ gcn::Label *mStatsTitleLabel = new Label(_("Stats"));
+ gcn::Label *mStatsTotalLabel = new Label(_("Total"));
+ gcn::Label *mStatsCostLabel = new Label(_("Cost"));
mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER);
// Derived Stats
- mStatsAttackLabel = new gcn::Label(_("Attack:"));
- mStatsDefenseLabel= new gcn::Label(_("Defense:"));
- mStatsMagicAttackLabel = new gcn::Label(_("M.Attack:"));
- mStatsMagicDefenseLabel = new gcn::Label(_("M.Defense:"));
+ mStatsAttackLabel = new Label(_("Attack:"));
+ mStatsDefenseLabel= new Label(_("Defense:"));
+ mStatsMagicAttackLabel = new Label(_("M.Attack:"));
+ mStatsMagicDefenseLabel = new Label(_("M.Defense:"));
// Gettext flag for next line: xgettext:no-c-format
- mStatsAccuracyLabel = new gcn::Label(_("% Accuracy:"));
+ mStatsAccuracyLabel = new Label(_("% Accuracy:"));
// Gettext flag for next line: xgettext:no-c-format
- mStatsEvadeLabel = new gcn::Label(_("% Evade:"));
+ mStatsEvadeLabel = new Label(_("% Evade:"));
// Gettext flag for next line: xgettext:no-c-format
- mStatsReflexLabel = new gcn::Label(_("% Reflex:"));
+ mStatsReflexLabel = new Label(_("% Reflex:"));
- mStatsAttackPoints = new gcn::Label;
- mStatsDefensePoints = new gcn::Label;
- mStatsMagicAttackPoints = new gcn::Label;
- mStatsMagicDefensePoints = new gcn::Label;
- mStatsAccuracyPoints = new gcn::Label;
- mStatsEvadePoints = new gcn::Label;
- mStatsReflexPoints = new gcn::Label;
+ mStatsAttackPoints = new Label;
+ mStatsDefensePoints = new Label;
+ mStatsMagicAttackPoints = new Label;
+ mStatsMagicDefensePoints = new Label;
+ mStatsAccuracyPoints = new Label;
+ mStatsEvadePoints = new Label;
+ mStatsReflexPoints = new Label;
// New labels
for (int i = 0; i < 6; i++)
{
- mStatsLabel[i] = new gcn::Label("0");
+ mStatsLabel[i] = new Label("0");
mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER);
- mStatsDisplayLabel[i] = new gcn::Label;
- mPointsLabel[i] = new gcn::Label("0");
+ mStatsDisplayLabel[i] = new Label;
+ mPointsLabel[i] = new Label("0");
mPointsLabel[i]->setAlignment(gcn::Graphics::CENTER);
}
- mRemainingStatsPointsLabel = new gcn::Label;
+ mRemainingStatsPointsLabel = new Label;
// Set button events Id
mStatsButton[0] = new Button("+", "STR", this);
@@ -181,39 +179,13 @@ void StatusWindow::update()
mGpLabel->adjustSize();
}
- mHpBar->setText(toString(mPlayer->getHp()) +
- "/" + toString(mPlayer->getMaxHp()));
-
- mMpBar->setText(toString(mPlayer->mMp) +
- "/" + toString(mPlayer->mMaxMp));
-
- mXpBar->setText(toString(mPlayer->getXp()) +
- "/" + toString(mPlayer->mXpForNextLevel));
-
- mJobBar->setText(toString(mPlayer->mJobXp) +
- "/" + toString(mPlayer->mJobXpForNextLevel));
+ updateHPBar(mHpBar, true);
- // HP Bar coloration
- if (mPlayer->getHp() < int(mPlayer->getMaxHp() / 3))
- {
- mHpBar->setColor(223, 32, 32); // Red
- }
- else if (mPlayer->getHp() < int((mPlayer->getMaxHp() / 3) * 2))
- {
- mHpBar->setColor(230, 171, 34); // Orange
- }
- else
- {
- mHpBar->setColor(0, 171, 34); // Green
- }
+ updateMPBar(mMpBar, true);
- mHpBar->setProgress((float) mPlayer->getHp() / (float) mPlayer->getMaxHp());
- mMpBar->setProgress((float) mPlayer->mMp / (float) mPlayer->mMaxMp);
+ updateXPBar(mXpBar, false);
- mXpBar->setProgress(
- (float) mPlayer->getXp() / (float) mPlayer->mXpForNextLevel);
- mJobBar->setProgress(
- (float) mPlayer->mJobXp / (float) mPlayer->mJobXpForNextLevel);
+ updateJobBar(mJobBar, false);
// Stats Part
// ----------
@@ -281,6 +253,9 @@ void StatusWindow::update()
void StatusWindow::draw(gcn::Graphics *g)
{
+ if (!isVisible())
+ return;
+
update();
Window::draw(g);
@@ -292,29 +267,97 @@ void StatusWindow::action(const gcn::ActionEvent &event)
if (event.getId().length() == 3)
{
if (event.getId() == "STR")
- {
player_node->raiseAttribute(LocalPlayer::STR);
- }
if (event.getId() == "AGI")
- {
player_node->raiseAttribute(LocalPlayer::AGI);
- }
if (event.getId() == "VIT")
- {
player_node->raiseAttribute(LocalPlayer::VIT);
- }
if (event.getId() == "INT")
- {
player_node->raiseAttribute(LocalPlayer::INT);
- }
if (event.getId() == "DEX")
- {
player_node->raiseAttribute(LocalPlayer::DEX);
- }
if (event.getId() == "LUK")
- {
player_node->raiseAttribute(LocalPlayer::LUK);
+ }
+}
+
+void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->getHp()) +
+ "/" + toString(player_node->getMaxHp()));
+ else
+ bar->setText(toString(player_node->getHp()));
+
+ // HP Bar coloration
+ if (player_node->getHp() < player_node->getMaxHp() / 3)
+ {
+ bar->setColor(223, 32, 32); // Red
+ }
+ else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2)
+ {
+ bar->setColor(230, 171, 34); // Orange
+ }
+ else
+ {
+ bar->setColor(0, 171, 34); // Green
+ }
+
+ bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
+}
+
+void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->mMp) +
+ "/" + toString(player_node->mMaxMp));
+ else
+ bar->setText(toString(player_node->mMp));
+
+
+ bar->setProgress((float) player_node->mMp / (float) player_node->mMaxMp);
+}
+
+void StatusWindow::updateXPBar(ProgressBar *bar, bool percent)
+{
+ if (player_node->mXpForNextLevel == 0) {
+ bar->setText(_("Max level"));
+ bar->setProgress(1.0);
+ } else {
+ if (percent)
+ {
+ float xp = (float) player_node->getXp() /
+ player_node->mXpForNextLevel;
+ bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) +
+ "%");
}
+ else
+ bar->setText(toString(player_node->getXp()) +
+ "/" + toString(player_node->mXpForNextLevel));
+
+ bar->setProgress((float) player_node->getXp() /
+ (float) player_node->mXpForNextLevel);
}
}
+void StatusWindow::updateJobBar(ProgressBar *bar, bool percent)
+{
+ if (player_node->mJobXpForNextLevel == 0) {
+ bar->setText(_("Max level"));
+ bar->setProgress(1.0);
+ } else {
+ if (percent)
+ {
+ float xp = (float) player_node->mJobXp /
+ player_node->mJobXpForNextLevel;
+ bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) +
+ "%");
+ }
+ else
+ bar->setText(toString(player_node->mJobXp) +
+ "/" + toString(player_node->mJobXpForNextLevel));
+
+ bar->setProgress((float) player_node->mJobXp /
+ (float) player_node->mJobXpForNextLevel);
+ }
+}
diff --git a/src/gui/status.h b/src/gui/status.h
index 9e4de3fd..1425fe12 100644
--- a/src/gui/status.h
+++ b/src/gui/status.h
@@ -57,6 +57,11 @@ class StatusWindow : public Window, public gcn::ActionListener
*/
void update();
+ static void updateHPBar(ProgressBar *bar, bool showMax = false);
+ static void updateMPBar(ProgressBar *bar, bool showMax = false);
+ static void updateXPBar(ProgressBar *bar, bool percent = true);
+ static void updateJobBar(ProgressBar *bar, bool percent = true);
+
private:
LocalPlayer *mPlayer;
diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp
index bcac0a90..8d4363d9 100644
--- a/src/gui/statuswindow.cpp
+++ b/src/gui/statuswindow.cpp
@@ -208,28 +208,7 @@ void StatusWindow::update()
mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP");
mMoneyLabel->adjustSize();
- int hp = mPlayer->getHp();
- int maxHp = mPlayer->getMaxHp();
-
- mHpValueLabel->setCaption(toString(hp) +
- " / " + toString(maxHp));
- mHpValueLabel->adjustSize();
-
- // HP Bar coloration
- if (hp < int(maxHp / 3))
- {
- mHpBar->setColor(223, 32, 32); // Red
- }
- else if (hp < int((maxHp / 3) * 2))
- {
- mHpBar->setColor(230, 171, 34); // Orange
- }
- else
- {
- mHpBar->setColor(0, 171, 34); // Green
- }
-
- mHpBar->setProgress((float) hp / maxHp);
+ updateHPBar(mHpBar, true);
// Stats Part
// ----------
@@ -368,3 +347,30 @@ void StatusWindow::action(const gcn::ActionEvent &event)
mPlayer->lowerAttribute(LocalPlayer::WIL);
}
}
+
+// WARNING: Duplicated method!
+
+void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->getHp()) +
+ "/" + toString(player_node->getMaxHp()));
+ else
+ bar->setText(toString(player_node->getHp()));
+
+ // HP Bar coloration
+ if (player_node->getHp() < player_node->getMaxHp() / 3)
+ {
+ bar->setColor(223, 32, 32); // Red
+ }
+ else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2)
+ {
+ bar->setColor(230, 171, 34); // Orange
+ }
+ else
+ {
+ bar->setColor(0, 171, 34); // Green
+ }
+
+ bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
+}
diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h
index 262b89f6..05bac4e5 100644
--- a/src/gui/statuswindow.h
+++ b/src/gui/statuswindow.h
@@ -62,6 +62,8 @@ class StatusWindow : public Window, public gcn::ActionListener
*/
void update();
+ static void updateHPBar(ProgressBar *bar, bool showMax = false);
+
private:
LocalPlayer *mPlayer;
diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp
new file mode 100644
index 00000000..81212ae8
--- /dev/null
+++ b/src/gui/storagewindow.cpp
@@ -0,0 +1,210 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string>
+
+#include <guichan/font.hpp>
+#include <guichan/mouseinput.hpp>
+
+#include "button.h"
+#include "inventorywindow.h"
+#include "item_amount.h"
+#include "itemcontainer.h"
+#include "label.h"
+#include "progressbar.h"
+#include "scrollarea.h"
+#include "storagewindow.h"
+#include "viewport.h"
+
+#include "widgets/layout.h"
+
+#include "../inventory.h"
+#include "../item.h"
+#include "../localplayer.h"
+#include "../units.h"
+
+#include "../net/messageout.h"
+#ifdef EATHENA_SUPPORT
+#include "../net/ea/protocol.h"
+#endif
+
+#include "../resources/iteminfo.h"
+
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
+#include "../utils/stringutils.h"
+
+StorageWindow::StorageWindow(Network *network, int invSize):
+ Window(_("Storage")),
+ mNetwork(network),
+ mMaxSlots(invSize),
+ mItemDesc(false)
+{
+ setWindowName("Storage");
+ setResizable(true);
+ setCloseButton(true);
+
+ // If you adjust these defaults, don't forget to adjust the trade window's.
+ setDefaultSize(375, 300, ImageRect::CENTER);
+
+ mStoreButton = new Button(_("Store"), "store", this);
+ mRetrieveButton = new Button(_("Retrieve"), "retrieve", this);
+
+ mItems = new ItemContainer(player_node->getStorage(), 10, 5, 1);
+ mItems->addSelectionListener(this);
+
+ mInvenScroll = new ScrollArea(mItems);
+ mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+
+ mUsedSlots = toString(player_node->getStorage()->getNumberOfSlotsUsed());
+
+ mSlotsLabel = new Label(_("Slots: "));
+
+ mSlotsBar = new ProgressBar(1.0f, 100, 20, 225, 200, 25);
+
+ setMinHeight(130);
+ setMinWidth(mSlotsLabel->getWidth());
+
+ place(0, 0, mSlotsLabel).setPadding(3);
+ place(1, 0, mSlotsBar, 3);
+ place(0, 1, mInvenScroll, 4, 4);
+ place(2, 5, mStoreButton);
+ place(3, 5, mRetrieveButton);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, mStoreButton->getHeight());
+
+ loadWindowState();
+}
+
+StorageWindow::~StorageWindow()
+{
+ delete mItems;
+}
+
+void StorageWindow::logic()
+{
+ if (!isVisible())
+ return;
+
+ Window::logic();
+
+ if (mUsedSlots != toString(player_node->getStorage()->getNumberOfSlotsUsed()))
+ {
+ mUsedSlots = toString(player_node->getStorage()->getNumberOfSlotsUsed());
+
+ mSlotsBar->setProgress((float)
+ player_node->getStorage()->getNumberOfSlotsUsed() / mMaxSlots);
+
+ mSlotsBar->setText(strprintf("%s/%d", mUsedSlots.c_str(), mMaxSlots));
+ }
+}
+
+void StorageWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "store")
+ {
+ if (!inventoryWindow->isVisible()) return;
+
+ Item *item = inventoryWindow->getSelectedItem();
+
+ if (!item)
+ return;
+
+ if (item->getQuantity() == 1)
+ {
+ addStore(item, 1);
+ }
+ else
+ {
+ // Choose amount of items to trade
+ new ItemAmountWindow(AMOUNT_STORE_ADD, this, item);
+ }
+ }
+ else if (event.getId() == "retrieve")
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (!item)
+ return;
+
+ if (item->getQuantity() == 1)
+ {
+ removeStore(item, 1);
+ }
+ else
+ {
+ // Choose amount of items to trade
+ new ItemAmountWindow(AMOUNT_STORE_REMOVE, this, item);
+ }
+ }
+}
+
+void StorageWindow::mouseClicked(gcn::MouseEvent &event)
+{
+ Window::mouseClicked(event);
+
+ if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ Item *item = mItems->getSelectedItem();
+
+ if (!item) {
+ mRetrieveButton->setEnabled(false);
+ return;
+ }
+
+ mRetrieveButton->setEnabled(true);
+
+ /* Convert relative to the window coordinates to absolute screen
+ * coordinates.
+ */
+ const int mx = event.getX() + getX();
+ const int my = event.getY() + getY();
+ viewport->showPopup(mx, my, item);
+ }
+}
+
+Item* StorageWindow::getSelectedItem() const
+{
+ return mItems->getSelectedItem();
+}
+
+void StorageWindow::addStore(Item* item, int ammount)
+{
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_MOVE_TO_STORAGE);
+ outMsg.writeInt16(item->getInvIndex());
+ outMsg.writeInt32(ammount);
+}
+
+void StorageWindow::removeStore(Item* item, int ammount)
+{
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CSMG_MOVE_FROM_STORAGE);
+ outMsg.writeInt16(item->getInvIndex());
+ outMsg.writeInt32(ammount);
+}
+
+void StorageWindow::close()
+{
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_CLOSE_STORAGE);
+}
diff --git a/src/gui/storagewindow.h b/src/gui/storagewindow.h
new file mode 100644
index 00000000..c78d33a7
--- /dev/null
+++ b/src/gui/storagewindow.h
@@ -0,0 +1,110 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef STORAGEWINDOW_H
+#define STORAGEWINDOW_H
+
+#include "window.h"
+
+#include "../inventory.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/selectionlistener.hpp>
+
+class Item;
+class ItemContainer;
+class Network;
+class ProgressBar;
+class TextBox;
+
+/**
+ * Storage dialog.
+ *
+ * \ingroup Interface
+ */
+class StorageWindow : public Window, gcn::ActionListener,
+ gcn::SelectionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ StorageWindow(Network *network, int invSize = (STORAGE_SIZE - 1));
+
+ /**
+ * Destructor.
+ */
+ ~StorageWindow();
+
+ /**
+ * Logic (updates buttons and weight information).
+ */
+ void logic();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ /**
+ * Returns the selected item.
+ */
+ Item* getSelectedItem() const;
+
+ void mouseClicked(gcn::MouseEvent &event);
+
+ /**
+ * Add the specified ammount of the specified item to storage
+ */
+ void addStore(Item* item, int ammount);
+
+ /**
+ * Remove the specified ammount of the specified item from storage
+ */
+ void removeStore(Item* item, int ammount);
+
+ /**
+ * Closes the Storage Window, as well as telling the server that the
+ * window has been closed.
+ */
+ void close();
+
+ private:
+ Network *mNetwork;
+ ItemContainer *mItems;
+
+ std::string mSlots;
+ std::string mUsedSlots;
+ gcn::Button *mStoreButton, *mRetrieveButton;
+ gcn::ScrollArea *mInvenScroll;
+
+ gcn::Label *mSlotsLabel;
+
+ ProgressBar *mSlotsBar;
+
+ int mMaxSlots;
+
+ bool mItemDesc;
+};
+
+extern StorageWindow *storageWindow;
+
+#endif // STORAGEWINDOW_H
diff --git a/src/gui/table.cpp b/src/gui/table.cpp
index 1fd088ce..ec5b0480 100644
--- a/src/gui/table.cpp
+++ b/src/gui/table.cpp
@@ -23,7 +23,7 @@
#include <guichan/graphics.hpp>
#include <guichan/key.hpp>
-#include "color.h"
+#include "palette.h"
#include "table.h"
#include "../configuration.h"
@@ -98,6 +98,7 @@ GuiTable::GuiTable(TableModel *initial_model, gcn::Color background,
GuiTable::~GuiTable()
{
+ uninstallActionListeners();
delete mModel;
}
@@ -264,7 +265,7 @@ void GuiTable::installActionListeners()
// -- widget ops
void GuiTable::draw(gcn::Graphics* graphics)
{
- if (!mModel)
+ if (!mModel || !isVisible())
return;
if (config.getValue("guialpha", 0.8) != mAlpha)
@@ -272,11 +273,8 @@ void GuiTable::draw(gcn::Graphics* graphics)
if (mOpaque)
{
- const int red = getBackgroundColor().r;
- const int green = getBackgroundColor().g;
- const int blue = getBackgroundColor().b;
- const int alpha = (int)(mAlpha * 255.0f);
- graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->setColor(guiPalette->getColor(Palette::BACKGROUND,
+ (int)(mAlpha * 255.0f)));
graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
}
@@ -321,18 +319,19 @@ void GuiTable::draw(gcn::Graphics* graphics)
widget->setDimension(bounds);
- if (!mLinewiseMode && c == mSelectedColumn && r == mSelectedRow)
+ graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT,
+ (int)(mAlpha * 255.0f)));
+
+ if (mLinewiseMode && r == mSelectedRow && c == 0)
+ {
+ graphics->fillRectangle(gcn::Rectangle(0, y_offset,
+ getWidth(), height));
+ }
+ else if (!mLinewiseMode &&
+ c == mSelectedColumn && r == mSelectedRow)
{
- bool valid;
- const int red =
- (textColor->getColor('H', valid) >> 16) & 0xFF;
- const int green =
- (textColor->getColor('H', valid) >> 8) & 0xFF;
- const int blue = textColor->getColor('H', valid) & 0xFF;
- const int alpha = (int)(mAlpha * 127.0f);
-
- graphics->setColor(gcn::Color(red, green, blue, alpha));
- graphics->fillRectangle(bounds);
+ graphics->fillRectangle(gcn::Rectangle(x_offset, y_offset,
+ width, height));
}
graphics->pushClipArea(bounds);
@@ -343,21 +342,6 @@ void GuiTable::draw(gcn::Graphics* graphics)
x_offset += width;
}
- if (mLinewiseMode && r == mSelectedRow)
- {
- bool valid;
- const int red =
- (textColor->getColor('H', valid) >> 16) & 0xFF;
- const int green =
- (textColor->getColor('H', valid) >> 8) & 0xFF;
- const int blue = textColor->getColor('H', valid) & 0xFF;
- const int alpha = (int)(mAlpha * 127.0f);
-
- graphics->setColor(gcn::Color(red, green, blue, alpha));
- graphics->fillRectangle(gcn::Rectangle(0, y_offset,
- x_offset, height));
- }
-
y_offset += height;
}
@@ -401,25 +385,21 @@ void GuiTable::keyPressed(gcn::KeyEvent& keyEvent)
else if (key.getValue() == gcn::Key::UP)
{
setSelectedRow(mSelectedRow - 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::DOWN)
{
setSelectedRow(mSelectedRow + 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::LEFT)
{
setSelectedColumn(mSelectedColumn - 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::RIGHT)
{
setSelectedColumn(mSelectedColumn + 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::HOME)
@@ -459,7 +439,7 @@ void GuiTable::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
{
if (isFocused())
{
- if (getSelectedRow() >= 0 )
+ if (getSelectedRow() > 0 || (getSelectedRow() == 0 && mWrappingEnabled))
{
setSelectedRow(getSelectedRow() - 1);
}
diff --git a/src/gui/textbox.cpp b/src/gui/textbox.cpp
index 2a86d549..10f727e3 100644
--- a/src/gui/textbox.cpp
+++ b/src/gui/textbox.cpp
@@ -23,10 +23,11 @@
#include <guichan/font.hpp>
+#include "palette.h"
#include "textbox.h"
-TextBox::TextBox():
- gcn::TextBox()
+TextBox::TextBox() :
+ gcn::TextBox(), mTextColor(&guiPalette->getColor(Palette::TEXT))
{
setOpaque(false);
setFrameSize(0);
@@ -37,52 +38,46 @@ void TextBox::setTextWrapped(const std::string &text, int minDimension)
{
// Make sure parent scroll area sets width of this widget
if (getParent())
- {
getParent()->logic();
- }
// Take the supplied minimum dimension as a starting point and try to beat it
mMinWidth = minDimension;
std::stringstream wrappedStream;
- std::string::size_type newlinePos, lastNewlinePos = 0;
+ std::string::size_type spacePos, newlinePos, lastNewlinePos = 0;
int minWidth = 0;
int xpos;
+ spacePos = text.rfind(" ", text.size());
+
+ if (spacePos != std::string::npos)
+ {
+ const std::string word = text.substr(spacePos + 1);
+ const int length = getFont()->getWidth(word);
+
+ if (length > mMinWidth)
+ mMinWidth = length;
+ }
+
do
{
// Determine next piece of string to wrap
newlinePos = text.find("\n", lastNewlinePos);
if (newlinePos == std::string::npos)
- {
newlinePos = text.size();
- }
std::string line =
text.substr(lastNewlinePos, newlinePos - lastNewlinePos);
- std::string::size_type spacePos, lastSpacePos = 0;
+ std::string::size_type lastSpacePos = 0;
xpos = 0;
- spacePos = text.rfind(" ", text.size());
-
- if (spacePos != std::string::npos)
- {
- const std::string word = text.substr(spacePos + 1);
- const int length = getFont()->getWidth(word);
-
- if (length > mMinWidth)
- mMinWidth = length;
- }
-
do
{
spacePos = line.find(" ", lastSpacePos);
if (spacePos == std::string::npos)
- {
spacePos = line.size();
- }
std::string word =
line.substr(lastSpacePos, spacePos - lastSpacePos);
diff --git a/src/gui/textbox.h b/src/gui/textbox.h
index 10a81fc0..5884e11c 100644
--- a/src/gui/textbox.h
+++ b/src/gui/textbox.h
@@ -39,6 +39,11 @@ class TextBox : public gcn::TextBox
*/
TextBox();
+ inline void setTextColor(const gcn::Color* color)
+ {
+ mTextColor = color;
+ }
+
/**
* Sets the text after wrapping it to the current width of the widget.
*/
@@ -49,8 +54,18 @@ class TextBox : public gcn::TextBox
*/
int getMinWidth() { return mMinWidth; }
+ /**
+ * Draws the text.
+ */
+ inline void draw(gcn::Graphics *graphics)
+ {
+ setForegroundColor(*mTextColor);
+ gcn::TextBox::draw(graphics);
+ }
+
private:
int mMinWidth;
+ const gcn::Color* mTextColor;
};
#endif
diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp
index 99a95a2e..5c6e4f49 100644
--- a/src/gui/textfield.cpp
+++ b/src/gui/textfield.cpp
@@ -21,6 +21,7 @@
#include <guichan/font.hpp>
+#include "palette.h"
#include "sdlinput.h"
#include "textfield.h"
@@ -54,8 +55,10 @@ TextField::TextField(const std::string& text):
int gridy[4] = {0, 3, 28, 31};
int a = 0, x, y;
- for (y = 0; y < 3; y++) {
- for (x = 0; x < 3; x++) {
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
skin.grid[a] = textbox->getSubImage(
gridx[x], gridy[y],
gridx[x + 1] - gridx[x] + 1,
@@ -76,20 +79,22 @@ TextField::~TextField()
instances--;
if (instances == 0)
- {
for_each(skin.grid, skin.grid + 9, dtor<Image*>());
- }
}
void TextField::draw(gcn::Graphics *graphics)
{
- if (isFocused()) {
+ if (!isVisible())
+ return;
+
+ if (isFocused())
+ {
drawCaret(graphics,
- getFont()->getWidth(mText.substr(0, mCaretPosition)) -
- mXScroll);
+ getFont()->getWidth(mText.substr(0, mCaretPosition)) -
+ mXScroll);
}
- graphics->setColor(getForegroundColor());
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
graphics->setFont(getFont());
graphics->drawText(mText, 1 - mXScroll, 1);
@@ -97,9 +102,7 @@ void TextField::draw(gcn::Graphics *graphics)
{
mAlpha = config.getValue("guialpha", 0.8);
for (int a = 0; a < 9; a++)
- {
skin.grid[a]->setAlpha(mAlpha);
- }
}
}
@@ -117,9 +120,8 @@ void TextField::setNumeric(bool numeric)
{
mNumeric = numeric;
if (!numeric)
- {
return;
- }
+
const char *text = mText.c_str();
for (const char *textPtr = text; *textPtr; ++textPtr)
{
@@ -134,18 +136,15 @@ void TextField::setNumeric(bool numeric)
int TextField::getValue() const
{
if (!mNumeric)
- {
return 0;
- }
+
int value = atoi(mText.c_str());
if (value < mMinimum)
- {
return mMinimum;
- }
+
if (value > mMaximum)
- {
return mMaximum;
- }
+
return value;
}
diff --git a/src/gui/textrenderer.h b/src/gui/textrenderer.h
new file mode 100644
index 00000000..b69e72a7
--- /dev/null
+++ b/src/gui/textrenderer.h
@@ -0,0 +1,81 @@
+/*
+ * Text Renderer
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TEXT_RENDERER_H
+#define TEXT_RENDERER_H
+
+#include "graphics.h"
+#include "palette.h"
+
+/**
+ * Class for text rendering. Used by the TextParticle, the Text and FlashText
+ * objects and the Preview in the color dialog.
+ */
+class TextRenderer
+{
+ public:
+ /**
+ * Renders a specified text.
+ */
+ static inline void renderText(gcn::Graphics *graphics, const std::string&
+ text, int x, int y, gcn::Graphics::Alignment align,
+ const gcn::Color color, gcn::Font *font, bool outline = false,
+ bool shadow = false, int alpha = 255)
+ {
+ graphics->setFont(font);
+
+ // Text shadow
+ if (shadow)
+ {
+ graphics->setColor(guiPalette->getColor(Palette::SHADOW,
+ alpha / 2));
+ if (outline)
+ {
+ graphics->drawText(text, x + 2, y + 2, align);
+ }
+ else
+ {
+ graphics->drawText(text, x + 1, y + 1, align);
+ }
+ }
+
+ if (outline) {
+/* graphics->setColor(guiPalette->getColor(Palette::OUTLINE,
+ alpha/4));
+ // TODO: Reanable when we can draw it nicely in software mode
+ graphics->drawText(text, x + 2, y + 2, align);
+ graphics->drawText(text, x + 1, y + 2, align);
+ graphics->drawText(text, x + 2, y + 1, align);*/
+
+ // Text outline
+ graphics->setColor(guiPalette->getColor(Palette::OUTLINE, alpha));
+ graphics->drawText(text, x + 1, y, align);
+ graphics->drawText(text, x - 1, y, align);
+ graphics->drawText(text, x, y + 1, align);
+ graphics->drawText(text, x, y - 1, align);
+ }
+
+ graphics->setColor(color);
+ graphics->drawText(text, x, y, align);
+ }
+};
+
+#endif
diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp
index 9910f4ce..5be71a6f 100644
--- a/src/gui/trade.cpp
+++ b/src/gui/trade.cpp
@@ -22,13 +22,13 @@
#include <sstream>
#include <guichan/font.hpp>
-#include <guichan/widgets/label.hpp>
#include "button.h"
#include "chat.h"
#include "inventorywindow.h"
#include "item_amount.h"
#include "itemcontainer.h"
+#include "label.h"
#include "scrollarea.h"
#include "textfield.h"
#include "trade.h"
@@ -59,20 +59,29 @@ TradeWindow::TradeWindow(Network *network):
Window(_("Trade: You")),
#ifdef EATHENA_SUPPORT
mNetwork(network),
-#endif
+ mMyInventory(new Inventory(INVENTORY_SIZE, 2)),
+ mPartnerInventory(new Inventory(INVENTORY_SIZE, 2))
+#else
mMyInventory(new Inventory(INVENTORY_SIZE)),
- mPartnerInventory(new Inventory(INVENTORY_SIZE))
-#ifdef TMWSERV_SUPPORT
- , mStatus(PREPARING)
+ mPartnerInventory(new Inventory(INVENTORY_SIZE)),
+ mStatus(PREPARING)
#endif
{
setWindowName("Trade");
setResizable(true);
- setDefaultSize(115, 197, 332, 209);
+ setCloseButton(true);
+ setDefaultSize(342, 209, ImageRect::CENTER);
+
+ setMinWidth(342);
+ setMinHeight(209);
+
+ std::string longestName = getFont()->getWidth(_("OK")) >
+ getFont()->getWidth(_("Trade")) ?
+ _("OK") : _("Trade");
Button *mAddButton = new Button(_("Add"), "add", this);
#ifdef EATHENA_SUPPORT
- mOkButton = new Button(_("Ok"), "ok", this);
+ mOkButton = new Button(longestName, "ok", this);
#endif
Button *mCancelButton = new Button(_("Cancel"), "cancel", this);
mTradeButton = new Button(_("Propose trade"), "trade", this);
@@ -86,6 +95,7 @@ TradeWindow::TradeWindow(Network *network):
mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 2);
#endif
mMyItemContainer->addSelectionListener(this);
+
ScrollArea *mMyScroll = new ScrollArea(mMyItemContainer);
#ifdef TMWSERV_SUPPORT
@@ -94,10 +104,12 @@ TradeWindow::TradeWindow(Network *network):
mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 2);
#endif
mPartnerItemContainer->addSelectionListener(this);
+
ScrollArea *mPartnerScroll = new ScrollArea(mPartnerItemContainer);
- mMoneyLabel = new gcn::Label(strprintf(_("You get %d GP."), 0));
- gcn::Label *mMoneyLabel2 = new gcn::Label(_("You give:"));
+ mMoneyLabel = new Label(strprintf(_("You get %s."), ""));
+ gcn::Label *mMoneyLabel2 = new Label(_("You give:"));
+
mMoneyField = new TextField;
mMoneyField->setWidth(40);
Button *mMoneyChange = new Button(_("Change"), "money", this);
@@ -114,9 +126,10 @@ TradeWindow::TradeWindow(Network *network):
place(0, 0, mAddButton);
#ifdef EATHENA_SUPPORT
place(1, 0, mOkButton);
-#endif
+#else
place(2, 0, mTradeButton);
place(3, 0, mCancelButton);
+#endif
Layout &layout = getLayout();
layout.extend(0, 2, 2, 1);
layout.setRowHeight(1, Layout::AUTO_SET);
@@ -124,6 +137,10 @@ TradeWindow::TradeWindow(Network *network):
layout.setColWidth(0, Layout::AUTO_SET);
layout.setColWidth(1, Layout::AUTO_SET);
+#ifdef EATHENA_SUPPORT
+ mOkButton->setCaption(_("OK"));
+#endif
+
loadWindowState();
}
@@ -184,7 +201,8 @@ void TradeWindow::reset()
mMyInventory->clear();
mPartnerInventory->clear();
#ifdef EATHENA_SUPPORT
- mTradeButton->setEnabled(false);
+ mOkButton->setCaption(_("OK"));
+ mOkButton->setActionEventId("ok");
mOkButton->setEnabled(true);
mOkOther = false;
mOkMe = false;
@@ -206,11 +224,6 @@ void TradeWindow::receivedOk()
#else
-void TradeWindow::setTradeButton(bool enabled)
-{
- mTradeButton->setEnabled(enabled);
-}
-
void TradeWindow::receivedOk(bool own)
{
if (own)
@@ -218,13 +231,8 @@ void TradeWindow::receivedOk(bool own)
mOkMe = true;
if (mOkOther)
{
- mTradeButton->setEnabled(true);
- mOkButton->setEnabled(false);
- }
- else
- {
- mTradeButton->setEnabled(false);
- mOkButton->setEnabled(false);
+ mOkButton->setCaption(_("Trade"));
+ mOkButton->setActionEventId("trade");
}
}
else
@@ -232,13 +240,8 @@ void TradeWindow::receivedOk(bool own)
mOkOther = true;
if (mOkMe)
{
- mTradeButton->setEnabled(true);
- mOkButton->setEnabled(false);
- }
- else
- {
- mTradeButton->setEnabled(false);
- mOkButton->setEnabled(true);
+ mOkButton->setCaption(_("Trade"));
+ mOkButton->setActionEventId("trade");
}
}
}
@@ -252,6 +255,10 @@ void TradeWindow::tradeItem(Item *item, int quantity)
addItem(item->getId(), true, quantity);
item->increaseQuantity(-quantity);
#else
+ // TODO: Our newer version of eAthena doesn't register this following
+ // function. Detect the actual server version, and re-enable this
+ // for that version only.
+ //addItem(item->getId(), true, quantity, item->isEquipment());
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_TRADE_ITEM_ADD_REQUEST);
outMsg.writeInt16(item->getInvIndex());
@@ -291,15 +298,19 @@ void TradeWindow::action(const gcn::ActionEvent &event)
if (event.getId() == "add")
{
+ if (!inventoryWindow->isVisible()) return;
+
if (!item)
return;
if (mMyInventory->getFreeSlot() < 1)
return;
- if (mMyInventory->contains(item)) {
- chatWindow->chatLog("Failed adding item. You can not "
- "overlap one kind of item on the window.", BY_SERVER);
+ if (mMyInventory->contains(item))
+ {
+ chatWindow->chatLog(_("Failed adding item. You can not "
+ "overlap one kind of item on the window."),
+ BY_SERVER);
return;
}
@@ -372,3 +383,13 @@ void TradeWindow::action(const gcn::ActionEvent &event)
}
#endif
}
+
+void TradeWindow::close()
+{
+#ifdef TMWSERV_SUPPORT
+ Net::GameServer::Player::acceptTrade(false);
+#else
+ MessageOut outMsg(mNetwork);
+ outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST);
+#endif
+}
diff --git a/src/gui/trade.h b/src/gui/trade.h
index bde0481c..4c215ba6 100644
--- a/src/gui/trade.h
+++ b/src/gui/trade.h
@@ -91,11 +91,6 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
* Increase quantity of an item.
*/
void increaseQuantity(int index, bool own, int quantity);
-
- /**
- * Set trade Button disabled
- */
- void setTradeButton(bool enabled);
#endif
/**
@@ -123,6 +118,12 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
*/
void action(const gcn::ActionEvent &event);
+ /**
+ * Closes the Trade Window, as well as telling the server that the
+ * window has been closed.
+ */
+ void close();
+
private:
#ifdef TMWSERV_SUPPORT
enum Status
@@ -152,6 +153,7 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
gcn::Label *mMoneyLabel;
gcn::Button *mTradeButton;
#ifdef EATHENA_SUPPORT
+ gcn::Button *mAddButton;
gcn::Button *mOkButton;
#endif
gcn::TextField *mMoneyField;
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
index 7c72e2f5..b4b839e9 100644
--- a/src/gui/truetypefont.cpp
+++ b/src/gui/truetypefont.cpp
@@ -76,7 +76,7 @@ typedef std::list<TextChunk>::iterator CacheIterator;
static int fontCounter;
-TrueTypeFont::TrueTypeFont(const std::string &filename, int size)
+TrueTypeFont::TrueTypeFont(const std::string &filename, int size, int style)
{
if (fontCounter == 0 && TTF_Init() == -1)
{
@@ -86,6 +86,7 @@ TrueTypeFont::TrueTypeFont(const std::string &filename, int size)
++fontCounter;
mFont = TTF_OpenFont(filename.c_str(), size);
+ TTF_SetFontStyle (mFont, style);
if (!mFont)
{
diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h
index 71b45fd1..1cf6c2c8 100644
--- a/src/gui/truetypefont.h
+++ b/src/gui/truetypefont.h
@@ -26,8 +26,8 @@
#include <string>
#include <guichan/font.hpp>
-#ifndef __APPLE__
-#include <SDL/SDL_ttf.h>
+#ifdef __APPLE__
+#include <SDL_ttf/SDL_ttf.h>
#else
#include <SDL_ttf.h>
#endif
@@ -48,7 +48,7 @@ class TrueTypeFont : public gcn::Font
* @param filename Font filename.
* @param size Font size.
*/
- TrueTypeFont(const std::string &filename, int size);
+ TrueTypeFont(const std::string &filename, int size, int style = 0);
/**
* Destructor.
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index ca41dbda..8c903c28 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -24,13 +24,11 @@
#include <SDL_thread.h>
#include <zlib.h>
-#include <guichan/widgets/label.hpp>
-
-// Curl should be included after Guichan to avoid Windows redefinitions
#include <curl/curl.h>
#include "browserbox.h"
#include "button.h"
+#include "label.h"
#include "progressbar.h"
#include "scrollarea.h"
#include "updatewindow.h"
@@ -109,7 +107,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
mBrowserBox = new BrowserBox;
mScrollArea = new ScrollArea(mBrowserBox);
- mLabel = new gcn::Label(_("Connecting..."));
+ mLabel = new Label(_("Connecting..."));
mProgressBar = new ProgressBar(0.0, 310, 20, 168, 116, 31);
mCancelButton = new Button(_("Cancel"), "cancel", this);
mPlayButton = new Button(_("Play"), "play", this);
@@ -131,7 +129,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- setLocationRelativeTo(getParent());
+ center();
setVisible(true);
mCancelButton->requestFocus();
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index cbd1f3f7..c840e456 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -44,6 +44,8 @@ extern volatile int tick_time;
Viewport::Viewport():
mMap(0),
+ mMouseX(0),
+ mMouseY(0),
mPixelViewX(0.0f),
mPixelViewY(0.0f),
mTileViewX(0),
@@ -132,19 +134,23 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
{
if (player_x > mPixelViewX + mScrollRadius)
{
- mPixelViewX += (player_x - mPixelViewX - mScrollRadius) / mScrollLaziness;
+ mPixelViewX += (player_x - mPixelViewX - mScrollRadius) /
+ mScrollLaziness;
}
if (player_x < mPixelViewX - mScrollRadius)
{
- mPixelViewX += (player_x - mPixelViewX + mScrollRadius) / mScrollLaziness;
+ mPixelViewX += (player_x - mPixelViewX + mScrollRadius) /
+ mScrollLaziness;
}
if (player_y > mPixelViewY + mScrollRadius)
{
- mPixelViewY += (player_y - mPixelViewY - mScrollRadius) / mScrollLaziness;
+ mPixelViewY += (player_y - mPixelViewY - mScrollRadius) /
+ mScrollLaziness;
}
if (player_y < mPixelViewY - mScrollRadius)
{
- mPixelViewY += (player_y - mPixelViewY + mScrollRadius) / mScrollLaziness;
+ mPixelViewY += (player_y - mPixelViewY + mScrollRadius) /
+ mScrollLaziness;
}
lastTick++;
}
@@ -167,18 +173,14 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
mMap->getHeight() * mMap->getTileHeight() - graphics->getHeight();
if (mMap)
{
- if (mPixelViewX < 0) {
+ if (mPixelViewX < 0)
mPixelViewX = 0;
- }
- if (mPixelViewY < 0) {
+ if (mPixelViewY < 0)
mPixelViewY = 0;
- }
- if (mPixelViewX > viewXmax) {
+ if (mPixelViewX > viewXmax)
mPixelViewX = viewXmax;
- }
- if (mPixelViewY > viewYmax) {
+ if (mPixelViewY > viewYmax)
mPixelViewY = viewYmax;
- }
}
mTileViewX = (int) (mPixelViewX + 16) / 32;
@@ -205,7 +207,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
player_node->setName(player_node->getName());
}
-
// Draw text
if (textManager)
{
@@ -216,8 +217,8 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
Beings &beings = beingManager->getAll();
for (BeingIterator i = beings.begin(); i != beings.end(); i++)
{
- (*i)->drawSpeech(-(int) mPixelViewX, -(int) mPixelViewY);
- (*i)->drawEmotion(graphics, -(int) mPixelViewX, -(int) mPixelViewY);
+ (*i)->drawSpeech((int) mPixelViewX, (int) mPixelViewY);
+ (*i)->drawEmotion(graphics, (int) mPixelViewX, (int) mPixelViewY);
}
if (miniStatusWindow)
@@ -234,21 +235,20 @@ void Viewport::logic()
if (!mMap || !player_node)
return;
- int mouseX, mouseY;
- Uint8 button = SDL_GetMouseState(&mouseX, &mouseY);
+ Uint8 button = SDL_GetMouseState(&mMouseX, &mMouseY);
if (mPlayerFollowMouse && button & SDL_BUTTON(1) &&
#ifdef TMWSERV_SUPPORT
get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay)
{
mLocalWalkTime = tick_time;
- player_node->setDestination(mouseX + (int) mPixelViewX,
- mouseY + (int) mPixelViewY);
+ player_node->setDestination(mMouseX + (int) mPixelViewX,
+ mMouseY + (int) mPixelViewY);
#else
mWalkTime != player_node->mWalkTime)
{
- player_node->setDestination(mouseX / 32 + mTileViewX,
- mouseY / 32 + mTileViewY);
+ player_node->setDestination(mMouseX / 32 + mTileViewX,
+ mMouseY / 32 + mTileViewY);
mWalkTime = player_node->mWalkTime;
#endif
}
@@ -257,11 +257,10 @@ void Viewport::logic()
void Viewport::drawDebugPath(Graphics *graphics)
{
// Get the current mouse position
- int mouseX, mouseY;
- SDL_GetMouseState(&mouseX, &mouseY);
+ SDL_GetMouseState(&mMouseX, &mMouseY);
- const int mouseTileX = (mouseX + (int) mPixelViewX) / 32;
- const int mouseTileY = (mouseY + (int) mPixelViewY) / 32;
+ const int mouseTileX = (mMouseX + (int) mPixelViewX) / 32;
+ const int mouseTileY = (mMouseY + (int) mPixelViewY) / 32;
const Vector &playerPos = player_node->getPosition();
Path debugPath = mMap->findPath(
@@ -353,10 +352,12 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
if (being->mAction == Being::DEAD)
break;
- if (player_node->withinAttackRange(being) || keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ if (player_node->withinAttackRange(being) ||
+ keyboard.isKeyActive(keyboard.KEY_ATTACK))
{
player_node->setGotoTarget(being);
- player_node->attack(being, !keyboard.isKeyActive(keyboard.KEY_TARGET));
+ player_node->attack(being,
+ !keyboard.isKeyActive(keyboard.KEY_TARGET));
}
else
{
@@ -403,9 +404,7 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
20, Being::MONSTER);
if (target)
- {
- player_node->setTarget(target);
- }
+ player_node->setTarget(target);
}
}
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index a097a4ac..c051e5a2 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -124,6 +124,16 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int getCameraY() const { return (int) mPixelViewY; }
/**
+ * Returns mouse x in pixels.
+ */
+ int getMouseX() const { return mMouseX; }
+
+ /**
+ * Returns mouse y in pixels.
+ */
+ int getMouseY() const { return mMouseY; }
+
+ /**
* Changes viewpoint by relative pixel coordinates.
*/
void scrollBy(float x, float y) { mPixelViewX += x; mPixelViewY += y; }
@@ -140,18 +150,20 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
*/
void drawPath(Graphics *graphics, const Path &path);
- Map *mMap; /**< The current map. */
+ Map *mMap; /**< The current map. */
int mScrollRadius;
int mScrollLaziness;
int mScrollCenterOffsetX;
int mScrollCenterOffsetY;
- float mPixelViewX; /**< Current viewpoint in pixels. */
- float mPixelViewY; /**< Current viewpoint in pixels. */
+ int mMouseX; /**< Current mouse position in pixels. */
+ int mMouseY; /**< Current mouse position in pixels. */
+ float mPixelViewX; /**< Current viewpoint in pixels. */
+ float mPixelViewY; /**< Current viewpoint in pixels. */
int mTileViewX; /**< Current viewpoint in tiles. */
int mTileViewY; /**< Current viewpoint in tiles. */
- bool mShowDebugPath; /**< Show a path from player to pointer. */
- bool mVisibleNames; /**< Show target names. */
+ bool mShowDebugPath; /**< Show a path from player to pointer. */
+ bool mVisibleNames; /**< Show target names. */
bool mPlayerFollowMouse;
#ifdef TMWSERV_SUPPORT
@@ -160,11 +172,10 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int mWalkTime;
#endif
- PopupMenu *mPopupMenu; /**< Popup menu. */
- Being *mSelectedBeing; /**< Current selected being. */
-
+ PopupMenu *mPopupMenu; /**< Popup menu. */
+ Being *mSelectedBeing; /**< Current selected being. */
};
-extern Viewport *viewport; /**< The viewport */
+extern Viewport *viewport; /**< The viewport */
#endif
diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp
index 92837603..b736591c 100644
--- a/src/gui/widgets/dropdown.cpp
+++ b/src/gui/widgets/dropdown.cpp
@@ -23,8 +23,8 @@
#include "dropdown.h"
-#include "../color.h"
#include "../listbox.h"
+#include "../palette.h"
#include "../scrollarea.h"
#include "../../configuration.h"
@@ -74,12 +74,15 @@ DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea,
int gridy[4] = {0, 3, 28, 31};
int a = 0, x, y;
- for (y = 0; y < 3; y++) {
- for (x = 0; x < 3; x++) {
- skin.grid[a] = boxBorder->getSubImage(
- gridx[x], gridy[y],
- gridx[x + 1] - gridx[x] + 1,
- gridy[y + 1] - gridy[y] + 1);
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y],
+ gridx[x + 1] -
+ gridx[x] + 1,
+ gridy[y + 1] -
+ gridy[y] + 1);
skin.grid[a]->setAlpha(mAlpha);
a++;
}
@@ -104,20 +107,22 @@ DropDown::~DropDown()
for_each(skin.grid, skin.grid + 9, dtor<Image*>());
}
+
+ gcn::ListModel *listModel = getListModel();
+ if (listModel) delete listModel;
}
void DropDown::draw(gcn::Graphics* graphics)
{
+ if (!isVisible())
+ return;
+
int h;
if (mDroppedDown)
- {
h = mFoldedUpHeight;
- }
else
- {
h = getHeight();
- }
if (config.getValue("guialpha", 0.8) != mAlpha)
{
@@ -134,27 +139,20 @@ void DropDown::draw(gcn::Graphics* graphics)
}
}
- bool valid;
const int alpha = (int)(mAlpha * 255.0f);
gcn::Color faceColor = getBaseColor();
faceColor.a = alpha;
- gcn::Color highlightColor = textColor->getColor('H', valid);
- highlightColor.a = alpha;
+ const gcn::Color* highlightColor = &guiPalette->getColor(Palette::HIGHLIGHT,
+ alpha);
gcn::Color shadowColor = faceColor - 0x303030;
shadowColor.a = alpha;
if (mOpaque)
{
- int red = getBackgroundColor().r;
- int green = getBackgroundColor().g;
- int blue = getBackgroundColor().b;
- graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->setColor(guiPalette->getColor(Palette::BACKGROUND, alpha));
graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), h));
- red = getForegroundColor().r;
- green = getForegroundColor().g;
- blue = getForegroundColor().b;
- graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->setColor(guiPalette->getColor(Palette::TEXT, alpha));
}
graphics->setFont(getFont());
@@ -166,7 +164,7 @@ void DropDown::draw(gcn::Graphics* graphics)
if (isFocused())
{
- graphics->setColor(highlightColor);
+ graphics->setColor(*highlightColor);
graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth() - h, h));
}
@@ -178,7 +176,7 @@ void DropDown::draw(gcn::Graphics* graphics)
// Draw two lines separating the ListBox with selected
// element view.
- graphics->setColor(highlightColor);
+ graphics->setColor(*highlightColor);
graphics->drawLine(0, h, getWidth(), h);
graphics->setColor(shadowColor);
graphics->drawLine(0, h + 1, getWidth(), h + 1);
diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp
index 21402c89..7a2d9ee8 100644
--- a/src/gui/widgets/tab.cpp
+++ b/src/gui/widgets/tab.cpp
@@ -24,6 +24,8 @@
#include "tab.h"
#include "tabbedarea.h"
+#include "../palette.h"
+
#include "../../configuration.h"
#include "../../graphics.h"
@@ -35,7 +37,7 @@
int Tab::mInstances = 0;
float Tab::mAlpha = config.getValue("guialpha", 0.8);
-enum{
+enum {
TAB_STANDARD, // 0
TAB_HIGHLIGHTED, // 1
TAB_SELECTED, // 2
@@ -94,8 +96,10 @@ void Tab::init()
{
tab[mode] = resman->getImage(data[mode].file);
a = 0;
- for (y = 0; y < 3; y++) {
- for (x = 0; x < 3; x++) {
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
tabImg[mode].grid[a] = tab[mode]->getSubImage(
data[x].gridX, data[y].gridY,
data[x + 1].gridX - data[x].gridX + 1,
@@ -121,13 +125,17 @@ void Tab::draw(gcn::Graphics *graphics)
{
mode = TAB_SELECTED;
// if tab is selected, it doesnt need to highlight activity
- mLabel->setForegroundColor(gcn::Color(0, 0, 0));
+ mLabel->setForegroundColor(guiPalette->getColor(Palette::TEXT));
mHighlighted = false;
}
else if (mHighlighted)
{
mode = TAB_HIGHLIGHTED;
- mLabel->setForegroundColor(gcn::Color(255, 0, 0));
+ mLabel->setForegroundColor(guiPalette->getColor(Palette::TAB_HIGHLIGHT));
+ }
+ else
+ {
+ mLabel->setForegroundColor(guiPalette->getColor(Palette::TEXT));
}
}
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
index ce11fe69..a8f2b6f0 100644
--- a/src/gui/widgets/tabbedarea.cpp
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -40,9 +40,8 @@ Tab* TabbedArea::getTab(const std::string &name)
while (itr != itr_end)
{
if ((*itr).first->getCaption() == name)
- {
return static_cast<Tab*>((*itr).first);
- }
+
++itr;
}
return NULL;
@@ -51,9 +50,7 @@ Tab* TabbedArea::getTab(const std::string &name)
void TabbedArea::draw(gcn::Graphics *graphics)
{
if (mTabs.empty())
- {
return;
- }
drawChildren(graphics);
}
@@ -64,9 +61,8 @@ gcn::Widget* TabbedArea::getWidget(const std::string &name)
while (itr != itr_end)
{
if ((*itr).first->getCaption() == name)
- {
return (*itr).second;
- }
+
++itr;
}
@@ -91,9 +87,7 @@ void TabbedArea::addTab(Tab *tab, gcn::Widget *widget)
mTabs.push_back(std::pair<Tab*, gcn::Widget*>(tab, widget));
if (!mSelectedTab)
- {
setSelectedTab(tab);
- }
adjustTabPositions();
adjustSize();
@@ -107,15 +101,10 @@ void TabbedArea::removeTab(Tab *tab)
{
int index = getSelectedTabIndex();
- if (index == (int)mTabs.size() - 1
- && mTabs.size() == 1)
- {
+ if (index == (int)mTabs.size() - 1 && mTabs.size() == 1)
tabIndexToBeSelected = -1;
- }
else
- {
tabIndexToBeSelected = index - 1;
- }
}
TabContainer::iterator iter;
diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp
new file mode 100644
index 00000000..01790a67
--- /dev/null
+++ b/src/gui/widgets/textpreview.cpp
@@ -0,0 +1,81 @@
+/*
+ * The Mana World
+ * Copyright (C) 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <typeinfo>
+
+#include "textpreview.h"
+
+#include "../gui.h"
+#include "../palette.h"
+#include "../textrenderer.h"
+#include "../truetypefont.h"
+
+#include "../../configuration.h"
+
+float TextPreview::mAlpha = config.getValue("guialpha", 0.8);
+
+TextPreview::TextPreview(const std::string* text)
+{
+ mText = text;
+ mTextAlpha = false;
+ mFont = gui->getFont();
+ mTextColor = &guiPalette->getColor(Palette::TEXT);
+ mTextBGColor = NULL;
+ mBGColor = &guiPalette->getColor(Palette::BACKGROUND);
+ mOpaque = false;
+}
+
+void TextPreview::draw(gcn::Graphics* graphics)
+{
+ if (config.getValue("guialpha", 0.8) != mAlpha)
+ mAlpha = config.getValue("guialpha", 0.8);
+
+ int alpha = (int) (mAlpha * 255.0f);
+
+ if (!mTextAlpha)
+ alpha = 255;
+
+ if (mOpaque)
+ {
+ graphics->setColor(gcn::Color((int) mBGColor->r,
+ (int) mBGColor->g,
+ (int) mBGColor->b,
+ (int)(mAlpha * 255.0f)));
+ graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont))
+ {
+ TrueTypeFont *font = static_cast<TrueTypeFont*>(mFont);
+ int x = font->getWidth(*mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0);
+ int y = font->getHeight() + 1 + 2 * ((mOutline || mShadow) ? 1 : 0);
+ graphics->setColor(gcn::Color((int) mTextBGColor->r,
+ (int) mTextBGColor->g,
+ (int) mTextBGColor->b,
+ (int)(mAlpha * 255.0f)));
+ graphics->fillRectangle(gcn::Rectangle(1, 1, x, y));
+ }
+
+ TextRenderer::renderText(graphics, *mText, 2, 2, gcn::Graphics::LEFT,
+ gcn::Color(mTextColor->r, mTextColor->g,
+ mTextColor->b, alpha),
+ mFont, mOutline, mShadow, alpha);
+}
diff --git a/src/gui/widgets/textpreview.h b/src/gui/widgets/textpreview.h
new file mode 100644
index 00000000..e7b7db80
--- /dev/null
+++ b/src/gui/widgets/textpreview.h
@@ -0,0 +1,142 @@
+/*
+ * The Mana World
+ * Copyright (C) 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TEXTPREVIEW_H
+#define TEXTPREVIEW_H
+
+#include <guichan/color.hpp>
+#include <guichan/font.hpp>
+#include <guichan/widget.hpp>
+
+/**
+ * Preview widget for particle colors, etc.
+ */
+class TextPreview : public gcn::Widget
+{
+ public:
+ TextPreview(const std::string* text);
+
+ /**
+ * Sets the color the text is printed in.
+ *
+ * @param color the color to set
+ */
+ inline void setTextColor(const gcn::Color* color)
+ {
+ mTextColor = color;
+ }
+
+ /**
+ * Sets the text to use the set alpha value.
+ *
+ * @param alpha whether to use alpha values for the text or not
+ */
+ inline void useTextAlpha(bool alpha)
+ {
+ mTextAlpha = alpha;
+ }
+
+ /**
+ * Sets the color the text background is drawn in. This is only the
+ * rectangle directly behind the text, not to full widget.
+ *
+ * @param color the color to set
+ */
+ inline void setTextBGColor(const gcn::Color* color)
+ {
+ mTextBGColor = color;
+ }
+
+ /**
+ * Sets the background color of the widget.
+ *
+ * @param color the color to set
+ */
+ inline void setBGColor(const gcn::Color* color)
+ {
+ mBGColor = color;
+ }
+
+ /**
+ * Sets the font to render the text in.
+ *
+ * @param font the font to use.
+ */
+ inline void setFont(gcn::Font *font)
+ {
+ mFont = font;
+ }
+
+ /**
+ * Sets whether to use a shadow while rendering.
+ *
+ * @param shadow true, if a shadow is wanted, false else
+ */
+ inline void setShadow(bool shadow)
+ {
+ mShadow = shadow;
+ }
+
+ /**
+ * Sets whether to use an outline while rendering.
+ *
+ * @param outline true, if an outline is wanted, false else
+ */
+ inline void setOutline(bool outline)
+ {
+ mOutline = outline;
+ }
+
+ /**
+ * Widget's draw method. Does the actual job.
+ *
+ * @param graphics graphics to draw into
+ */
+ void draw(gcn::Graphics *graphics);
+
+ /**
+ * Set opacity for this widget (whether or not to show the background
+ * color)
+ *
+ * @param opaque Whether the widget should be opaque or not
+ */
+ void setOpaque(bool opaque) { mOpaque = opaque; }
+
+ /**
+ * Gets opacity for this widget (whether or not the background color
+ * is shown below the widget)
+ */
+ bool isOpaque() { return mOpaque; }
+
+ private:
+ gcn::Font *mFont;
+ const std::string* mText;
+ const gcn::Color* mTextColor;
+ const gcn::Color* mBGColor;
+ const gcn::Color* mTextBGColor;
+ static float mAlpha;
+ bool mTextAlpha;
+ bool mOpaque;
+ bool mShadow;
+ bool mOutline;
+};
+
+#endif
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 58439316..4689c86a 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -26,6 +26,8 @@
#include <guichan/exception.hpp>
#include "gui.h"
+#include "palette.h"
+#include "skin.h"
#include "window.h"
#include "windowcontainer.h"
@@ -37,16 +39,10 @@
#include "../log.h"
#include "../resources/image.h"
-#include "../resources/resourcemanager.h"
-
-#include "../utils/xml.h"
ConfigListener *Window::windowConfigListener = 0;
-WindowContainer *Window::windowContainer = 0;
int Window::instances = 0;
int Window::mouseResize = 0;
-//ImageRect Window::border;
-Image *Window::closeImage = NULL;
bool Window::mAlphaChanged = false;
class WindowConfigListener : public ConfigListener
@@ -70,23 +66,16 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
mMinWinWidth(100),
mMinWinHeight(40),
mMaxWinWidth(INT_MAX),
- mMaxWinHeight(INT_MAX),
- mSkin(skin)
+ mMaxWinHeight(INT_MAX)
{
logger->log("Window::Window(\"%s\")", caption.c_str());
if (!windowContainer)
- {
throw GCN_EXCEPTION("Window::Window(): no windowContainer set");
- }
-
- // Loads the skin
- loadSkin(mSkin);
-
- setGuiAlpha();
if (instances == 0)
{
+ skinLoader = new SkinLoader();
windowConfigListener = new WindowConfigListener;
// Send GUI alpha changed for initialization
windowConfigListener->optionChanged("guialpha");
@@ -99,6 +88,11 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
setPadding(3);
setTitleBarHeight(20);
+ // Loads the skin
+ mSkin = skinLoader->load(skin);
+
+ setGuiAlpha();
+
// Add this window to the window container
windowContainer->add(this);
@@ -117,21 +111,8 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
Window::~Window()
{
logger->log("Window::~Window(\"%s\")", getCaption().c_str());
- const std::string &name = mWindowName;
- // Saving X, Y and Width and Height for resizables in the config
- if (!name.empty())
- {
- config.setValue(name + "WinX", getX());
- config.setValue(name + "WinY", getY());
- config.setValue(name + "Visible", isVisible());
-
- if (mGrip)
- {
- config.setValue(name + "WinWidth", getWidth());
- config.setValue(name + "WinHeight", getHeight());
- }
- }
+ saveWindowState();
delete mLayout;
@@ -142,22 +123,18 @@ Window::~Window()
delete(w);
}
+ removeWidgetListener(this);
+
instances--;
- // Clean up static resources
- for (int i = 0; i < 9; i++)
- {
- delete border.grid[i];
- border.grid[i] = NULL;
- }
+ mSkin->instances--;
if (instances == 0)
{
+ delete skinLoader;
config.removeListener("guialpha", windowConfigListener);
delete windowConfigListener;
windowConfigListener = NULL;
-
- closeImage->decRef();
}
}
@@ -168,14 +145,17 @@ void Window::setWindowContainer(WindowContainer *wc)
void Window::draw(gcn::Graphics *graphics)
{
+ if (!isVisible())
+ return;
+
Graphics *g = static_cast<Graphics*>(graphics);
- g->drawImageRect(0, 0, getWidth(), getHeight(), border);
+ g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
// Draw title
if (mShowTitle)
{
- g->setColor(gcn::Color(0, 0, 0));
+ g->setColor(guiPalette->getColor(Palette::TEXT));
g->setFont(getFont());
g->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT);
}
@@ -183,8 +163,8 @@ void Window::draw(gcn::Graphics *graphics)
// Draw Close Button
if (mCloseButton)
{
- g->drawImage(closeImage,
- getWidth() - closeImage->getWidth() - getPadding(),
+ g->drawImage(mSkin->getCloseImage(),
+ getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(),
getPadding()
);
}
@@ -192,18 +172,29 @@ void Window::draw(gcn::Graphics *graphics)
// Update window alpha values
if (mAlphaChanged)
{
- for_each(border.grid, border.grid + 9,
+ for_each(mSkin->getBorder().grid, mSkin->getBorder().grid + 9,
std::bind2nd(std::mem_fun(&Image::setAlpha),
config.getValue("guialpha", 0.8)));
- closeImage->setAlpha(config.getValue("guialpha", 0.8));
+ mSkin->getCloseImage()->setAlpha(config.getValue("guialpha", 0.8));
}
drawChildren(graphics);
}
void Window::setContentSize(int width, int height)
{
- setSize(width + 2 * getPadding(),
- height + getPadding() + getTitleBarHeight());
+ width = width + 2 * getPadding();
+ height = height + getPadding() + getTitleBarHeight();
+
+ if (getMinWidth() > width)
+ width = getMinWidth();
+ else if (getMaxWidth() < width)
+ width = getMaxWidth();
+ if (getMinHeight() > height)
+ height = getMinHeight();
+ else if (getMaxHeight() < height)
+ height = getMaxHeight();
+
+ setSize(width, height);
}
void Window::setLocationRelativeTo(gcn::Widget *widget)
@@ -218,14 +209,61 @@ void Window::setLocationRelativeTo(gcn::Widget *widget)
getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y));
}
+void Window::setLocationRelativeTo(ImageRect::ImagePosition position,
+ int offsetX, int offsetY)
+{
+ if (position == ImageRect::UPPER_LEFT)
+ {
+ }
+ else if (position == ImageRect::UPPER_CENTER)
+ {
+ offsetX += (graphics->getWidth() - getWidth()) / 2;
+ }
+ else if (position == ImageRect::UPPER_RIGHT)
+ {
+ offsetX += graphics->getWidth() - getWidth();
+ }
+ else if (position == ImageRect::LEFT)
+ {
+ offsetY += (graphics->getHeight() - getHeight()) / 2;
+ }
+ else if (position == ImageRect::CENTER)
+ {
+ offsetX += (graphics->getWidth() - getWidth()) / 2;
+ offsetY += (graphics->getHeight() - getHeight()) / 2;
+ }
+ else if (position == ImageRect::RIGHT)
+ {
+ offsetX += graphics->getWidth() - getWidth();
+ offsetY += (graphics->getHeight() - getHeight()) / 2;
+ }
+ else if (position == ImageRect::LOWER_LEFT)
+ {
+ offsetY += graphics->getHeight() - getHeight();
+ }
+ else if (position == ImageRect::LOWER_CENTER)
+ {
+ offsetX += (graphics->getWidth() - getWidth()) / 2;
+ offsetY += graphics->getHeight() - getHeight();
+ }
+ else if (position == ImageRect::LOWER_RIGHT)
+ {
+ offsetX += graphics->getWidth() - getWidth();
+ offsetY += graphics->getHeight() - getHeight();
+ }
+
+ setPosition(offsetX, offsetY);
+}
+
void Window::setMinWidth(unsigned int width)
{
- mMinWinWidth = width;
+ mMinWinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth();
}
void Window::setMinHeight(unsigned int height)
{
- mMinWinHeight = height;
+ mMinWinHeight = height > mSkin->getMinHeight() ?
+ height : mSkin->getMinHeight();
}
void Window::setMaxWidth(unsigned int width)
@@ -317,14 +355,14 @@ void Window::mousePressed(gcn::MouseEvent &event)
if (mCloseButton)
{
gcn::Rectangle closeButtonRect(
- getWidth() - closeImage->getWidth() - getPadding(),
+ getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(),
getPadding(),
- closeImage->getWidth(),
- closeImage->getHeight());
+ mSkin->getCloseImage()->getWidth(),
+ mSkin->getCloseImage()->getHeight());
if (closeButtonRect.isPointInRect(x, y))
{
- setVisible(false);
+ close();
}
}
@@ -333,6 +371,11 @@ void Window::mousePressed(gcn::MouseEvent &event)
}
}
+void Window::close()
+{
+ setVisible(false);
+}
+
void Window::mouseReleased(gcn::MouseEvent &event)
{
if (mGrip && mouseResize)
@@ -388,8 +431,8 @@ void Window::mouseDragged(gcn::MouseEvent &event)
{
int newX = std::max(0, getX());
int newY = std::max(0, getY());
- newX = std::min(windowContainer->getWidth() - getWidth(), newX);
- newY = std::min(windowContainer->getHeight() - getHeight(), newY);
+ newX = std::min(graphics->getWidth() - getWidth(), newX);
+ newY = std::min(graphics->getHeight() - getHeight(), newY);
setPosition(newX, newY);
}
@@ -434,13 +477,13 @@ void Window::mouseDragged(gcn::MouseEvent &event)
newDim.height += newDim.y;
newDim.y = 0;
}
- if (newDim.x + newDim.width > windowContainer->getWidth())
+ if (newDim.x + newDim.width > graphics->getWidth())
{
- newDim.width = windowContainer->getWidth() - newDim.x;
+ newDim.width = graphics->getWidth() - newDim.x;
}
- if (newDim.y + newDim.height > windowContainer->getHeight())
+ if (newDim.y + newDim.height > graphics->getHeight())
{
- newDim.height = windowContainer->getHeight() - newDim.y;
+ newDim.height = graphics->getHeight() - newDim.y;
}
// Update mouse offset when dragging bottom or right border
@@ -469,8 +512,19 @@ void Window::loadWindowState()
if (mGrip)
{
- setSize((int) config.getValue(name + "WinWidth", mDefaultWidth),
- (int) config.getValue(name + "WinHeight", mDefaultHeight));
+ int width = (int) config.getValue(name + "WinWidth", mDefaultWidth);
+ int height = (int) config.getValue(name + "WinHeight", mDefaultHeight);
+
+ if (getMinWidth() > width)
+ width = getMinWidth();
+ else if (getMaxWidth() < width)
+ width = getMaxWidth();
+ if (getMinHeight() > height)
+ height = getMinHeight();
+ else if (getMaxHeight() < height)
+ height = getMaxHeight();
+
+ setSize(width, height);
}
else
{
@@ -478,19 +532,115 @@ void Window::loadWindowState()
}
}
+void Window::saveWindowState()
+{
+ // Saving X, Y and Width and Height for resizables in the config
+ if (!mWindowName.empty() && mWindowName != "window")
+ {
+ config.setValue(mWindowName + "WinX", getX());
+ config.setValue(mWindowName + "WinY", getY());
+ config.setValue(mWindowName + "Visible", isVisible());
+
+ if (mGrip)
+ {
+ if (getMinWidth() > getWidth())
+ setWidth(getMinWidth());
+ else if (getMaxWidth() < getWidth())
+ setWidth(getMaxWidth());
+ if (getMinHeight() > getHeight())
+ setHeight(getMinHeight());
+ else if (getMaxHeight() < getHeight())
+ setHeight(getMaxHeight());
+
+ config.setValue(mWindowName + "WinWidth", getWidth());
+ config.setValue(mWindowName + "WinHeight", getHeight());
+ }
+ }
+}
+
void Window::setDefaultSize(int defaultX, int defaultY,
int defaultWidth, int defaultHeight)
{
+ if (getMinWidth() > defaultWidth)
+ defaultWidth = getMinWidth();
+ else if (getMaxWidth() < defaultWidth)
+ defaultWidth = getMaxWidth();
+ if (getMinHeight() > defaultHeight)
+ defaultHeight = getMinHeight();
+ else if (getMaxHeight() < defaultHeight)
+ defaultHeight = getMaxHeight();
+
mDefaultX = defaultX;
mDefaultY = defaultY;
mDefaultWidth = defaultWidth;
mDefaultHeight = defaultHeight;
}
+void Window::setDefaultSize()
+{
+ mDefaultX = getX();
+ mDefaultY = getY();
+ mDefaultWidth = getWidth();
+ mDefaultHeight = getHeight();
+}
+
+void Window::setDefaultSize(int defaultWidth, int defaultHeight,
+ ImageRect::ImagePosition position,
+ int offsetX, int offsetY)
+{
+ int x = 0, y = 0;
+
+ if (position == ImageRect::UPPER_LEFT)
+ {
+ }
+ else if (position == ImageRect::UPPER_CENTER)
+ {
+ x = (graphics->getWidth() - defaultWidth) / 2;
+ }
+ else if (position == ImageRect::UPPER_RIGHT)
+ {
+ x = graphics->getWidth() - defaultWidth;
+ }
+ else if (position == ImageRect::LEFT)
+ {
+ y = (graphics->getHeight() - defaultHeight) / 2;
+ }
+ else if (position == ImageRect::CENTER)
+ {
+ x = (graphics->getWidth() - defaultWidth) / 2;
+ y = (graphics->getHeight() - defaultHeight) / 2;
+ }
+ else if (position == ImageRect::RIGHT)
+ {
+ x = graphics->getWidth() - defaultWidth;
+ y = (graphics->getHeight() - defaultHeight) / 2;
+ }
+ else if (position == ImageRect::LOWER_LEFT)
+ {
+ y = graphics->getHeight() - defaultHeight;
+ }
+ else if (position == ImageRect::LOWER_CENTER)
+ {
+ x = (graphics->getWidth() - defaultWidth) / 2;
+ y = graphics->getHeight() - defaultHeight;
+ }
+ else if (position == ImageRect::LOWER_RIGHT)
+ {
+ x = graphics->getWidth() - defaultWidth;
+ y = graphics->getHeight() - defaultHeight;
+ }
+
+ mDefaultX = x - offsetX;
+ mDefaultY = y - offsetY;
+ mDefaultWidth = defaultWidth;
+ mDefaultHeight = defaultHeight;
+}
+
void Window::resetToDefaultSize()
{
setPosition(mDefaultX, mDefaultY);
setSize(mDefaultWidth, mDefaultHeight);
+ saveWindowState();
}
int Window::getResizeHandles(gcn::MouseEvent &event)
@@ -528,179 +678,16 @@ void Window::setGuiAlpha()
for (int i = 0; i < 9; i++)
{
//logger->log("Window::setGuiAlpha: Border Image (%i)", i);
- border.grid[i]->setAlpha(config.getValue("guialpha", 0.8));
+ mSkin->getBorder().grid[i]->setAlpha(config.getValue("guialpha", 0.8));
}
mAlphaChanged = false;
}
-void Window::loadSkin(const std::string &fileName)
+int Window::getGuiAlpha()
{
- const std::string windowId = Window::getId();
-
- ResourceManager *resman = ResourceManager::getInstance();
-
- logger->log("Loading Window Skin '%s'.", fileName.c_str());
- logger->log("Loading Window ID '%s'.", windowId.c_str());
-
-
- if (fileName.empty())
- logger->error("Window::loadSkin(): Invalid File Name.");
-
- // TODO:
- // If there is an error loading the specified file, we should try to revert
- // to a 'default' skin file. Only if the 'default' skin file can't be loaded
- // should we have a terminating error.
- XML::Document doc(fileName);
- xmlNodePtr rootNode = doc.rootNode();
-
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
- {
- logger->error("Widget Skinning error");
- }
-
- std::string skinSetImage;
- skinSetImage = XML::getProperty(rootNode, "image", "");
- Image *dBorders = NULL;
- if (!skinSetImage.empty())
- {
- logger->log("Window::loadSkin(): <skinset> defines '%s' as a skin image.", skinSetImage.c_str());
- dBorders = resman->getImage("graphics/gui/" + skinSetImage);//"graphics/gui/speech_bubble.png");
- }
- else
- {
- logger->error("Window::loadSkin(): Skinset does not define an image!");
- }
-
- //iterate <widget>'s
- for_each_xml_child_node(widgetNode, rootNode)
- {
- if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget"))
- continue;
-
- std::string widgetType;
- widgetType = XML::getProperty(widgetNode, "type", "unknown");
- if (widgetType == "Window")
- {
- // Iterate through <part>'s
- // LEEOR / TODO:
- // We need to make provisions to load in a CloseButton image. For now it
- // can just be hard-coded.
- for_each_xml_child_node(partNode, widgetNode)
- {
- if (!xmlStrEqual(partNode->name, BAD_CAST "part"))
- {
- continue;
- }
-
- std::string partType;
- partType = XML::getProperty(partNode, "type", "unknown");
- // TOP ROW
- if (partType == "top-left-corner")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height);
- }
- else if (partType == "top-edge")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height);
- }
- else if (partType == "top-right-corner")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height);
- }
-
- // MIDDLE ROW
- else if (partType == "left-edge")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height);
- }
- else if (partType == "bg-quad")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height);
- }
- else if (partType == "right-edge")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height);
- }
-
- // BOTTOM ROW
- else if (partType == "bottom-left-corner")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height);
- }
- else if (partType == "bottom-edge")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height);
- }
- else if (partType == "bottom-right-corner")
- {
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height);
- }
-
- // Part is of an uknown type.
- else
- {
- logger->log("Window::loadSkin(): Unknown Part Type '%s'", partType.c_str());
- }
- }
- }
- // Widget is of an uknown type.
- else
- {
- logger->log("Window::loadSkin(): Unknown Widget Type '%s'", widgetType.c_str());
- }
- }
- dBorders->decRef();
-
- logger->log("Finished loading Window Skin.");
-
- // Hard-coded for now until we update the above code to look for window buttons.
- closeImage = resman->getImage("graphics/gui/close_button.png");
+ float alpha = config.getValue("guialpha", 0.8);
+ return (int) (alpha * 255.0f);
}
Layout &Window::getLayout()
@@ -728,3 +715,8 @@ void Window::reflowLayout(int w, int h)
mLayout = NULL;
setContentSize(w, h);
}
+
+void Window::center()
+{
+ setLocationRelativeTo(getParent());
+}
diff --git a/src/gui/window.h b/src/gui/window.h
index 3806342a..7f15e262 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -31,11 +31,11 @@
class ConfigListener;
class ContainerPlacer;
-class Image;
-class ImageRect;
class Layout;
class LayoutCell;
class ResizeGrip;
+class Skin;
+class SkinLoader;
class WindowContainer;
/**
@@ -61,7 +61,7 @@ class Window : public gcn::Window, gcn::WidgetListener
* @param skin The location where the window's skin XML can be found.
*/
Window(const std::string &caption = "Window", bool modal = false,
- Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml");
+ Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml");
/**
* Destructor. Deletes all the added widgets.
@@ -89,6 +89,12 @@ class Window : public gcn::Window, gcn::WidgetListener
void setLocationRelativeTo(gcn::Widget *widget);
/**
+ * Sets the location relative to the given enumerated position.
+ */
+ void setLocationRelativeTo(ImageRect::ImagePosition position,
+ int offsetX = 0, int offsetY = 0);
+
+ /**
* Sets whether or not the window can be resized.
*/
void setResizable(bool resize);
@@ -151,8 +157,7 @@ class Window : public gcn::Window, gcn::WidgetListener
/**
* Sets flag to show a title or not.
*/
- void setShowTitle(bool flag)
- { mShowTitle = flag; }
+ void setShowTitle(bool flag) { mShowTitle = flag; }
/**
* Sets whether the window is sticky. A sticky window will not have
@@ -233,6 +238,12 @@ class Window : public gcn::Window, gcn::WidgetListener
void loadWindowState();
/**
+ * Saves the window state so that when the window is reloaded, it'll
+ * maintain its previous state and location.
+ */
+ void saveWindowState();
+
+ /**
* Set the default win pos and size.
* (which can be different of the actual ones.)
*/
@@ -240,10 +251,25 @@ class Window : public gcn::Window, gcn::WidgetListener
int defaultWidth, int defaultHeight);
/**
+ * Set the default win pos and size tot he current ones.
+ */
+ void setDefaultSize();
+
+ /**
+ * Set the default win pos and size.
+ * (which can be different of the actual ones.)
+ * This version of setDefaultSize sets the window's position based
+ * on a relative enumerated position, rather than a coordinate position.
+ */
+ void setDefaultSize(int defaultWidth, int defaultHeight,
+ ImageRect::ImagePosition position,
+ int offsetx = 0, int offsetY = 0);
+
+ /**
* Reset the win pos and size to default. Don't forget to set defaults
* first.
*/
- void resetToDefaultSize();
+ virtual void resetToDefaultSize();
/**
* Gets the layout handler for this window.
@@ -261,11 +287,6 @@ class Window : public gcn::Window, gcn::WidgetListener
void reflowLayout(int w = 0, int h = 0);
/**
- * Loads a window skin
- */
- void loadSkin(const std::string &fileName);
-
- /**
* Adds a widget to the window and sets it at given cell.
*/
LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1);
@@ -275,9 +296,22 @@ class Window : public gcn::Window, gcn::WidgetListener
*/
ContainerPlacer getPlacer(int x, int y);
- protected:
- /** The window container windows add themselves to. */
- static WindowContainer *windowContainer;
+ /**
+ * Positions the window in the center of it's parent.
+ */
+ void center();
+
+ /**
+ * Overrideable functionality for when the window is to close. This
+ * allows for class implementations to clean up or do certain actions
+ * on window close they couldn't do otherwise.
+ */
+ virtual void close();
+
+ /**
+ * Gets the alpha value used by the window, in a GUIChan usable format.
+ */
+ int getGuiAlpha();
private:
enum ResizeHandles
@@ -316,7 +350,6 @@ class Window : public gcn::Window, gcn::WidgetListener
int mDefaultY; /**< Default window Y position */
int mDefaultWidth; /**< Default window width */
int mDefaultHeight; /**< Default window height */
- std::string mSkin; /**< Name of the skin to use */
/**
* The config listener that listens to changes relevant to all windows.
@@ -325,8 +358,8 @@ class Window : public gcn::Window, gcn::WidgetListener
static int mouseResize; /**< Active resize handles */
static int instances; /**< Number of Window instances */
- ImageRect border; /**< The window border and background */
- static Image *closeImage; /**< Close Button Image */
+
+ Skin* mSkin; /**< Skin in use by this window */
/**
* The width of the resize border. Is independent of the actual window
diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp
index 2846b1c1..eda739b9 100644
--- a/src/gui/windowcontainer.cpp
+++ b/src/gui/windowcontainer.cpp
@@ -23,6 +23,8 @@
#include "../utils/dtor.h"
+WindowContainer *windowContainer = NULL;
+
void WindowContainer::logic()
{
delete_all(mDeathList);
diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h
index 62704d1b..bc918184 100644
--- a/src/gui/windowcontainer.h
+++ b/src/gui/windowcontainer.h
@@ -45,6 +45,11 @@ class WindowContainer : public gcn::Container
*/
void scheduleDelete(gcn::Widget *widget);
+ /**
+ * Get the number of widget instances
+ */
+ int getNumberOfInstances() { return mDeathList.size(); }
+
private:
/**
* List of widgets that are scheduled to be deleted.
@@ -54,4 +59,6 @@ class WindowContainer : public gcn::Container
Widgets mDeathList;
};
+extern WindowContainer* windowContainer;
+
#endif